function getSourceElement (evt) {
	if(evt.target) return(evt.target);
	if(evt.srcElement) return(evt.srcELement);
}

/*if(document.defaultView.navigator.userAgent.indexOf("Firefox") != -1) {
	MouseEvent.prototype.srcElement = MouseEvent.target;

}*/
/******************************************************************************
Extension to object String
Returns the numeric part of a string
******************************************************************************/
String.prototype.extractNumber = function () {
	var number = this.match(/\d/g, "");
	var number = number.join("");
	var number = parseInt(number);
	return(number);
}

String.prototype.trim = function () {
	var string = new String(this);
	var character;

	if(string.length > 0) {
		character = string.charAt(0);
		while(character.match(/\s/) == character) {
			if(string.length > 1) {
				string = string.substr(1);
			}else{
				return("");
			}
			character = string.charAt(0);
		}
		if(string.length > 0) {
			character = string.charAt(string.length - 1);
			while(character.match(/\s/) == character) {
				if(string.length > 1) {
					string = string.substr(0, string.length - 1);
				}else{
					return("");
				}
				character = string.charAt(string.length - 1);
			}
		}
	}

	return(string);
}


/******************************************************************************
Because in IE it is impossible to change type of element after creation
via document.creatElement ...
******************************************************************************/
function createInputElement (elementType, elementName) {
	var inputElement;
	var doctype = getDocumentType();
	var tagEnding;

	if(doctype == "xhtml") {
		tagEnding = ' />';
	}else{
		tagEnding = '>';
	}

	if(isIe()) {
		inputElement = document.createElement('<input type="' + elementType + '" name="' + elementName + '"' + tagEnding);
	}else{
		inputElement = document.createElement("INPUT");
		inputElement.setAttribute("type", elementType);
		inputElement.setAttribute("name", elementName);
	}

	return(inputElement)
}

/******************************************************************************
Figures out what kind of documenttype we have currently,
and returns either html, or xhtml
******************************************************************************/
function getDocumentType () {
	if(getDOMLevel() != false) {
		var publicid = document.doctype.publicId.toLowerCase();
		var systemid = document.doctype.systemId.toLowerCase();

		if(publicid.indexOf("xhtml") != -1 &&
		systemid.indexOf("xhtml") != -1) {
			return("xhtml");
		}else{
			return("html");
		}
	}
	return(false);
}

isIe();
function isIe () {
	if(document.all && navigator.userAgent.toLowerCase().indexOf("opera") == -1) return(true);
	return(false);
}

/******************************************************************************
Figures out the DOM-Level that is available in the current environment
******************************************************************************/
function getDOMLevel () {
	if(document.implementation.hasFeature("core", "3.0")) {
		return(3);
	}else if(document.implementation.hasFeature("core", "2.0")){
		return(2);
	}else if(document.implementation.hasFeature("core", "1.0")) {
		return(1);
	}else{
		return(false);
	}
}

/* Reference Article:
Dustin Diaz:
http://www.dustindiaz.com/top-ten-javascript/
*/

/* addEvent: simplified event attachment */
function addEvent( obj, type, fn ) {
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else {
		obj["on"+type] = obj["e"+type+fn];
	}
}

var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
		add : function(node, sEventName, fHandler){
			listEvents.push(arguments);
		},
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				item[0][item[1]] = null;
			};
		}
	};
} ();
addEvent(window,'unload',EventCache.flush);

/* window 'load' attachment */
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

/* grab Elements from the DOM by className */
function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
	node = document;
	if ( tag == null )
	tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

/* toggle an element's display */
function toggleDisplay(obj) {
	var el = document.getElementById(obj);
	if ( el.style.display != 'none' ) {
		el.style.display = 'none';
	}
	else {
		el.style.display = '';
	}
}

/* insert an element after a particular node */
function insertAfter(parent, node, referenceNode) {
	parent.insertBefore(node, referenceNode.nextSibling);
}

/* Array prototype, matches value in array: returns bool */
Array.prototype.inArray = function (value) {
	var i;
	for (i=0; i < this.length; i++) {
		if (this[i] === value) {
			return true;
		}
	}
	return false;
};

/* get, set, and delete cookies */
function getCookie( name ) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ";", len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}

function setCookie( name, value, expires, path, domain, secure ) {
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+"="+escape( value ) +
				( ( expires ) ? ";expires="+expires_date.toGMTString() : "" ) + //expires.toGMTString()
				( ( path ) ? ";path=" + path : "" ) +
				( ( domain ) ? ";domain=" + domain : "" ) +
				( ( secure ) ? ";secure" : "" );
}

function deleteCookie( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + "=" +
	( ( path ) ? ";path=" + path : "") +
	( ( domain ) ? ";domain=" + domain : "" ) +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

/* quick getElement reference */
// function $() {
// 	var elements = new Array();
// 	for (var i = 0; i < arguments.length; i++) {
// 		var element = arguments[i];
// 		if (typeof element == 'string')
// 			element = document.getElementById(element);
// 		if (arguments.length == 1)
// 			return element;
// 		elements.push(element);
// 	}
// 	return elements;
// }






/* Function printf(format_string,arguments...)
 * Javascript emulation of the C printf function (modifiers and argument types
 *    "p" and "n" are not supported due to language restrictions)
 *
 * Copyright 2003 K&L Productions. All rights reserved
 * http://www.klproductions.com
 *
 * Terms of use: This function can be used free of charge IF this header is not
 *               modified and remains with the function code.
 *
 * Legal: Use this code at your own risk. K&L Productions assumes NO resposibility
 *        for anything.
 ********************************************************************************/
function printf(fstring)
{ var pad = function(str,ch,len)
{ var ps='';
        for(var i=0; i<Math.abs(len); i++) ps+=ch;
				return len>0?str+ps:ps+str;
}
    var processFlags = function(flags,width,rs,arg)
{ var pn = function(flags,arg,rs)
{ if(arg>=0)
{ if(flags.indexOf(' ')>=0) rs = ' ' + rs;
                else if(flags.indexOf('+')>=0) rs = '+' + rs;
}
            else
							rs = '-' + rs;
						return rs;
}
        var iWidth = parseInt(width,10);
				if(width.charAt(0) == '0')
{ var ec=0;
            if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) ec++;
						if(rs.length<(iWidth-ec)) rs = pad(rs,'0',rs.length-(iWidth-ec));
						return pn(flags,arg,rs);
}
        rs = pn(flags,arg,rs);
				if(rs.length<iWidth)
{ if(flags.indexOf('-')<0) rs = pad(rs,' ',rs.length-iWidth);
            else rs = pad(rs,' ',iWidth - rs.length);
}
        return rs;
}
    var converters = new Array();
		converters['c'] = function(flags,width,precision,arg)
{ if(typeof(arg) == 'number') return String.fromCharCode(arg);
        if(typeof(arg) == 'string') return arg.charAt(0);
				return '';
}
    converters['d'] = function(flags,width,precision,arg)
{ return converters['i'](flags,width,precision,arg);
}
    converters['u'] = function(flags,width,precision,arg)
{ return converters['i'](flags,width,precision,Math.abs(arg));
}
    converters['i'] =  function(flags,width,precision,arg)
{ var iPrecision=parseInt(precision);
        var rs = ((Math.abs(arg)).toString().split('.'))[0];
				if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
				return processFlags(flags,width,rs,arg);
}
    converters['E'] = function(flags,width,precision,arg)
{ return (converters['e'](flags,width,precision,arg)).toUpperCase();
}
    converters['e'] =  function(flags,width,precision,arg)
{ iPrecision = parseInt(precision);
        if(isNaN(iPrecision)) iPrecision = 6;
				rs = (Math.abs(arg)).toExponential(iPrecision);
				if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs.replace(/^(.*)(e.*)$/,'$1.$2');
				return processFlags(flags,width,rs,arg);
}
    converters['f'] = function(flags,width,precision,arg)
{ iPrecision = parseInt(precision);
        if(isNaN(iPrecision)) iPrecision = 6;
				rs = (Math.abs(arg)).toFixed(iPrecision);
				if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs + '.';
				return processFlags(flags,width,rs,arg);
}
    converters['G'] = function(flags,width,precision,arg)
{ return (converters['g'](flags,width,precision,arg)).toUpperCase();
}
    converters['g'] = function(flags,width,precision,arg)
{ iPrecision = parseInt(precision);
        absArg = Math.abs(arg);
				rse = absArg.toExponential();
				rsf = absArg.toFixed(6);
				if(!isNaN(iPrecision))
				{ rsep = absArg.toExponential(iPrecision);
				rse = rsep.length < rse.length ? rsep : rse;
				rsfp = absArg.toFixed(iPrecision);
				rsf = rsfp.length < rsf.length ? rsfp : rsf;
				}
				if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) rse = rse.replace(/^(.*)(e.*)$/,'$1.$2');
				if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) rsf = rsf + '.';
				rs = rse.length<rsf.length ? rse : rsf;
				return processFlags(flags,width,rs,arg);
}
    converters['o'] = function(flags,width,precision,arg)
{ var iPrecision=parseInt(precision);
        var rs = Math.round(Math.abs(arg)).toString(8);
				if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
				if(flags.indexOf('#')>=0) rs='0'+rs;
				return processFlags(flags,width,rs,arg);
}
    converters['X'] = function(flags,width,precision,arg)
{ return (converters['x'](flags,width,precision,arg)).toUpperCase();
}
    converters['x'] = function(flags,width,precision,arg)
{ var iPrecision=parseInt(precision);
        arg = Math.abs(arg);
				var rs = Math.round(arg).toString(16);
				if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
				if(flags.indexOf('#')>=0) rs='0x'+rs;
				return processFlags(flags,width,rs,arg);
}
    converters['s'] = function(flags,width,precision,arg)
{ var iPrecision=parseInt(precision);
        var rs = arg;
				if(rs.length > iPrecision) rs = rs.substring(0,iPrecision);
				return processFlags(flags,width,rs,0);
}
    farr = fstring.split('%');
		retstr = farr[0];
		fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
		for(var i=1; i<farr.length; i++)
{ fps=fpRE.exec(farr[i]);
        if(!fps) continue;
				if(arguments[i]!=null) retstr+=converters[fps[4]](fps[1],fps[2],fps[3],arguments[i]);
				retstr += fps[5];
}
    return retstr;
}
/* Function printf() END */

