
// dhtml.js   -  colin@verot.net  -  2005

//    var f = document.getElementById(id);
//    f.funcname1 = funcname1;
//    f.funcname2 = funcname2;
//    cmf_addEvent(f, 'keyup', 'funcname1');
//    cmf_addEvent(f, 'change', 'funcname2');
function cmf_addEvent(obj,type,fct) {
    if (obj.addEventListener) { 
        obj.addEventListener(type, function(e){ obj[fct](e);}, false);
    } else if (obj.attachEvent) {
        obj.attachEvent('on'+type,function(e){ obj[fct](e); }); 
    } else {
        var cmf_Prev=obj["on" + type];
        if (cmf_Prev) {
            obj['on'+type]=function(e){ cmf_Prev(e); obj[fct](e); };
        } else { 
            obj['on'+type]=obj[fct]; 
        }
    }
}

// toggle all checkboxes
function cmf_togglecheckboxes(obj, name) {
    var f = obj.form, z = 0;
    
    z=5;
    for(z=0; z<f.length;z++){
    //alert(f[z].name+' '+f[z].value);
    var reg = new RegExp("^"+name+"\\[(.*)\\]$", "i");

   
        if (f[z].type == 'checkbox' && reg.test(f[z].name)) {
	        f[z].checked = obj.checked;
	    }
    }
}


// togglediv
function cmf_togglediv(obj) {
    var e = document.getElementById(obj);
    if(e.style.display != "block") {
        e.style.display = "block";
    } else {
        e.style.display = "none";
    }
}


// autodiv
var last_toggle_obj = '';
function cmf_autodiv(obj) {
    var e = document.getElementById(last_toggle_obj);
    if (e) e.style.display = "none";
    var e = document.getElementById(obj);
    if(e.style.display != "block") {
        e.style.display = "block";
        last_toggle_obj = obj;
    } else {
        e.style.display = "none";
    }
}


// populink
function cmf_popuplink(link, name, height, width, location, status, scrollbars, menubars, toolbars, resizable) {
    var w = window.open(link, name, "height="+height+",  width="+width+", location="+location+", status="+status+",  scrollbars="+scrollbars+", menubars="+menubars+",  toolbars="+toolbars+", resizable="+resizable+"" );
    if (w.opener == null) w.opener = self;
    return true; 
}


// dynamic_list
function cmf_dynamic_list() { 
    var dlist = document.getElementById(this.dynamic_list_id);
    var list = eval(this.list_id);
    var sel = this.options[this.selectedIndex].value;
    if (!sel) return;
    var list = list[sel];
    dlist.options.length = 0;
    for(i=0;i<list.length;i+=1) {
    	dlist.options[i] = new Option(list[i][1],list[i][0]);
    }    
}


// text_insert
function cmf_insertAtCursor(myID, myValue) {
    var myField = document.getElementById(myID);
	//IE support
	if (document.selection) {
		myField.focus();
		sel = document.selection.createRange();
		sel.text = myValue;
		myField.focus();
	}
	//MOZILLA/NETSCAPE support
	else if (myField.selectionStart || myField.selectionStart == '0') {
		var startPos = myField.selectionStart;
		var endPos = myField.selectionEnd;
		var scrollTop = myField.scrollTop;
		myField.value = myField.value.substring(0, startPos)
		              + myValue 
                      + myField.value.substring(endPos, myField.value.length);
		myField.focus();
		myField.selectionStart = startPos + myValue.length;
		myField.selectionEnd = startPos + myValue.length;
		myField.scrollTop = scrollTop;
	} else {
		myField.value += myValue;
		myField.focus();
	}
}



// character counter
function characterCounter_EventAdd(obj,type,fct) {
 if ( obj.addEventListener ){ obj.addEventListener(type, function(e){ obj[fct](e);}, false); }
 else if ( obj.attachEvent ){ obj.attachEvent('on'+type,function(e){ obj[fct](e); }); }
 else {
  var cmf_Prev=obj["on" + type];
  if (cmf_Prev){ obj['on'+type]=function(e){ cmf_Prev(e); obj[fct](e); }; }
  else { obj['on'+type]=obj[fct]; }
 }
}
function setCharacterCounter(field, status, max, min) {
	var f = document.getElementById(field);
	var s = document.getElementById(status);
    f.characterCounter = characterCounter;
    f.characterCounterMax = max;
    f.characterCounterMin = min;
    f.characterCounterStatus = status;
    characterCounter_EventAdd(f, 'keyup', 'characterCounter');
    characterCounter_EventAdd(f, 'change', 'characterCounter');
	f.characterCounter();
}
function characterCounter() {
	maxLength = this.characterCounterMax;
	minLength = this.characterCounterMin;
	statusSpan = document.getElementById(this.characterCounterStatus);
	var currentLength = this.value.length;
	var content = '';
	if (maxLength && minLength) {
	    content = 'Requires between '+minLength+' and '+maxLength+' characters';
	} else if (maxLength) {
	    content = 'Requires '+maxLength+' characters maximum';
	} else if (minLength) {
	    content = 'Requires '+minLength+' characters minimum';
	}	
	// can add  ('+currentLength+')
	if (maxLength && currentLength > maxLength && maxLength > 0) {
	    content = '<span class="cmf-charactercounter-warning">' + content + '</span>';
	} else if (minLength && currentLength < minLength) {
	    content = '<span class="cmf-charactercounter-warning">' + content + '</span>';
	} else {
	    content = '';
    }
    statusSpan.innerHTML = content;
}




// scroller.js
var swap_speed = 3000;
var scroll_speed = 50;
var scroll_step = 5;
var currentDiv=0;
var nextDiv=0;
var totalDivs=0;
// hides and position all divs
function hideall(){
    var cpt=0;
    while (document.getElementById("scrollerdiv"+cpt)) {
        document.getElementById("scrollerdiv"+cpt).style.display="none";
        document.getElementById("scrollerdiv"+cpt).style.position="absolute";
        document.getElementById("scrollerdiv"+cpt).style.top = "0px";
        cpt++;
    }
}
// to swap divs
function swap() {
    var currentDivObj=document.getElementById("scrollerdiv"+currentDiv);
    hideall();
    currentDivObj.style.display="block";
    currentDiv=(currentDiv<totalDivs-1)? currentDiv+1 : 0;
    setTimeout("swap()",swap_speed);
}
// to scroll divs
function scroll() {
    var currentDivObj=document.getElementById("scrollerdiv"+currentDiv);
    var nextDivObj=document.getElementById("scrollerdiv"+nextDiv);
    var scrollerDivObj=document.getElementById("cmf-scroller");
    if ((parseInt(currentDivObj.offsetHeight) + parseInt(currentDivObj.style.top) + 10) >= scrollerDivObj.offsetHeight) {
        currentDivObj.style.top=parseInt(currentDivObj.style.top)-scroll_step+"px";
        nextDivObj.style.top=parseInt(nextDivObj.style.top)-scroll_step+"px";
        setTimeout("scroll()",scroll_speed)
    } else if ((parseInt(currentDivObj.offsetHeight) + parseInt(currentDivObj.style.top) + 10) < scrollerDivObj.offsetHeight) {
        currentDivObj.style.top=parseInt(currentDivObj.style.top)-scroll_step+"px";
        if (nextDiv != currentDiv) document.getElementById("scrollerdiv"+nextDiv).style.display="none";
        nextDiv=(currentDiv<totalDivs-1)? currentDiv+1 : 0;
        document.getElementById("scrollerdiv"+nextDiv).style.top=scrollerDivObj.offsetHeight+"px";
        document.getElementById("scrollerdiv"+nextDiv).style.display="block";
        var tmpDiv = nextDiv;
        nextDiv = currentDiv;
        currentDiv = tmpDiv;
        setTimeout("scroll()",scroll_speed)
    } 
}
function cmf_scroller(type, scroll_spd, scroll_stp, swap_spd){
    scroll_speed=scroll_spd;
    scroll_step=scroll_stp;
    swap_speed=swap_spd;
    while (document.getElementById("scrollerdiv"+totalDivs)!=null)
        totalDivs++;
    hideall();
    if (totalDivs > 0) {
        if (type == 'swap') {
            document.getElementById("scrollerdiv0").style.display="block";
            swap();
        } else {
            document.getElementById("scrollerdiv0").style.display="block";
            document.getElementById("scrollerdiv0").style.top=(document.getElementById("cmf-scroller").offsetHeight - 10)+"px";
            scroll();
        }
    }
}





//==================================================
//=
//=	xhtml degrabable tabs origionally for tsh (thestandardhack.com)
//=	by tim scarfe, developer-x.com / tim@developer-x.com
//=	started - 14:00 22/12/2001 / updated - 2:39 PM 6/21/2002
//=	time spent - 30 hours 
//=
//==================================================
//==================================================
//=	Non-Global Code Starts
//==================================================
tabSystem.makeGlobalProps = function( e ) {
	// These are the generic "Catch-All" properties for tabsystems. You may also create custom tab sets.
	tabSystem.classTrigger = "cmf-tabsystem";
	tabSystem.tabPageClass = "cmf-tabpage";
	tabSystem.activeTabClass = "cmf-tab-active";
	tabSystem.hoverTabClass = "cmf-tab-hover";
	tabSystem.normalTabClass = "cmf-tab";
	tabSystem.startIndex = 0;
	tabSystem.removeHeadings=true;
	//tabSystem.styleSheetUri="";
	tabSystem.tabContainerClass="cmf-tabcontainer";
	tabSystem.tabSelectedKeyword="cmf-tabdefault";
	tabSystem.invertOrder=0;
	tabSystem.firstHeadingClass="cmf-firstHeading";
	tabSystem.firstHeadingKeepTrigger="cmf-tabkeepheading";
	// GLOBAL ONLY (Custom Event Listeners)
	tabSystem.style_changeEvent="onstylechange";
	tabSystem.buildEvent="onbuild";
	tabSystem.unbuildEvent="onunbuild";
	tabSystem.tab_mouseoverEvent="onmouseover";
	tabSystem.tab_mouseoutEvent="onmouseout";
	tabSystem.tab_clickEvent="onclick";
	tabSystem.onloadEvent="onload";
	tabSystem.Dependancies = ( document
					&& document.getElementById
					&& document.getElementsByTagName
					&& document.createElement
					&& document.getElementsByClassName // this is an extension component
					&& window )?1:0;
	// global sig/slot event handling
	tabSystem.addEventHandler=function _glo_tabSystem_addEventHandler_( evt, fn, obj, once ) { Listener.add( ((obj)?obj:tabSystem), evt, fn, this, once ) };
	tabSystem.removeEventHandler=function _glo_tabSystem_removeEventHandler_( evt, fn, obj ) { Listener.remove( ((obj)?obj:tabSystem), evt, fn, this ) };
	tabSystem.fireEventHandler=function _glo_tabSystem_fireEventHandler_( evt, obj, args ) { if( ((obj)?obj:this)[evt] )((obj)?obj:tabSystem)[evt](args) };
} 
tabSystem.takeOutOfMemory = function _tabSystem_takeOutOfMemory_( e ) {
	for(var x=0;x<tabSystem.instances.length;x++) {
		tabSystem.instances[x].takeOutOfMemory( );
	}
}
tabSystem.construct = function tabSystem_construct_( e ) { // render generic "catch-all" tabsets
	var ts = document.getElementsByClassName( 
					document, tabSystem.classTrigger 
					)
	for(var x=0;x<ts[ tabSystem.classTrigger ].length;x++) {
		var el=ts[ tabSystem.classTrigger ][ x ];
		tabSystem.instances.push( new tabSystem( el, true ) );
	}
	tabSystem.fireEventHandler( tabSystem.onloadEvent );
}
tabSystem.genericStyleSheet = function tabSystem_genericStyleSheet_( e ) { // "catch-all" tabset style sheets
	if(!tabSystem.styleSheet) {
		var head=document.getElementsByTagName("head").item( 0 );
		var s=document.createElement("link");
		s.rel="stylesheet";
		s.type="text/css";
		s.media="screen";
		head.appendChild( s );
		tabSystem.styleSheet=s;
	}
	tabSystem.styleSheet.href=((e)?e:tabSystem.styleSheetUri);
}
tabSystem.getTabsetByDivision = function _tabSystem_getTabsetByDivision_( el ) {
	for(var x=0;x<tabSystem.instances.length;x++) {
		if(tabSystem.instances[x].el==el) return( tabSystem.instances[x] )
	}
}
//==================================================
//=	Tab Object Constructor
//==================================================
tabSystem.tab = function _tabSystem_tab_( member ) {
	this.ts=member;
	this.index=null;
	this.tabPage=null;
	this.hClone=null;
	this.event={};
	this.heading=null;
	// tab level sig/slot event handling
	this.addEventHandler=function _tab_addEventHandler_( evt, fn, obj, once ) { Listener.add( ((obj)?obj:this), evt, fn, this, once ) };
	this.removeEventHandler=function _tab_removeEventHandler_( evt, fn, obj ) { Listener.remove( ((obj)?obj:this), evt, fn, this ) };
	this.fireEventHandler=function _tab_fireEventHandler_( evt, obj, args ) { if( ((obj)?obj:this)[evt] )((obj)?obj:this)[evt](args) };
	this.notReady="This tab is not ready."
	this.readyStateCheck = function _tabSystem_tab_readyStateCheck_( e ) {
		return (this.hClone&&this.tabPage&&this.ts) ?1:0;
	}
	this.addTabPage=function _tabSystem_tab_addTabPage_( e ) { this.tabPage=e; }
	this.createListItem = function _tabSystem_tab_createListItem_( e ) {
		if(this.hClone) {
			this.li = document.createElement("li");
			this.li.appendChild( this.hClone );
		} //else throw new Error(this.notReady);
	}
	
	this.addHeading = function _tabSystem_tab_addHeading_( dom_node ) { 
			this.hClone=dom_node;
			if(this.hClone.style.display=="none") this.hClone.style.display="block";
	}
	this.styletab = function _tabSystem_tab_styletab_( e ) {
		if( this.readyStateCheck( ) ) {
			this.hClone.style.cursor=document.all?"hand":"pointer";
			this.hClone.className=this.ts.normalTabClass+" "+this.ts.backupClassName||this.ts.className;
		}  //else throw new Error( this.notReady );
	}
	this.removeEvents = function _tabSystem_tab_removeEvents_( tab ) {
		if( this.readyStateCheck( ) ) {
			this.removeEventHandler( "onmouseout", this.event._mou_, this.hClone );
			this.removeEventHandler( "onclick", this.event._click_, this.hClone );
			this.removeEventHandler( "onmouseover", this.event._mov_, this.hClone );
	
		} //else throw new Error(this.notReady);
	}
	this.addEvents = function _tabSystem_addevents_( tab ) {
		if( this.readyStateCheck( ) ) {
			this.backupClassName=this.hClone.className;
			var index=this.index, obj=this.ts;
			this.event._mov_ = function ( e ) {
				obj.tabs[ index ].hClone.className+=" "+obj.hoverTabClass;
				obj.fireEventHandler( tabSystem.tab_mouseoverEvent, obj.tabs[ index ] );
			}
			this.event._mou_ = function ( e ) {
				obj.tabs[ index ].hClone.className=obj.tabs[ index ].backupClassName;
				obj.fireEventHandler( tabSystem.tab_mouseoutEvent, obj.tabs[ index ] );
			}
			this.event._click_ = function( e ) {
				obj.switchtab( index );
				obj.fireEventHandler( tabSystem.tab_clickEvent, obj.tabs[ index ] );
			}
			this.addEventHandler( "onmouseout", this.event._mou_, this.hClone );
			this.addEventHandler( "onclick", this.event._click_, this.hClone);
			this.addEventHandler( "onmouseover", this.event._mov_, this.hClone );
		}
		//else throw new Error(this.notReady);
	}
	this.remove = function _tabSystem_removePage_(  ) {
		if( this.readyStateCheck( ) ) {
			this.tabPage.parentNode.removeChild( this.tabPage );
			this.ts.rebuild( );
		}// else throw new Error(this.notReady);
	}
}
//==================================================
//=	TabSystem Object Constructor
//==================================================
function tabSystem( el, genericCapture ) {
	if(!genericCapture)tabSystem.instances.push(this);
	this.classTrigger=tabSystem.classTrigger;
	this.tabPageClass=tabSystem.tabPageClass;
	this.activeTabClass=tabSystem.activeTabClass;
	this.tabContainerClass=tabSystem.tabContainerClass;
	this.hoverTabClass=tabSystem.hoverTabClass;
	this.normalTabClass=tabSystem.normalTabClass;
	this.startIndex=tabSystem.startIndex;
	this.genericCapture=genericCapture;
	this.removeHeadings=tabSystem.removeHeadings;
	this.styleSheetUri=tabSystem.styleSheetUri;
	this.tabSelectedKeyword=tabSystem.tabSelectedKeyword;
	this.invertOrder=tabSystem.invertOrder;
	this.firstHeadingClass=tabSystem.firstHeadingClass;
	this.firstHeadingKeepTrigger=tabSystem.firstHeadingKeepTrigger;
	this.el = el;
	this.tabs=[];
	this.id=this.el.getAttribute("id");
	this.getTabIndexByTab=function _tabSystem_getTabIndexByTab_( e ) {
		for(var x=0;x<this.tabs.length;x++)if (this.tabs[x]==e) return(x)
	}
	// instance sig/slot event handling
	this.addEventHandler=function _tabSystem_addEventHandler_( evt, fn, obj, once ) { Listener.add( ((obj)?obj:this), evt, fn, this, once ) };
	this.removeEventHandler=function _tabSystem_removeEventHandler_( evt, fn, obj ) { Listener.remove( ((obj)?obj:this), evt, fn, this ) };
	this.fireEventHandler=function _tabSystem_fireEventHandler_( evt, obj, args ) { if( ((obj)?obj:this)[evt] )((obj)?obj:this)[evt](args) };
	this.rebuild = function _tabSystem_rebuild_( e ) {
		// this basically just collapses and re-constructs the tab system
		// doing this would obviously pick up on any new tabs that have been added.
		// need to add a more efficient way of doing this at some point (hence this tier level)
		var si=this.selected.index;
		this.deconstruct( );
		this.build( );
		this.switchtab(si);
	}
	// add a tab dynamically
	this.addTab = function _tabSystem_addTab_( div, insertBefore ) {
		// please supply a division dom node with a first child of a heading element;
		// i'm not going to wipe your arse for you, if you fuck it up, it's your problem :)
		div.className=this.tabPageClass;
		this.el.insertBefore( div, (insertBefore)?insertBefore:this.tabs[0].tabPage );
		this.rebuild();
	}
	// ie6 memory
	this.takeOutOfMemory = function _tabSystem_takeOutOfMemory_( e ) { // ie6..s
		for(x in this) {try{this[x]=null}catch(ex){;;;}}
	}
	this.addStyleSheet=function _tabSystem_addStyleSheet_( stURI ) {
		
		if(!this.genericCapture) { // if called on a generic level, bubbles up to global level
			if(!this.styleSheet) {
				var head=document.getElementsByTagName("head").item( 0 );
				this.styleSheet=document.createElement("link");
				this.styleSheet.rel="stylesheet";
				this.styleSheet.type="text/css";
				this.styleSheet.media="screen";
				this.styleSheet.href=stURI;
				head.appendChild( this.styleSheet );
			}
			else {
				this.styleSheet.disabled=0;
				this.styleSheet.href=stURI;
			}
		}
		else tabSystem.genericStyleSheet( stURI );
		this.fireEventHandler( tabSystem.style_changeEvent );
	}
	this.backup=function _tabSystem_backup_( e ) {
		// this will backup any nested tab sets too, you have been warned
		this.bDocFrag=this.el.cloneNode( 1 );
	}
	this.deconstruct=function _tabSystem_restore_( e ) {
		if(this.rendered==0) throw new Error("This tab set is not built.");
		// hide the tab container
		this.tabContainer.style.display="none";
		// we have a very nasty sitation here: nested tabsets will still take style down from parents
		// because ie only recognises the "any decendants of.." css space thingy. not direct children; ">".
		// the way to get around it is to have another class name for the tab pages on the nested tabset, but 
		// this wont be caught by generics. What a pain the arse!
		for(var x=0;x<this.tabs.length;x++) {
			// we make all tab page divisions visible
			this.tabs[x].tabPage.style.display="block";
			// if first headings had been hidden, we make them viewable ;)
			if( this.removeHeadings ) this.tabs[x].heading.style.display="block";
		}
		// we do misc stuff and fire events off etc
		this.rendered=0;
		this.fireEventHandler( tabSystem.unbuildEvent );
		var s=this.styleSheet||tabSystem.styleSheet;
		if(s)s.disabled=1;
	}
	
	this.build = function _tabSystem_build_( e ) { // division the structure..
		if(this.rendered==1) throw new Error("This tab set is already built.");
		// memory cleanup
		if(this.tabs.lengh>0) for(var x=0;x<this.tabs.length;x++) {
			for(x in this.tabs[x]) if(this.tabs[x]!=this) this.tabs[x]=null;
		}
		// reset tabs copllection
		this.tabs=[];
		//this.backup( );
		this.addStyleSheet( this.styleSheetUri );
		if( !this.hasBeenBuiltOnce && 
			this.el.className.search( 
				new RegExp( this.firstHeadingKeepTrigger ) )!=-1) this.removeHeadings=0;
		// insert a division at the beginnning of the main div to hold tabs.
		this.tabContainer = document.createElement("div");
		this.el.insertBefore( this.tabContainer, this.el.firstChild );
		this.tabContainer.style.display="block";
		this.tabContainer.className=this.tabContainerClass;
		// create a structured list in the container for the tabs to sit in, (good for no css support).
		this.ul=document.createElement( "ul" );
		this.tabContainer.appendChild( this.ul ); 
		// itterate through the tab-pages in the tab division..
		var d=this.el.getElementsByTagName("div");var z=0;
		
		for(var x=0;x<d.length;x++) {
			
			if(d[x].className.search(this.tabPageClass)!=-1 && d[x].parentNode==this.el) {
				var t = new tabSystem.tab( this );
				t.index=z;
				// check to see if user has requested a default selection on tab
				if( !this.hasBeenBuiltOnce
					 && d[x].className .search( this.tabSelectedKeyword ) != -1 ) 
						this.startIndex=z;
				// first we take out the first child of the tab page
				// we clone the node for later use.
				var h=d.item( x ).firstChild.style?d.item( x ).firstChild:d.item( x ).childNodes.item( 1 );
				if( this.removeHeadings ) {
					// now we take out the heading from the tab-page.
					h.style.display="none";
				} else h.style.display="block";
				// add heading/page to tab
				t.addTabPage( d[x] );
				t.addHeading( h.cloneNode( 1 ) );
				// style the heading 
				h.className=this.firstHeadingClass +=" "+h.className;
				
				// re-style the old heading
				t.styletab( );
				
				// insert the tab into the structured list in the container.
					
				t.createListItem( );
				// by default tabs will look the wrong way around
				if( this.invertOrder && this.ul.firstChild )  this.ul.insertBefore( t.li, this.ul.firstChild );
					else this.ul.appendChild( t.li );
			
				// reference to the origional heading
				t.heading=h;
				// add events to the tab	
				t.addEvents( );
				// add tab to main obj array;
				this.tabs[ z ]=t;
				z++ // this is the counter to keep track of tabs.
			}
		}
		// all tabs rendered, now switch to the default first index
		this.switchtab( this.startIndex, 1 );
		this.rendered=1;
		this.hasBeenBuiltOnce=1;
		this.fireEventHandler( tabSystem.buildEvent );
	}
	this.switchTabToId = function _tabSystem_switchtab_( id ) { // maybe test this? ;)
		for(var x=0;x<this.tabs.length;x++) {
			if( this.tabs[x].hClone.id && this.tabs[x].hClone.id==id ) {
				this.switchtab( this.tabs[x].index );
			}
		}
	}
	this.switchtab = function _tabSystem_switchtab_( e, firstTime ) { // switches on tab INDEX not tab
		if(!this.tabs[e]) throw new Error("tab does not exist..");
		var t=this.tabs[e]; // NOT hClone!
		if( this.selected ) {
			this.selected.styletab( );
			this.selected.addEvents( );
		
			this.selected.tabPage.style.display="none";
		}
		if( firstTime ) { // hide all tab-pages first time
			for(var x=0;x<this.tabs.length;x++) {
				this.tabs[x].tabPage.style.display="none";
			}
		}
		t.hClone.className +=" "+ this.activeTabClass;
		t.removeEvents( );
		t.tabPage.style.display="block";
		this.selected=null; this.selected=t;
	}
	if ( this.genericCapture ) this.build( );
	this.addEventHandler( "onunload", this.takeOutOfMemory, 0, 1 );
}
//==================================================
//=	Patch in a couple of things we need
//==================================================
if(document.all || document.getElementsByTagName) {
	document.getElementsByClassName = function (el) {
		var searchObj, nodeList;
		// initialize
		searchObj = n = new Object();
		for (var i = 1; i < arguments.length; i++) {
			searchObj[arguments[i]] = new Array();
		}
		nodeList = el.all || el.getElementsByTagName("*");
		// loop over all descendant elements (c)
		for (var i = 0, c = null, cn; (el.all ? c = nodeList(i) : c = nodeList.item(i)); i++) {
			if (c.nodeType == 1) {
				cn = c.className.split(" ");
				for (j = 0; j < cn.length; j++) {
					// if the current cn element is defined in searchObj, 
					// then it must be one we're searching for. add it.
					if (searchObj[cn[j]]) {
						searchObj[cn[j]][searchObj[cn[j]].length] = c;
					}
				}
			}
		}
		return ( searchObj );
	}
}
if(!Array.prototype.push) {
	Array.prototype.push =  function( e ) {
		var i;
		for(i=0; j=arguments[i]; i++) this[this.length] = j;
		return ( this.length );
	}
}
if(!window.Error) { // some browsers dont have this, and i dont want to throw strings in ie5..
	function Error( message ) {
		this.message=message;
		this.name=new String;
	}
}
//==================================================
//=	Global Code Starts
//==================================================


//if( window && tabSystem.Dependancies && Listener) Listener.add( window, "onload", tabSystem.construct, tabSystem, 1 )
//	else window.status="Standards-Check failed for tab system";

/* =================================================================================================
 * Listener - by Aaron Boodman
 * 5/23/2002; Queens, NY.
 * http://www.youngpup.net/projects/dhtml/listener/
 * 
// Event listener implimentation for javascript. Works with native events as well as custom events. 
//
// Essentially, Listener hijacks a member of an object and makes it a pointer to an internal 
// Listener method. When the hijacked member is called, Listener fires any number of other methods 
// by proxy in whatever scope you (the script author) specify. All arguments passed to the source 
// event are received by all listeners automatically.
// 
// This amounts to a very powerful event listener setup similar to "signals and slots", but without 
// the confusing nomenclature and lack of distinction between methods and events.
//
//
// syntax:
//
// Listener.add(objSource, strEventName, fpListener, objScope, blnRunOnce);
//   objSource    : the object whose events you are listening for
//   strEventName : the name of the event to listen for ("onclick", "onUpdateComplete", etc)
//   fpListener   : a pointer to the function which should fire in response to 
//                  objSource[sEventName]();
//   objScope     : the object whose scope fpListener should be run in when fired.
//   blnRunOnce   : flag that indicates whether the listener should automatically be removed after 
//                  it is first fired.
//
// Listener.remove(objSource, strEventNae, fpListener, objScope);
//   *see above for args*
//
//
 * http://www.youngpup.net/
 * ============================================================================================== */
// Tim Scarfe :
// Fix to Mozilla bug, remove attrib on listener is being confused with Listener.remove (thanks to "standard" on dhtmlcentral)
// Changed delete arr[x] to arr[x]=null for IE4 support.
function Listener(fp, scope, removing) {
        this.fp = fp;
        this.scope = scope;
        this.removeing = removing;
}
Listener.add = function(oSource, sEvent, fpDest, oScope, bRunOnce) {
        if (!oSource[sEvent] || oSource[sEvent] == null || !oSource[sEvent]._listeners) {
                oSource[sEvent] = function() { Listener.fire(oSource, sEvent, arguments) };
                oSource[sEvent]._listeners = new Array();
        }
        var idx = this.findForEvent(oSource[sEvent], fpDest, oScope);
        if (idx == -1) idx = oSource[sEvent]._listeners.length;
        
        oSource[sEvent]._listeners[idx] = new Listener(fpDest, oScope, bRunOnce);
}
Listener.remove = function(oSource, sEvent, fpDest, oScope) {
        var idx = this.findForEvent(oSource[sEvent], fpDest, oScope);
        if (idx != -1) {
                var iLast = oSource[sEvent]._listeners.length - 1;
                oSource[sEvent]._listeners[idx] = oSource[sEvent]._listeners[iLast];
                oSource[sEvent]._listeners.length--;
        }
}
Listener.findForEvent = function(fpEvent, fpDest, oScope) {
        if (fpEvent._listeners) {
                for (var i = 0; i < fpEvent._listeners.length; i++) {
                        if (fpEvent._listeners[i].scope == oScope && fpEvent._listeners[i].fp == fpDest) {
                                return i;
                        }
                }
        }
        return -1;
}
Listener.fire = function(oSourceObj, sEvent, args) {
	if(oSourceObj&&oSourceObj[sEvent]&&oSourceObj[sEvent]._listeners) { // TRS 
		var lstnr, fp;
		var last = oSourceObj[sEvent]._listeners.length - 1;
		// must loop in reverse, because we might be removing elements as we go.
		for (var i = last; i >= 0; i--) {
			lstnr = oSourceObj[sEvent]._listeners[i];
			fp = lstnr.fp;
                
			fp.apply(lstnr.scope, args);
			if (lstnr.remove) Listener.remove(oSourceObj, sEvent, lstnr.fp, lstnr.scope);
		}
	}
	
	return(-1)
}
// impliment function apply for browsers which don't support it natively
if (!Function.prototype.apply) {
        Function.prototype.apply = function(oScope, args) {
                var sarg = [];
                var rtrn, call;
                if (!oScope) oScope = window;
                if (!args) args = [];
                for (var i = 0; i < args.length; i++) {
                        sarg[i] = "args["+i+"]";
                }
                call = "oScope.__applyTemp__(" + sarg.join(",") + ");";
                oScope.__applyTemp__ = this;
                rtrn = eval(call);
                delete oScope.__applyTemp__;
                return rtrn;
        }
}