
//v4.2 - changed the way stored script is called. instead of evaling everything, 
//		a small piece of code is evaled that calls a pre-defined function, so all
//		of the event code doesnt get evaluated inline. seems much faster this way.

//ALSO! this version is using 'display' styles instead of 'visibility' styles.

//v4.0 - now just call "extensionsInitialize(...)". 
//it now checks to see if extensions already have been initialized, and does only creates it if not

function extensionsInitialize() {	



	if (document.extensions == null) {
		document.extensions = new extensionsObject();
	}


	function extensionsObject() {

		//initialize....

		//add a groups object if it doesnt exist
		this.groups = new Object();

		this.debug = new debugObject();

		this.extendButtons = extendButtons;
		this.extendTheseButtons = extendTheseButtons;
		this.extendElementsByTagName = extendElementsByTagName;
		this.extendElement = extendElement;
		this.extendGroup = extendGroup;

		this.extendBanners = extendBanners;

		this.extend_show = extend_show;
		this.extend_src = extend_src;
		this.extend_class = extend_class;

		this.addAttributeByTagName = addAttributeByTagName;
		this.setStyle = setStyle;
		this.setProperty = setProperty;
		this.setProperty_recurseChildren = setProperty_recurseChildren;
		this.setPropertyFromAttribute = setPropertyFromAttribute;

		this.showTimer_onMouseOut = showTimer_onMouseOut;
		this.showTimer_child_onMouseOut = showTimer_child_onMouseOut;
		this.showTimer_child_onMouseOver = showTimer_child_onMouseOver;

		this.classTimer_onMouseOut = classTimer_onMouseOut;

		this.mergeScript = mergeScript;

		//constants
		this.default_showDelay = 100;

		function debugObject() {
			this.on = false;
			this.div = null;

			this.initialize = initialize;
			this.write = write;

			this.line = 0;

			this.debugLevels = new Array();

			function write(t, level) {

				if (level == null) { level = 0; }

				level = this.debugLevels[level];

				if (this.on && level != null) {
					
					level.line += 1;

					level.div.innerHTML = '\n<pre>' + level.line + ': ' + t + '</pre>' + level.div.innerHTML;

				}


			}

			function initialize(el, level) {

				if (level == null) {

					level = 0;
				} 

				if (el.constructor == String) {
					el = document.getElementById(el);
				}

				if (el == null) {
					alert('A debugger element or element id is required');
					return;
				}

				this.on = true;

				this.debugLevels[level] = new Object();
				
				this.debugLevels[level].line = 0;
				this.debugLevels[level].div = el;

				if (this.debugLevels[0] == null) {
					this.initialize(el, 0);
				}
			}
		}

		function addAttributeByTagName(tag, att, val, filterAtt, filterVal) {


			//warning! NOT case specific


			var ar = document.getElementsByTagName(tag);


			for (var i = 0; i < ar.length; i++) {

				var a = ar[i];

				var bAddAtt = false;

				//if we are filtering by an attribute
				if (filterAtt != null && filterAtt != '') {

					//if this node has that attribute
					if (a.getAttribute(filterAtt)) {


						//if the filterAtt is equal to the filterVal 
						if (a.getAttribute(filterAtt).toString().toLowerCase() == filterVal.toString().toLowerCase()) {

							//then set the node to have the tagname added
							bAddAtt = true;
						}
					}
				} else {
				
					bAddAtt = true;
				}

				if (bAddAtt == true) {
					a.setAttribute(att, val);
				}

			}
		}

		function shouldExtend(el, filterAtt, filterVals) {
			var sValue;

			if (el != null) {
			
				//if we are filtering by an attribute
				if (filterAtt != null && filterAtt != '') {

					sValue = el.getAttribute(filterAtt);
					
					//if this node has that attribute
					if (sValue != null) {
						sValue = sValue.toString().toLowerCase();

						//if the filterAtt is equal to the filterVal, or filterVal doesnt matter

						if (filterVals.length == 0) {
							return true;
						} else {
							for (var j = 0; j < filterVals.length; j++) {
								if (sValue == filterVals[j].toString().toLowerCase()) {
									return true;
								}
							}
						}

					}

				} else {

					return true;
				}
			}
		}

		function extendBanners(filterAtt, filterVal) {
			//extend all the elements collected with this tag

			var els = document.getElementsByTagName(img);

			if (filterVal == null)
				filterVal = '';

			var filterVals = filterVal.split(',');

			for (var i = 0; i < els.length; i++) {
				var el = els[i];
	
				if (shouldExtend(el, filterAtt, filterVals)) {
					this.extendElement(el);
				}
			}

		}


		function extendElementsByTagName(t, filterAtt, filterVal) {
			//extend all the elements collected with this tag


			var els = document.getElementsByTagName(t);

			if (filterVal == null)
				filterVal = '';

			var filterVals = filterVal.split(',');

			for (var i = 0; i < els.length; i++) {
				var el = els[i];
				if (shouldExtend(el, filterAtt, filterVals)) {

					this.extendElement(el);
				}
			}

		}



		function extendButtons() {
			//extend all the button tags
			this.extendTheseButtons(document.getElementsByTagName('button'));

			//extend all input/@type=button|submits|image tags
			this.extendTheseButtons(document.getElementsByTagName('input'));
		}

		function extendTheseButtons(btns) {

			for (var i = 0; i < btns.length; i++) {
				var btn = btns[i];

				if (btns.type) {
					if (btn.type.toLowerCase() == 'image' || btn.type.toLowerCase() == 'submit' || btn.type.toLowerCase() == 'button') {
						this.extendElement(btn);
					}
				} else {
					this.extendElement(btn);
				}
			}
		}


		function extend_src(o) {

			if (o == null) 
				return;

			if (o.src == null)
				return;

			//get the srcHover and srcActive
			var srcHover = o.getAttribute("srcHover")
			var srcActive = o.getAttribute("srcActive");
			var srcOut = o.getAttribute("srcOut");

			//add the img

			o.imgNormal		= new Image();
			o.imgNormal.src	= o.src		

			//onmouseout	-- this is the default mouseout after a mouseover. any srcOut will overide this
			if (o.src != null && srcHover != null && srcOut == null) {

					//merge script with any existing onmouseout code
				o.script_onMouseOut	= mergeScript(o.script_onMouseOut, 'extensions_src_default_onMouseOut(this)');

			}

			if (srcOut!=null) {

				o.imgOut		= new Image();
				o.imgOut.src	= srcOut;

					//merge script with any existing onmouseover code
				o.script_onMouseOut = mergeScript(o.script_onMouseOut, 'extensions_src_specific_onMouseOut(this)');

			}

			//onmouseover
			if (srcHover!=null) {
				o.imgHover		= new Image();
				o.imgHover.src	= srcHover;

document.extensions.debug.write('extended onmouseover src: ' + o.imgHoversrc);

				//merge script with any existing onmouseover code
				o.script_onMouseOver = mergeScript(o.script_onMouseOver, 'extensions_src_onMouseOver(this)');

				//default onmouseout
				//if no srcOut is specified, we want the onmouseout to restore what the onmouseover changed
				if (srcOut == null)
					o.script_onMouseOut = mergeScript(o.script_onMouseOut, 'extensions_src_default_onMouseOut(this)');

				//default onmousedown for hovers
				//if no srcActive is specified, we want the onmousedown to set this image and the active image for this group.
				if (srcActive == null) {


					o.imgActive		= new Image();
					o.imgActive.src	= srcHover;

						//merge script with any existing onmousedown code
					o.script_onMouseDown = mergeScript(o.script_onMouseDown, 'extensions_src_onMouseDown(this)');
				}

			}

			//onmousedown - if an active was set
			if (srcActive!=null) {


				o.imgActive		= new Image();
				o.imgActive.src = srcActive;

					//merge script with any existing onmousedown code
				o.script_onMouseDown = mergeScript(o.script_onMouseDown, 'extensions_src_onMouseDown(this)');
			}

		}




		function extend_class(o) {

//note: class extentions need to be overidden by show extensions

			//get the classHover and classActive
			var	classHover = o.getAttribute("classHover")

			var	classActive = o.getAttribute("classActive");

			//note: classDelay only effects on mouseout
			var classDelay = o.getAttribute("classDelay");

			if (classDelay != null) { o.group.classDelay = classDelay; }


			//add the classNames to the object
			if (o.className!=null) { o.classNormal	= o.className }
			if (classHover!=null) { 
				//dont do if showHoverClass is set
				if (o.showHoverClass == null) {

					//alert('classHover');
					o.classHover	= classHover;
				} else {
					classHover == null;
				}
			}

			if (classActive!=null) { 
			
								//dont do if showHoverClass is set
				if (o.showActiveClass == null) {
					o.classActive	= classActive;
					//alert('classActive');
				} else {
					classActive == null;
				}
				
				
			}


			//if this item has the same class as the classActive, then 
			//set it as the groups active class;
			if (o.classNormal == o.classActive) {
				o.group.classActive = o;
			}

			//onmouseout
				if (classHover != null || classActive != null) {

//x				o.script_onMouseOut = mergeScript(o.script_onMouseOut, onMouseOut);
				o.script_onMouseOut = mergeScript(o.script_onMouseOut, 'extensions_class_onMouseOut(this)');
	
				}

			//onmouseover
				if (classHover != null) {

					//build the onmouseover function, merge it with any existing onmouseover code
//x					o.script_onMouseOver = mergeScript(o.script_onMouseOver, onMouseOver);
					o.script_onMouseOver = mergeScript(o.script_onMouseOver, 'extensions_class_onMouseOver(this)');


				}
			//onmousedown
				if (classActive != null) {
//x					o.script_onMouseDown = mergeScript(o.script_onMouseDown, onMouseDown);
					o.script_onMouseDown = mergeScript(o.script_onMouseDown, 'extensions_class_onMouseDown(this)');

					//setup special direct function reference, so that class can be activated externally
					o.classActivate = o.script_onMouseDown;
				}


		}



		function extend_show(o) {

			if (o == null)
				return;

				//set the showHover
			var showHoverItems = o.getAttribute("showHover");

				//added showHoverClass attribute for when you want the classhover to act
				//in tandem with the showHover items
			var showHoverClass = o.getAttribute("showHoverClass");
			var showActiveClass = o.getAttribute("showActiveClass");
document.extensions.debug.write('active class ' + showActiveClass, 1);

			if ((showHoverClass != null || showActiveClass != null) && o.classNormal == null) { o.classNormal = o.className; }


				//set showOut to overide the autohide of the hover!
			var showAuto = o.getAttribute("showAuto");

				//set showOut to overide the autohide of the hover!
			var showOutItems = o.getAttribute("showOut");

				//if active is set, then clicking on a show will set it as the default
			var showActiveItems = o.getAttribute("showActive");

			if (showHoverItems == null && showActiveItems == null && showOutItems == null && showAuto == null)
				return;

document.extensions.debug.write('extending show? showHover: ' + showHoverItems + '; showActive: ' + showActiveItems + '; showOut: ' + showOutItems + '; showAuto: ' + showAuto);

			//initialize default arrays
			o.showHoverItems = new Array();

			o.showOutItems = new Array();

			o.showActiveItems = new Array();


			//set showDelay (delay turning shown elements off that-is)
			var showDelay = o.getAttribute("showDelay");
			if (showDelay != null) {
				o.group.showDelay = showDelay;
			} else {
				//if showDelay for the group has not yet been set, then default it
				if (o.group.showDelay == null) {
					o.group.showDelay = document.extensions.default_showDelay;
				}
			}


			if (showHoverItems != null) {

//document.extensions.debug.write(showHover);
				showHoverItems = showHoverItems.split(',');
//document.extensions.debug.write(o.showHover[0]);

				for (var i = 0; i < showHoverItems.length; i++)
					o.showHoverItems[i] = document.getElementById(showHoverItems[i]);

				//default onmouseout	-- onmouseout hides the showHover by default!
							// if showOut is set, then it doesnt define the onmouseout here
							// otherwise, hovers get hidden onmouseout					
				if (showOutItems == null) {

					o.script_onMouseOut = mergeScript(o.script_onMouseOut, 'extensions_show_default_onMouseOut(this)');
//					eval(o.script_onMouseOut);

				}

				//onmouseover

				//build the onmouseover function, merge it with any existing onmouseover code

//x				o.script_onMouseOver = mergeScript(o.script_onMouseOver, onMouseOver);
				o.script_onMouseOver = mergeScript(o.script_onMouseOver, 'extensions_show_onMouseOver(this)');

//extensions_show_onMouseOver
				//showHoverClass
				if (showHoverClass != null) {
					if (o.classNormal == null) { o.classNormal = o.className; }
					o.showHoverClass = showHoverClass;
				}


			}

			if (showOutItems != null) {
				showOutItems = showOutItems.split(',');
				for (var i = 0; i < showOutItems.length; i++)
					o.showOutItems[i] = document.getElementById(showOutItems[i]);

				//specified onmouseout

				//build the onmouseover function, merge it with any existing onmouseover code
				o.script_onMouseOut = mergeScript(o.script_onMouseOut, 'extensions_show_specific_onMouseOut(this)');
			}

			if (showActiveItems != null) {
				showActiveItems = showActiveItems.split(',');
				for (var i = 0; i < showActiveItems.length; i++) {
					o.showActiveItems[i] = document.getElementById(showActiveItems[i]);

				}

				//specified onmouseout

				//build the onmouseover function, merge it with any existing onmouseover code
				o.script_onMouseDown = mergeScript(o.script_onMouseDown, 'extensions_show_onMouseDown(this)');

				//add special function that can be called adhoc that executes same code as onMouseDown
//x				o.showActivate = new Function('extensions_show_onMouseDown(this)');
				o.setActive = setActive;
				o.hideActive = hideActive;
				o.showActivate = showActivate;

				//showActiveClass
				if (showActiveClass != null) {
					if (o.classNormal == null) { o.classNormal = o.className; }
					o.showActiveClass = showActiveClass;
				}

			}


				//show any specified default
			if (showAuto != null) {

				if (showAuto.toLowerCase() == 'yes' || showAuto.toLowerCase() == 'true') {
document.extensions.debug.write('activating', 1);
					o.showActivate();
				}

			}

			function hideActive() {

				try {
					document.extensions.setStyle(this.showActiveItems, 'display', 'none');

					document.extensions.setPropertyFromAttribute(this.showActiveItems, 'className', 'classNormal');
					this.group.showActive = null;
				} catch(e) {

					document.extensions.debug.write(this.id + '.hideActiveItems().error: ' + e.description, 0);
				}
			}

			function setActive() {

				try {
					document.extensions.setStyle(this.showActiveItems, 'display', '');
					document.extensions.setPropertyFromAttribute(this.showActiveItems, 'className', 'showClassActive', null, null, false);

					this.group.showActive = this;

					//if children have parentShowActiveClass
					for (var i = 0; i < this.showActiveItems.length; i++) {

						var item = this.showActiveItems[i];

						var itemActiveClass = item.getAttribute('parentShowActiveClass');
						if (itemActiveClass != null) {

//alert(itemActiveClass);

							var itemNormalClass = item.className;
							if (itemNormalClass == null) {
								itemNormalClass = item.getAttribute('classNormal');
							}
							if (itemNormalClass != null) {
								item.classNormal = itemNormalClass;
							}
							item.className = itemActiveClass;
						}

					}






				} catch(e) {

					document.extensions.debug.write(this.id + '.showActiveItems().error: ' + e.description, 0);
				}
			}

			function showActivate() {

					//clear any group timers
				if (this.group.showTimer != null) {
					clearTimeout(this.group.showTimer);
				}

					//if a different show is currently active, hide it
				if (this.group.showActive != null && this.group.showActive != this) {
					this.hideActive();
				}

				if (this.group.name != 'nogroup') {

					//
					this.setActive();

					try {

					} catch(e) {
						document.extensions.debug.write('activating children error: ' + e.description);
					}

					try {
						document.extensions.debug.write('setting active class', 1);
										if (this.showActiveClass != null) {
						document.extensions.debug.write('setting active class ' + this.className, 1);
											this.className = this.showActiveClass;
						document.extensions.debug.write('sett active class ' + this.className, 1);

										}
					} catch(e) {
						document.extensions.debug.write('activating show error: ' + e.description);
					}
				}
			}



		}

		function extendGroup(o) {

			//setup group settings in case this object is in a group of objects
			//that will act together.

			//get the group attribute setting, if no group, then it uses "nogroup".
			if (o.getAttribute('group') != null) {
				o.groupName = o.getAttribute('group');
			} else {
				o.groupName = 'nogroup';
			}
			var grp = o.groupName;

			//add the group to the extensions.groups object
			if (eval('this.groups.' + grp) == null) {
				eval('this.groups.' + grp + ' = new Object()');

				//intiailize special group setting for buttons, objects, etc
				eval('this.groups.' + grp + '.activeButton = null');
			}

			//add the extensions.groups.grp pointer to the btn
			o.group	= eval('this.groups.' + grp);

			o.group.name = o.groupName;

			o.group.showTimer = null;

		}


		function extendElement(el) {

			if (el.constructor == String) {
				el = document.getElementById(el);
				if (el == null) {
					return;
				}
			}

			//if this element has already been extended, dont do it again
			if (el.extended) {
				return;
			}extendElement

document.extensions.debug.write('extending element: ' + el.id);
			el.extended = true;


			//first, we setup group settings in case this element is in a group of elements
			//that will act together.

			this.extendGroup(el);


			el.script_onMouseOut = mergeScript(el.onmouseout, '');
			el.script_onMouseOver = mergeScript(el.onmouseover, '');
			el.script_onMouseDown = mergeScript(el.onmousedown, '');


			el.onmouseout  = extensions_onMouseOut;
			el.onmousedown = extensions_onMouseDown;
			el.onmouseover = extensions_onMouseOver;


			//show rollovers
			this.extend_show(el);

			//setup rollover button class attributes
			this.extend_class(el);

//return;
			//setup rollover img src attributes
			this.extend_src(el);


			//client-side banner rotations
			//this.

		//	el.onmouseup = function() {
		//		if (this.group == 'nogroup') {
		//			el.onmouseover();
		//		}
		//	}

			if (el.getAttribute('link') != null) {
					
				//only take over onClick if there is a link attribute
//x				el.script_onClick = mergeScript(el.onclick, onclick_target);
				el.script_onClick = mergeScript(el.onclick, 'extensions_onclick_target(this)');

				el.onclick			= extensions_onClick;

			}



			var extendWidthHeight = false;

			if (el.tagName != 'IMAGE') {
				if (el.type != null) {
					//if type is NOT null, then if it is not an image, 
					// then allow extension of the width and height

					if (el.type.toLowerCase() != 'image') {
						extendWidthHeight = true;
					}
				} else {
					//if type IS null, then allow extension of width and height if
					// it is a DIV or SPAN tag

					if (el.tagName == 'DIV' || el.tagName == 'SPAN') {
						extendWidthHeight = true;
					}
				}
			}

			if (extendWidthHeight) {
				//if width hasnt already been set
				if (el.width != 0) {

					// then if there is an attribute for width
					if (el.getAttribute('width') != null) {

						//then set the style.width
						el.style.width = el.getAttribute('width');
					}
				}

				//ditto
				if (el.height != 0) {

					if (el.getAttribute('height') != null) {
						el.style.height = el.getAttribute('height');
					}
				}
				}
		}

		function extensions_onMouseOut(event) {
			//alert(this.script_onMouseOut);
			return eval(this.script_onMouseOut);
		}
		function extensions_onMouseOver(event) {
			return eval(this.script_onMouseOver);
		}
		function extensions_onMouseDown(event) {
			return eval(this.script_onMouseDown);
		}
		function extensions_onClick(event) {
			return eval(this.script_onClick);
		}



		function setProperty_recurseChildren(items, childName, prop, value) {

			setProperty(items, prop, value);

			if (items.constructor == Array) {

				for (var i = 0; i < items.length; i++) {

					var item = items[i];

					if (item != null) {

						//for each of the items, see if it contains a property/array/etc using childName
						var childs = eval('item.' + childName);

						if (childs != null) {

							setProperty_recurseChildren(childs, childName, prop, value);
						}
					}

				}
			}

		}


		function setProperty(o, s, v, ifp, ifv) {


			if (o.constructor == String) {
				o = document.getElementById(o);

			}

			if (o.constructor == Array) {

				for (var i = 0; i < o.length; i++) {
					if (o[i] != null) {
						if (ifp != null) {

							if (eval('o[i].' + ifp)==eval(ifv)) {
								eval('o[i].' + s + ' = "' + v + '"');
							}
						} else {
							eval('o[i].' + s + ' = "' + v + '"');
						}
					}
				}
			} else {

				if (o != null) {
					if (ifp != null) {

document.extensions.debug.write('o.' + ifp + ' == "' + ifv + '"? ' + (eval('o.' + ifp)==eval(ifv)));

						if (eval('o.' + ifp)==eval(ifv)) {
document.extensions.debug.write('o.' + s + ' = "' + v + '"');
							eval('o.' + s + ' = "' + v + '"');
						}
					} else {
						eval('o.' + s + ' = "' + v + '"');
					}
				}
			}

		}

		function setPropertyFromAttribute(o, s, attv, ifp, ifv, allowNull) {

			if (o == null)
				return false;

			if (o.constructor == String) {
				o = document.getElementById(o);

			}

			var v = item.getAttribute(attv);
			if (v == null && !allowNull) {
				return;
			}

			if (o.constructor == Array) {

				for (var i = 0; i < o.length; i++) {

					var item = o[i];


					if (item != null) {
						if (ifp != null) {

							if (item.getAttribute(ifp) == ifv) {
							
								eval('item.' + s + ' = "' + v + '"');

							}
						} else {
								eval('item.' + s + ' = "' + v + '"');

						}
					}
				}
			} else {

				var item = o;
				if (item != null) {
					if (ifp != null) {

						if (item.getAttribute(ifp) == ifv) {
								eval('item.' + s + ' = "' + v + '"');

						}
					} else {
								eval('item.' + s + ' = "' + v + '"');

					}
				}
			}
		
		}


		function applyFilters(el) {

//alert('applyFilters');
try {
			if (el.constructor == String) {
				el = document.getElementById(o);

			}

			if (el.constructor == Array) {

				for (var i = 0; i < el.length; i++) {
					applyFilter(el[i]);
				}
			} else {
				applyFilter(el);
			}
} catch (e) {
	document.extensions.debug.write('applyFilters error: ' + e.description);
	
}
		}

		function applyFilter(el) {
try {
			if (el != null) {
				var fil = el.getAttribute('filter');
				if (fil != '') {
					el.style.filter = fil;
					if (el.filters != null) {
						if (el.filters[0] != null) {
							el.filters[0].apply();
						}
					}
				}
			}
} catch (e) {
	document.extensions.debug.write('applyFilter error: ' + e.description);
	
}
		}



		function playFilters(el) {
//alert('playfilters');
try {
			if (el.constructor == String) {
				el = document.getElementById(el);
			}

			if (el.constructor == Array) {
				for (var i = 0; i < el.length; i++) {
					playFilter(el[i]);
				}
			} else {
				playFilter(el);
			}
} catch (e) {

	document.extensions.debug.write('applyFilters(o) error: ' + e.description);
	
}
		}

		function playFilter(el) {
try {
			if (el.filters != null) {
				if (el.filters[0] != null) {
					var speed = el.getAttribute('filterSpeed');
					if (speed == null) { speed = .5 }
					el.filters[0].play(.5);
				}
			}
} catch (e) {
	document.extensions.debug.write('playFilter error: ' + e.description);
}
		}

		function setStyle(o, s, v) {

document.extensions.debug.write('setting style', 1);
			if (o == null) {
				return;
			}

			if (o.constructor == String) {
				o = document.getElementById(o);
				
			}

			if (o.constructor == Array) {

				for (var i = 0; i < o.length; i++) {
					if (o[i] != null) {
						if (o[i].style != null) {
							eval('o[i].style.' + s + ' = "' + v + '"');
						}
					}
				}
			} else {

				if (o != null) {
					if (o.style != null) {
						eval('o.style.' + s + ' = "' + v + '"');
					}
				}
			}
				
		}


		function mergeScript(s1, s2) {
			
			if (s1) {
				s1 = s1.toString();
			} else {
				s1 = '';
			}
			
			if (s2) {
				s2 = s2.toString();
			} else {
				s2 = '';
			}

			if (s1.substring(0, 8) == 'function') {
				//replace the last curly brace, and the function prefix (usually function anonymous() { or function () {
	//			s1 = s1.substring(0, s1.length-2).replace(/function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s1 = s1.replace(/\s*function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s1 = s1.replace(/\s*}\s*$/gi,'');
			}

			if (s1.substring(1, 9) == 'function') {
				//replace the last curly brace, and the function prefix (usually function anonymous() { or function () {
	//			s1 = s1.substring(1, s1.length-2).replace(/function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s1 = s1.replace(/\s*function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s1 = s1.replace(/\s*}\s*$/gi,'');
			}


			if (s2.substring(0, 8) == 'function') {
				//replace the last curly brace, and the function prefix (usually function anonymous() { or function () {
	//			s2 = s2.substring(0, s2.length-2).replace(/function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s2 = s2.replace(/\s*function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s2 = s2.replace(/\s*}\s*$/gi,'');
			}
			if (s2.substring(1, 9) == 'function') {
				//replace the last curly brace, and the function prefix (usually function anonymous() { or function () {
	//			s2 = s2.substring(1, s2.length-2).replace(/function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s2 = s2.replace(/\s*function\s*\w*\s*\(\s*\w*\s*\)\s*\{\s*/gi, '');
				s2 = s2.replace(/\s*}\s*$/gi,'');
			}



			if (s1 == '' || s1 == null) {
				return s2;
			} else {
				if (s2 == '' || s2 == null) {
					return s1;
				} else {
					return s1 + ';\n' + s2;
				}
			}

		}

		function classTimer_onMouseOut(el) {
//alert('class onmouseout');
			if (el.constructor == String) {
				el = document.getElementById(el);
			}
			if (el == null) {

				return;
			}

			if (!el.class_reactived) {
				el.className = el.classNormal; 
			}

		}


		function showTimer_child_onMouseOver(el) {
		
try {
			if (el.showParent != null) {
document.extensions.debug.write('mouseover, setting active true: ' + el.id);
				el.active == true;

				el.showParent.active = true;

				//cancel the timer that was going to hide this item, if parent was not null
				if (el.showParent.group != null) {
					if (el.showParent.group.showTimer != null) {
						clearTimeout(el.showParent.group.showTimer);
					}
				}

//			} else {
//document.extensions.debug.write('mouseover, no parent');

			}

} catch(e) {
	document.extensions.debug.write('showTimer_child_onMouseOver(el) error: ' + e.description);
	
}
		}
		function showTimer_child_onMouseOut(el) {

try {
document.extensions.debug.write('child mouse out, ' + el.id);

			if (el.showParent != null) {
//document.extensions.debug.write('setting parent to turn me off: ' + el.showParent.id + ' :' + el.showParent.group.showDelay);

				clearTimeout(el.showParent.group.showTimer);

				if (el.showParent.group.showActive != el.showParent) {
document.extensions.debug.write('setting parent to turn me off: ' + el.showParent.id + ' :' + el.showParent.group.showDelay + ': ' + 'document.extensions.showTimer_onMouseOut("' + el.showParent.id + '")');

					el.showParent.group.showTimer = setTimeout('document.extensions.showTimer_onMouseOut("' + el.showParent.id + '")', el.showParent.group.showDelay);
				}

				//el.showParent = null;
			}
} catch(e) {
	document.extensions.debug.write('showTimer_child_onMouseOut(el) error: ' + e.description);
	
}

		}


		function showTimer_onMouseOut(el) {

try {
document.extensions.debug.write('parent turning off..... ' + el);

			if (el.constructor == String) {
				el = document.getElementById(el);
			}

			if (el == null) {
document.extensions.debug.write('null..... ');
				return;
			}

			//children that get moved over, set their parent's active flag to true.
			//if we just moved out of the parent, reset it to false
			el.active = false;

			var hidethem = true;

			if (el.showHoverItems != null) {

				if (el.showHoverItems.constructor == Array) {

					for (var i = 0; i < el.showHoverItems.length; i++) {

						if (el.showHoverItems[i]) {

							//if any of the items being shown have been activated, then dont hide any of them
							if (el.showHoverItems[i].active == true) {
								hidethem = false;
			document.extensions.debug.write('active child... ' + el.showHoverItems[i].id);

							} else {
			document.extensions.debug.write('inactive child... ' + el.showHoverItems[i].id);

							}
						} else {

			document.extensions.debug.write('no items to show... ' + el.id);

						}
					}
					if (hidethem) {

		document.extensions.debug.write('no children active... ' + el.id);

						document.extensions.setStyle(el.showHoverItems, 'display', 'none');
						


						if (el.showHoverClass != null || el.showActiveClass != null) {

							if (el.group.showActive != null) {
								if (el.group.showActive != this) {
									el.className = el.classNormal;
								} else {

									el.group.showActive.showActivate();
								}
							}
	
						} else {

							el.className = el.classNormal;
						}

					}
				}
			}
} catch(e) {
	document.extensions.debug.write('showTimer_onMouseOut(el) error: ' + e.description);
	
}
		}


	}


}


function extensions_show_onMouseDown(o) {
	//document.extensions.debug.write('show onmousedown ' + this.id, 1);

	try {


		//if item is currently active, then deactivate it when clicked again
			if (o.group.showActive == o) {

				try {
					//alert('un activating');
						if (o.showActiveItems != null) {
							document.extensions.setStyle(o.showActiveItems, 'display', 'none');
						}

						o.group.showActive = null;

						if (o.showActiveClass != null && o.classNormal != null) {
							o.className = o.classNormal;
						}

				} catch(e) {

					document.extensions.debug.write('hiding showActive: ' + e.description + ' ' + event.srcElement.id);

				}
			} else {
			
				//activate the showActiveItems
				try {
					//alert('activating');
						if (o.showActiveItems != null) {
							document.extensions.setStyle(o.showActiveItems, 'display', '');
						}

						o.group.showActive = o;

						if (o.showActiveClass != null) {
							o.className = o.showActiveClass;
						}

				} catch(e) {

					document.extensions.debug.write('showing showActive: ' + e.description + ' ' + event.srcElement.id);

				}
			}

	} catch(e) {

		document.extensions.debug.write('show onMouseDown error: ' + e.description);

	}

}

function extensions_show_specific_onMouseOut(o) {
	try {
		if (o.group.name != 'nogroup') {
			if (o.group.showActive != o) {
				if (o.group.showHover != null) {
					document.extensions.setStyle(o.group.showHover.showHoverItems, 'display', 'none');

					if (o.group.showhover.showHoverClass != null) {
						o.group.showHover.className = o.group.showHover.classNormal;
					}
				}

				o.group.showHover = o;
				document.extensions.setStyle(o.showOutItems, 'display', '');


				if (o.group.showHover.showHoverClass != null) {
					o.group.showHover.className = o.group.showHover.classNormal;
				}

			}

			//restore active show class
			if (o.group.showActive != null) {
				if (o.group.showActive.showActiveClass != null) {
					o.group.showActive.className = o.group.showActive.showActiveClass;
				}
			}

		} else {
			document.extensions.setStyle(o.showOutItems, 'display', '');

		}
	} catch(e) {
	document.extensions.debug.write('show specific_onMouseOut error: ' + e.description);
	//alert('show specific_onMouseOut error: ' + e.description);
	}
}

function extensions_show_default_onMouseOut(o) {

	document.extensions.debug.write('mouse out of parent... ' + o.id);
	try {	
		//if o item is NOT the group active,

		//applyFilters(o.showHoverItems);

		if (o != o.group.showActive) {
			for (var i = 0; i < o.showHoverItems.length; i++) {

				//for each child that we are showing, 
				//add settings that allow it to stay open if the mouse moves from 
				//the parent into the child.
	try {	
				var oc = o.showHoverItems[i];
	} catch(e) {
		document.extensions.debug.write('err getting child hover item: ' + e);
	}
				if (oc != null) {

					//if child doesnt have any extension script settings, extend them now
					//so that the way we handle script will work for the children
	try {
					document.extensions.extendElement(oc, o);
	} catch(e) {
		document.extensions.debug.write('err extending child hover item: ' + e);
	}

	try {
					//add the onmouseout only once to the child's onmouseout script
					if (!oc.showParentSetOnce) {

						//add the showtimer child onmouseout code to the on mouse out script

	//								oc.script_onMouseOut = mergeScript(oc.script_onMouseOut, new Function('document.extensions.showTimer_child_onMouseOut(this)'));
	//								oc.script_onMouseOver = mergeScript(oc.script_onMouseOver, new Function('document.extensions.showTimer_child_onMouseOver(this)'));


						oc.script_onMouseOut = document.extensions.mergeScript(oc.script_onMouseOut, 'document.extensions.showTimer_child_onMouseOut(this)');
						oc.script_onMouseOver = document.extensions.mergeScript(oc.script_onMouseOver, 'document.extensions.showTimer_child_onMouseOver(this)');
						oc.showParentSetOnce = true;

					}

					oc.showParent = o;
	} catch(e) {
		document.extensions.debug.write('err setting showParent once: ' + e);
	}

	document.extensions.debug.write('set parent... ' + oc.showParent.id);
				}
			}

			if (o.group.showHover == o) {

	document.extensions.debug.write('showhover mouse out... ');
				clearTimeout(o.group.showTimer);
				o.group.showTimer = setTimeout('document.extensions.showTimer_onMouseOut("' + o.id + '")', o.group.showDelay);
			}
		} else {

			//restore active show class
			if (o.group.showActive != null) {
	document.extensions.debug.write('restoring active... ');
				o.group.showActive.showActivate();
						
	//						if (o.group.showActive.showActiveClass != null) {
	//							o.group.showActive.className = o.group.showActive.showActiveClass;
	//						}
			}
		}


		//playFilters(o.showHoverItems);

	} catch(e) {
	document.extensions.debug.write('show default_onMouseOut error: ' + e.description);
	//alert('show default_onMouseOut error: ' + e.description);

	}


}


function extensions_show_onMouseOver(o) {

	try {
					//applyFilters(o.showHoverItems);

					if (o.group.name != 'nogroup') {

						if (o.group.showActive != o) {

							try {
								if (o != o.group.showHover && o.group.showHover != null) {

									document.extensions.setProperty(o.group.showHover.showHoverItems, 'active', 'false');
									document.extensions.setStyle(o.group.showHover.showHoverItems, 'display', 'none');

									if (o.group.showHover.showHoverClass != null) {
										o.group.showHover.className = o.group.showHover.classNormal;
									}

	//x								setProperty_recurseChildren(o.group.showHover, 'showHoverItems', 'showHover', 'active', 'false');
	//x								setProperty_recurseChildren(o.group.showHover, 'showHoverItems', 'showHover', 'style.display', 'none');
								}
							} catch(e) {

		document.extensions.debug.write('show.onMouseOver.recursingActiveShow.error: ' + e.description);
		//alert('show.onMouseOver.recursingActiveShow.error: ' + e.description);
							}


		//					try {
		//						if (o.showHover != o.group.showActive) {
		//							setProperty_recurseChildren(o.group.showActive, 'showActiveItems', 'showActive', 'active', 'false');
		//							setProperty_recurseChildren(o.group.showActive, 'showActiveItems', 'showActive', 'style.display', 'none');
		//						}
		//					} catch(e) {
		//
		//document.extensions.debug.write('show.onMouseOver.recursingActiveShow.error: ' + e.description);
		//alert('show.onMouseOver.recursingActiveShow.error: ' + e.description);
		//					}



							o.group.showHover = o;
							document.extensions.setStyle(o.showHoverItems, 'display', '');
	//throw('test');
							if (o.showHoverClass != null) {
								o.className = o.showHoverClass;
							}
						} else {
	//alert(o.showActiveClass);

							if (o.showActiveClass != null) {
								o.className = o.showActiveClass;
		//alert('setting active class');
							}
						}
					} else {
						document.extensions.setStyle(o.showHoverItems, 'display', '');
					}


					//playFilters(o.showHoverItems);
	} catch(e) {

	document.extensions.debug.write('show onMouseOver error: ' + e.description);
	//alert('show onMouseOver error: ' + e.description);
	}
}

function extensions_src_onMouseDown(o) {

	if (o.groupName != 'nogroup') {
		if (o.group.activeImage != null) {
			o.group.activeImage.src = o.group.activeImage.imgNormal.src;
		}

		o.group.activeImage = o;
	}
	o.src = o.imgActive.src;

}

function extensions_src_onMouseOver(o) {


	if (o.groupName != 'nogroup') {

		//only set img active on mouseovers when there is a specfic imgOut
		if (o.imgOut != null) {

			if (o.group.activeImage != null && o.group.activeImage != o) {
				o.group.activeImage.src = o.group.activeImage.imgNormal.src;
			}

			if (o.group.activeImage != o) {
				o.src = o.imgHover.src;
			}

			o.group.activeImage = o;

		} else {
			o.src = o.imgHover.src;
		}

	} else {
		o.src = o.imgHover.src;
	}


}

function extensions_src_specific_onMouseOut(o) {

	if (o.groupName != 'nogroup') {

		if (o.group.activeImage != null) {

			if (o.group.activeImage != o) {
				o.group.activeImage.src = o.group.activeImage.imgNormal.src;
				o.src = o.imgOut.src;
			} 
			//if o item IS the active image, dont hide it...

		} else {
			o.src = o.imgOut.src;
		}

		o.group.activeImage = o;

	} else {
		o.src = o.imgOut.src;
	}
}

function extensions_src_default_onMouseOut(o) {
	document.extensions.debug.write('out.. active? ' + (o != o.group.activeImage));

	if (o != o.group.activeImage) { o.src = o.imgNormal.src; }
}





function extensions_class_onMouseDown(o) {


document.extensions.debug.write(o.id + ' class mousedown.. active? ' + (o == o.group.activeClass));

	try {

		if (o.classActive != null) {

			if (o.groupName != 'nogroup') {

				if (o.group.classActive != null) {

					o.group.classActive.className = o.group.classActive.classNormal;
				}
				//alert('setting active class');
				o.group.classActive = o;

			}
			o.className = o.classActive;

document.extensions.debug.write(o.id + ' class mousedown.. active? ' + (o == o.group.activeClass));

		}

	} catch(e) {
		document.extensions.debug.write('class onMouseDown error: ' + e.description);
	}	

}

function extensions_class_onMouseOver(o) {
	document.extensions.debug.write('class mouse over.. active? ' + (o == o.group.activeClass));
	try {

		if (o != o.group.classActive) {

			if (o.group.classHover != o) {

				o.class_reactived = true;
				o.className = o.classHover; 

				if (o.group.name != 'nogroup') {

					//turn off any other classes that are hovering in o group
					if (o.group.classHover != null) {

						o.group.classHover.className = o.classNormal;
						o.group.classHover.class_reactived = false;

					}
					o.group.classHover = o;
				}
			}

		}
						

	} catch(e) {
		document.extensions.debug.write('class onMouseOver error: ' + e.description);
	}
}

function extensions_class_onMouseOut(o) {
	document.extensions.debug.write('class mouse out.. active? ' + (o == o.group.activeClass));
	try {
		if (o != o.group.classActive) { 

			if (o.group.classDelay!=null) {

				o.class_reactived = false;
				o.group.classTimer = setTimeout('document.extensions.classTimer_onMouseOut("' + o.id + '")', o.group.classDelay);

			} else {
				o.className = o.classNormal; 
			}
			if (o.group.classHover == o) {
				o.group.classHover = null;
			}
		}
	} catch(e) {
		document.extensions.debug.write('class onMouseOver error: ' + e.description);
	}
}



function extensions_onclick_target(o) {

	var t = o.getAttribute('target');
	if (t == null) {

		document.location = o.getAttribute('link');

	} else {

		if (document.frames != null) {

			if (document.frames[t]!=null) {

				document.frames[t].location = o.getAttribute('link');

			} else {

				var t = window.open(o.getAttribute('link'), t);
			}
		} else {

			var t = window.open(o.getAttribute('link'), t);
		}
	}
}