/* This file was compressed using MbCompression library. http://blog.mironabramson.com */ Array.prototype.clone = function() { return this.slice(0); };

String.prototype.toTitleCase = function()
{
	var parts = this.split(/\s+/);
	for (var idx = 0, len = parts.length, part; idx < len; idx++)
	{
		part = parts[idx];
		if (part.length === 0) { continue; }
		parts[idx] = part.charAt(0).toUpperCase() + part.substr(1).toLowerCase();
	}
	return parts.join(' ');
};

String.prototype.unencodeHTML = function()
{
	return jQuery('<div>' + this + '</div>').text();
};

String.prototype.encodeHTML = function()
{
	return jQuery('<div></div>').text(this).text();
};

/**
 * Creates a proxy to the function proxy is called on which will get called with the arguments you supply to the proxy function
 * Note:	1) Arguments passed into the proxied function which this returns will be ignored.
 *			2) The proxied function gets called in the global scope if no scope is supplied
 */
Function.prototype.proxy = function(scope)
{
	var func = this;
	var args = Array.prototype.slice.apply(arguments, [1]);
	return function() { func.apply(scope||null, Array.prototype.slice.apply(arguments, [0]).concat(args)); }
};

/**
 * Creates a delegate to the current function which will get called in the scope you supply
 */
Function.prototype.delegate = function(scope)
{
	var func = this;
	return function() { func.apply(scope, arguments); }
};

Number.prototype.addCommas = function()
{
	var num = this.toString();
	
	//if there is a decimal, remove it before formatting
	var isDecimal = /\./.test(num);	
	if (isDecimal) {
	    var decimalFraction = parseFloat(num.match(/(\..+)/gi,'')).toFixed(2).toString().replace(/(.+\.)/gi,'');
	    num = num.replace(/(\..+)/gi,'');
	}
	
	var len = num.length;
	var partsCount = Math.floor(len / 3);
	var idxCounter = len % 3 || 3; // n cannot be ZERO or causes infinite loop

	// break the number into chunks of 3 digits; first chunk may be less than 3
	var sb = [];
	for (var idx = 0; idx < len; idx += idxCounter)
	{
		if (idx != 0) { idxCounter = 3; }
		sb[sb.length] = num.substr(idx, idxCounter);
		partsCount -= 1;
	}

	// put chunks back together, separated by comma
	num = sb.join(',');
	
	//if there was a decimal, add it back
	if (decimalFraction) {	    
	    num = num+'.'+decimalFraction;    
	}
	
	return num;
};

Number.prototype.toUSD = function()
{
	return '$' + this.addCommas();
};
/*
 * jQuery 1.2.6 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
 * $Rev: 5685 $
 */
(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break;}else
for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
/*$.fn.extend(
{
	kill: function() { var elm = this; $(elm).parent().get(0).removeChild(elm.get(0)); return elm; }
});*/

/**
 * Creates a Namespace
 */
$.ns = function(namespace, value, root)
{
	var parent = root || window;
	var namespaces = namespace.split('.');
	var len = namespaces.length;
	var name;
	if (len > 1)
	{
		len--;
		for (var idx = 0; idx < len; idx++)
		{
			name = namespaces[idx];
			if (!parent[name]) { parent[name] = {}; }
			parent = parent[name];
		}
		name = namespaces[len];
	}
	else
	{
		name = namespace;
	}
	
	parent[name] = (typeof(value) !== 'undefined')? value : {};
	
	return parent[name];
};

$._classAddToBase = function(base, prop, scope, superClass)
{
	var method = function()
	{
		return superClass.prototype[prop].apply(scope, arguments);
	};
	base[prop] = method;
};

$._getConstructor = function(constructor, proto, superClass)
{
	/*if (superClass)
	{
		var classAddToBase = function(base, prop, scope, superClass)
		{
			var method = function()
			{
				return superClass.prototype[prop].apply(scope, arguments);
			};
			base[prop] = method;
		}
	}*/
	if (!constructor)
	{
		if (!superClass)
		{
			constructor = function() { return this; }
			$.extend(constructor.prototype, proto);
		}
		else
		{
			constructor = function()
			{
				var scope = this;
				this.base = function()
				{
					superClass.apply(scope, arguments);
					var _base = {};
					for (var prop in superClass.prototype)
					{
						if (proto && !proto[prop]) { continue; }
						$._classAddToBase(_base, prop, scope, superClass);
					}
					this.base = _base;
				};
				return this;
			}
			$.extend(constructor.prototype, superClass.prototype, proto);
		}
	}
	else
	{
		if (!superClass)
		{
			$.extend(constructor.prototype, proto);
		}
		else
		{
			var constructorBak = constructor;
			var protoBak = constructorBak.prototype;
			
			constructor = function()
			{
				var scope = this;
				this.base = function()
				{
					superClass.apply(scope, arguments);
					
					var _base = {};
					for (var prop in superClass.prototype)
					{
						if (proto && !proto[prop]) { continue; }
						$._classAddToBase(_base, prop, scope, superClass);
					}
					this.base = _base;
				};
				
				constructorBak.apply(this, arguments);
				return this;
			}
			$.extend(constructor.prototype, superClass.prototype, protoBak, proto);
		}
	}
	
	return constructor;
};

/**
 * Creates a Class constructor
 */
$.createClass = function(namespace, constructor, proto, superClass, staticMembers)
{
	var constructor = $._getConstructor(constructor, proto, superClass, staticMembers);
	$.extend(constructor, staticMembers);
	return $.ns(namespace, constructor);
};

/**
 * Creates a Singleton constructor
 */
$.createSingleton = function(namespace, constructor, proto, superClass)
{
	var constructor = $._getConstructor(constructor, proto, superClass);
	var singleton = new constructor();
	return $.ns(namespace, singleton);
};
/**
 * CLASS: Event
 * @param type	String	Type of event
 * @param props	Object	Key value pairs to extend this object with
 */
$.createClass('$.Event', function(type)
{
	this.type = type;
	this.target = {};
});

$.Event.isTypeValid = function(eventClass, type)
{
	var typeIsValid = false;
	for (var prop in eventClass)
	{
		if (eventClass[prop] === type) { typeIsValid = true; break; }
	}
	return typeIsValid;
};

/**
 * EventDispatcher
 */
$.createClass('$.EventDispatcher', function()
{
	this.__events = {};
},
{
	addEventListener: function(type, listener)
	{
		if (typeof(type) !== 'string' || type.length === 0) { throw new Error('Invalid event type. Expected a non-zero length string.'); }
		if (typeof(listener) !== 'function') { throw new Error('Invalid event listener. Expected a function.'); }
		if (!this.__events[type])
		{
			this.__events[type] = [];
		}
		this.__events[type].push(listener);
	},
	removeEventListener: function(type, listener)
	{
		var listeners = this.__events[type];
		if (!listeners) { return; }
		for (var idx = 0, len = listeners.length; idx < len; idx++)
		{
			if (listeners[idx] !== listener) { continue; }
			listeners.splice(idx, 1);
			break;
		}
	},
	dispatchEvent: function(evt)
	{
		if (!this.__events || !evt || !evt.type || !evt.target) { throw new Error('Invalid event. Expected an Event object.'); }
		var listeners = this.__events[evt.type];
		if (!listeners) { return; }
		evt.target = this;
		for (var idx = 0, len = listeners.length; idx < len; idx++)
		{
			listeners[idx](evt);
		}
	}
});
jQuery.fn.wresize = function(f) 
{
	wresize = {fired: false, width: 0};

	function resizeOnce() 
	{
		if (jQuery.browser.msie)
		{
			if (!wresize.fired)
			{
				wresize.fired = true;
			}
			else 
			{
				var version = parseInt(jQuery.browser.version, 10);
				wresize.fired = false;
				if (version < 7)
				{
					return false;
				}
				else if (version == 7)
				{
					//a vertical resize is fired once, an horizontal resize twice
					var width = jQuery(window).width();
					if (width != wresize.width)
					{
						wresize.width = width;
						return false;
					}
				}
			}
		}
		return true;
	}

	function handleWResize(e) 
	{
		if (resizeOnce())
		{
			return f.apply(this, [e]);
		}
	}

	this.each( function() 
	{
		if (this == window)
		{
			$(this).resize(handleWResize);
		}
		else
		{
			$(this).resize(f);
		}
	});

	return this;
};
/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-07-21 18:45:56 -0500 (Sat, 21 Jul 2007) $
 * $Rev: 2447 $
 *
 * Version 2.1.1
 */
(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
jQuery.createSingleton('$.console', function()
{
    this._linkedLogs = {};
	this._containerElm = null;
	this._listElm = null;
	this._isShown = false;
	this._startTime = this._lastTime = this._totalSeconds = new Date().getTime();
	this._messages = [];
	this._counter = 0;
	this._attemps = [];
	this._code = '37|39|37|39';
	this._resetTimer = null;
	this._containerWidth = 550;
	this._containerStyle = 'position:absolute;display:none;top:0;right:10px;z-index:100000;width:' + this._containerWidth + 'px;height:350px;background-color:#111;';
	this._listStyle = 'list-style:decimal;position:relative;display:block;width:auto;height:auto;overflow:visible;';
	this._liStyle = 'position:relative;display:block;width:auto;height:auto;overflow:hidden;margin-bottom:5px;padding:2px 10px;color:#0F0;font:normal 11px monospace;white-space:nowrap;';
},
{
    // one to one log linking
    log: function(message, id)
	{
	    var now = new Date().getTime();
	    if (id) { this._linkLog(id, now); }
	    var seconds = (now - this._lastTime) / 1000;
	    this._totalSeconds = (now - this._startTime) / 1000;
	    
	    var colorCss = '';
	    var borderTopCss = '';
	    var borderBottomCss = '';
	    var linkedLog = this._linkedLogs[id];
	    if (linkedLog)
	    {
	        colorCss = 'color:#66F;';
	        if (linkedLog.stop)
	        {
	            borderBottomCss = 'border-bottom:1px solid #F00';
	        }
	        else
	        {
	            borderTopCss = 'border-top:1px solid #6F6';
	        }
	    }
	    var formattedMessage = '<li style="' + this._liStyle + ((this._counter%2 === 0)? 'background-color:#000;' : '') + colorCss + borderTopCss + borderBottomCss + '">' + (++this._counter) + ') [' + seconds + ' secs, total: ' + this._totalSeconds + ' secs';
	    if (linkedLog && linkedLog.stop)
	    {
	        formattedMessage += ', linked: ' + ((linkedLog.stop - linkedLog.start)/1000) + ' secs';
	    }
	    formattedMessage += ']<br /> - ' + message + '</li>';
	    this._lastTime = now;
	    
	    this._messages.push(formattedMessage);
	    
	    if (this._isShown)
	    {
	        $('#_console_total_').text('total: ' + this._totalSeconds + ' secs');
	        this._listElm.append(formattedMessage);
	    }
	    
		return this;
	},
	show: function()
	{
	    if (this._isShown) { return; }
	    if (!this._containerElm)
	    {
	        var html = [];
	        html.push('<div id="_console_" style="' + this._containerStyle + '">');
	        html.push(' <div style="position:relative;width:' + this._containerWidth + 'px;height:20px;overflow:hidden;background-color:#333;border-bottom:1px solid #666;padding:0 10px;">');
	        html.push('     <div id="_console_total_" style="position:absolute;left:10px;top:0;z-index:1;width:100px;height:100%;overflow:hidden;color:#0F0;font:normal 11px monospace;line-height:20px;">total: 0 secs</div>');
	        html.push('     <a href="#" style="display:block;position:absolute;right:20px;top:0;z-index:2;width:auto;height:100%;overflow:hidden;text-align:right;">x</a>');
	        html.push(' </div>');
	        html.push(' <div style="position:relative;width:' + this._containerWidth + 'px;height:310px;overflow:auto;">');
	        html.push('     <ul style="' + this._listStyle + '"></ul>');
	        html.push(' </div>');
	        html.push('</div>');
	        
	        this._containerElm = $(html.join(''))
	            .appendTo(document.body)
	            .bgiframe();
	        
	        this._containerElm.find('a').click(function(evt){ evt.preventDefault(); $.console.hide(); });
	        
	        this._listElm = this._containerElm.find('ul');
	    }
	    else
	    {
	        this._listElm = this._containerElm.find('ul');
	    }

	    if (this._messages.length > 0)
	    {
	        $('#_console_total_').text('total: ' + this._totalSeconds + ' secs');
	        
	        this._listElm.html(this._messages.join(''));
	    }
	    this._containerElm.show();
	    this._isShown = true;
	},
	hide: function()
	{
	    if (!this._containerElm || !this._isShown) { return; }
	    this._containerElm.hide();
	    this._isShown = false;
	},
	
	init: function()
    {
        $(document).keydown(this._onKeyDown.delegate(this));
    },
    
    deleteLinkedLog: function(id)
    {
        if (!id || !this._linkedLogs[id]) { return; }
        delete this._linkedLogs[id];
    },
    
    _linkLog: function(id, timestamp)
    {
        if (!this._linkedLogs[id])
        {
            this._linkedLogs[id] = { start: timestamp, stop: 0 };
        }
        else
        {
            // can only link to log entries - so delete it
            if (this._linkedLogs[id].stop)
            {
                this.deleteLinkedLog();
            }
            this._linkedLogs[id].stop = timestamp;
        }
    },
    
    _onKeyDown: function(evt)
    {
        if (this._isShown) { return; }
        
        var key = (evt.charCode)? evt.charCode : (evt.keyCode)? evt.keyCode : 0;
        //if (window.console) { window.console.log(evt.shiftKey +':'+key+','+this._attemps.join('|')); }
        if (evt.ctrlKey && this._isInCode(key)) //evt.shiftKey && 
        {
            this._attemps.push(key);
            
            if (this._isValidCode())
            {
                this._reset();
                this.show();
            }
        }
        this._startReset();
    },
    _startReset: function()
    {
        if (this._resetTimer)
        {
            clearTimeout(this._resetTimer);
            this._resetTimer = null;
        }
        this._resetTimer = setTimeout(this._reset.delegate(this), 500);
    },
    _reset: function()
    {
        this._attemps = [];
    },
    
    _isInCode: function(key)
    {
        return (('|'+this._code+'|').indexOf('|'+key+'|') > -1);
    },
    
    _isValidCode: function()
    {
        return (this._attemps.join('|') === this._code);
    }
});
$.console.log('created console');
$.console.init();
/*
 * jQuery.Modal
 * 
 * A modal dialog which can also be used for popup layers.
 * 
 * Modal needs the following configuration parameters:
 * 
 * elm					[required]	jQuery query selector (or dom element)
 * settings.title		[optional]	(string) Title/header html. Default = ''
 * settings.fixed		[optional]	(boolean) Whether the modal is position:fixed or not. Default = true
 * settings.modal		[optional]	(boolean) Whether the modal has a modal blackout "screen" or not. Default = true
 * settings.closeable	[optional]	(boolean) Whether the modal is closable via a close button or not . Default = true
 * settings.printable	[optional]	(boolean) Whether the modal is printable via a print button or not . Default = false
 * settings.closeText	[optional]	(string) Close button text - only used if modal is closable. Default = 'close'
 * settings.x			[optional]	(number) X position of modal. Default = null (centered horizontally)
 * settings.y			[optional]	(number) Y position of modal. Default = null (centered vertically)
 * settings.hookCount	[optional]	(number) Number of html hooks to add to the container (<span class="hk{n}}"></span>). Default = 0
 */
jQuery.createClass('jQuery.Modal',
// Constructor
function(elm, settings)
{
	this.id = elm.id;

	elm = jQuery(elm);
	this.settings = jQuery.extend(
	{
		title: '',
		fixed: true,
		modal: true,
		closeable: true,
		closeText: 'close',
		printable: false,
		printText: 'print',
		x: null,
		y: null,
		hookCount: 0,
		showHandler: function(){},
		beforeHideHandler: function(){},
		hideHandler: function(){}
	}, settings);
	
	this._initialized = false;
	this.isHidden = false;
	this._ie6 = (jQuery.browser.msie && jQuery.browser.version.charAt(0) === '6');
	
	this.elements = { cover:null, content:elm, wrapper:elm };
	
	this._init();
	
	jQuery.Modal._instances.push(this);
	
	return this;
},
// Instance (prototype) members
{
	/**
	 * PUBLIC METHODS
	 */
	getContentElm: function()
	{
		return this.elements.content;
	},
	
	/*
	 * x, y, fixed, modal
	 */
	show: function(settings)
	{
		this.settings = jQuery.extend(this.settings, settings);
		
		if (this.settings.modal)
		{
			this.elements.cover.css({ opacity: jQuery.Modal._coverOpacity, display: 'block' });
		}
		
		this.elements.wrapper.show();
		
		this.isHidden = false;
		
		if (!this._initialized)
		{
			this._initialized = true;
			this._onResize();
		}
		else
		{
			var win = jQuery(window);
			var viewportWidth = win.width();
			var viewportHeight = win.height();
			this._position(viewportWidth, viewportHeight);
		}
		
		this.settings.showHandler(this);
	},
	
	hide: function()
	{
	    this.settings.beforeHideHandler(this);
	    
		if (this.settings.modal)
		{
			this.elements.cover.fadeOut();
		}
		this.elements.wrapper.hide();

		this.settings.hideHandler(this);
		
		this.isHidden = true;
	},
	
	moveTo: function(x, y)
	{
		this.settings.x = x;
		this.settings.y = y;
		
		var win = jQuery(window);
		var viewportWidth = win.width();
		var viewportHeight = win.height();
		this._position(viewportWidth, viewportHeight);
	},
	
	/**
	 * PRIVATE METHODS
	 */
	_position: function(viewportWidth, viewportHeight)
	{
		var y = (typeof(this.settings.y) === 'number')? this.settings.y : Math.round((viewportHeight - this.elements.wrapper.outerHeight()) / 2);
		var x = (typeof(this.settings.x) === 'number')? this.settings.x : Math.round((viewportWidth - this.elements.wrapper.outerWidth()) / 2);
		var win = jQuery(window);
		var scrollY = win.scrollTop();
		var scrollX = win.scrollLeft();
		if (!this.settings.fixed || this._ie6)
		{
			y += win.scrollTop();
			x += win.scrollLeft();
		}
		
		if (y < 0) { y = 0; }
		
		this.elements.wrapper.css({ top: y+'px', left: x+'px' });
		
		if (this._ie6)
		{
			this.elements.cover.css({ top: scrollY+'px', left: scrollX+'px' });
		}
	},
	_createCover: function()
	{
		if (!this.settings.modal) { return; }

		var cover = jQuery('#modal-cover');
		if (cover.length === 1)
		{
			this.elements.cover = cover;
			return;
		}
		
		// Set up the cover
		this.elements.cover = jQuery('<div id="modal-cover"></div>').appendTo(document.body).bgiframe();
		
		jQuery.Modal._coverOpacity = (!this.elements.cover.get(0).filters)? this.elements.cover.css('opacity') : (this.elements.cover.get(0).filters.alpha.opacity/100);
	},
	_resizeCover: function(viewportWidth, viewportHeight)
	{
		if (!this._ie6 || !this.settings.modal || !this.elements.cover) { return; }
		
		var docElm = document.documentElement;
		var width = docElm.clientWidth;
		var height = docElm.clientHeight;
		this.elements.cover.css({ width: width+'px', height: height+'px' });
	},
	_resizeWrapper: function()
	{
		if (!this._ie6) { return; }
		this.elements.wrapper.css({ width: this.elements.content.outerWidth()+'px' });
	},
	
	_onResize: function()
	{
		var win = jQuery(window);
		var viewportWidth = win.width();
		var viewportHeight = win.height();
		this._resizeWrapper();
		this._position(viewportWidth, viewportHeight);
		this._resizeCover(viewportWidth, viewportHeight);
	},
	_onScroll: function()
	{
		if (!this._ie6 || !this.settings.fixed) { return; }
		var win = jQuery(window);
		var viewportWidth = win.width();
		var viewportHeight = win.height();
		this._position(viewportWidth, viewportHeight);
	},
	_onCloseClick: function(evt)
	{
		evt.preventDefault();
		this.hide();
	},
	
	_onPrintClick: function(evt)
	{
		evt.preventDefault();
		//this.hide();
	    
		//alert('print');
	},
	
	_init: function()
	{
		this._createCover();
		
		var classes = ['modal-wrap'];
		if (this.settings.fixed) { classes.push('modal-fixed'); }
		if (this.settings.closeable) { classes.push('modal-closeable'); }
		if (this.settings.printable && this.id == 'map-directions') {
		    classes.push('modal-printable');
        }
		if (this.settings.title.length > 0) { classes.push('modal-title'); }
		
		// Wrap the element
		this.elements.content.addClass('modal-content-wrap');
		this.elements.content.wrap('<div class="' + classes.join(' ') + '"><div class="modal-inner"></div></div>');
		this.elements.content.css('display', 'block');
		var innerWrapper = this.elements.content.parent();
		this.elements.wrapper = innerWrapper.parent();
		if (!this.settings.modal)
		{
			this.elements.wrapper.bgiframe();
		}

		// Add the title
		if (this.settings.title)
		{
			innerWrapper.prepend(this.settings.title);
		}

		// Add the close button
		if (this.settings.closeable)
		{
			innerWrapper.append('<a href="#" class="modal-close" title="close"><span>' + this.settings.closeText + '</span></a>');
			//jQuery('a.modal-close', this.elements.wrapper).click(this._onCloseClick.delegate(this)).bgiframe();
			jQuery('a.modal-close', this.elements.wrapper).click(this._onCloseClick.delegate(this));
		}
		// Add the print button
		if (this.settings.printable)
		{
			innerWrapper.append('<a href="#" class="modal-print" title="print"><span>' + this.settings.printText + '</span></a>');
			//jQuery('a.modal-print', this.elements.wrapper).click(this._onPrintClick.delegate(this)).bgiframe();
			jQuery('a.modal-print', this.elements.wrapper).click(this._onPrintClick.delegate(this));
		}
		if (this.settings.hookCount > 0)
		{
			var hookHTML = [];
			for (var idx = 1; idx <= this.settings.hookCount; idx++)
			{
				hookHTML[hookHTML.length] = '<span class="hk' + idx + '"></span>';
			}
			innerWrapper.append(hookHTML.join(''));
		}

		jQuery(document.body).append(this.elements.wrapper);
		
		var top = this.elements.content.css('top'); //this.elements.content.get(0).style.top;		
		if (top && !isNaN(top = parseInt(top)) && top > 0) { this.elements.content.css('top', '0'); this.settings.y = top; }

		this._resizeWrapper();

		var win = jQuery(window);
		var viewportWidth = win.width();
		var viewportHeight = win.height();
		this._position(viewportWidth, viewportHeight);
		this._resizeCover(viewportWidth, viewportHeight);

		win.wresize(this._onResize.delegate(this))
			.scroll(this._onScroll.delegate(this));
	}
}, null,
// Static members
{
	_instances: [],
	_coverOpacity: 0,
	get: function(elm)
	{
		var modal = null;
		var domElm = jQuery(elm).get(0);
		for (var idx = 0, len = jQuery.Modal._instances.length; idx < len; idx++)
		{
			if (jQuery.Modal._instances[idx].getContentElm().get(0) === domElm)
			{
				modal = jQuery.Modal._instances[idx];
				break;
			}
		}
		return modal;
	}
});

(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
$.createClass('X.ModalFactoryEvent', function(type, modalId)
{
	this.base(type);
	this.modalId = modalId;
	return this;
}, null, $.Event);

/**
 * SINGLETON: ModalFactory, the one-stop shop for all your modal needs
 */
jQuery.createSingleton('X.ModalFactory', function()
{
    this.base();
    
	this.currentModal = null;
	this.modals = {};
	this.instanceCounter = 0;
},
{	
	create: function(cssClassNames, content, closeable, printable, x, y, onShowHandler, fixed)
	{
		var id = '__modal_' + (++this.instanceCounter) + '__';
		
		var classNames = [];
		if (cssClassNames && cssClassNames.length > 0)
		{			
			if (typeof(cssClassNames) == 'string')
			{
				classNames.push(cssClassNames);
			}
			else // Assume an array
			{
				classNames = classNames.concat(cssClassNames);
			}
		}
		
		var modalElm = $('<div id="' + id + '" class="' + classNames.join(' ') + '">' + content + '</div>');
		
		var options = { closeable: closeable, printable: printable, x: x, y: y, fixed: fixed };
		options = $.extend(
		{
			modal: true,
			fixed: true,
			closeable: false,
			printable: false,
			x: null,
			y: null
		}, options);

		this.modals[id] = new $.Modal(modalElm.get(0), options);
		
		this.dispatchEvent(new X.ModalFactoryEvent('create', id));
		
		this.show(id);
		
		if (typeof(onShowHandler) === 'function')
		{
		    onShowHandler(this.modals[id]);
		}
	},
	
	show: function(id)
	{
		if (typeof(id) !== 'string' || id.length === 0) { return; }
		
		this.hide();
		
		var modal = this.modals[id];
		if (!modal) { return; }
		var modalElm = $('#' + id);
		
		if (modalElm.length !== 1 || modalElm.hasClass('wait-available')) { return; }
		
		this.currentModal = modal;
		
		modal.show();
	},
	
	init: function()
	{
		$('a.modal-opener').click(this._onClickOpener);
	},
	
	_buildModal: function(id)
	{
	    var elm = $('#'+id);
	    if (elm.length === 0) { return; }
			
		var options =
		{
			fixed: !elm.hasClass('not-fixed'),
			closeable: !elm.hasClass('not-closeable'),
			printable: !elm.hasClass('not-printable'),
			modal: true,
			x: null,
			y: null
		};
		
		X.ModalFactory.modals[id] = new $.Modal(elm.get(0), options);
		
		this.dispatchEvent(new X.ModalFactoryEvent('create', id));
	},
	
	// Called in the scope of the link dom element
	_onClickOpener: function(evt)
	{
		evt.preventDefault();
		
		var id;
		if (this.rel)
		{
			try { var options = $.evalJSON(this.rel); id = options.modalId; }
			catch (ex) { id = this.rel; }			
			if ($('#'+id+'.modal').length === 0)
			{
			    id = this.name || null;
			}
		}
		else
		{
			id = this.name || null;
		}
		
		if (!id || $('#'+id+'.modal').length === 0) { return; }		
		if (!X.ModalFactory.modals[id])
		{
		    X.ModalFactory._buildModal(id);
		}
		
		X.ModalFactory.show(id);
	},
	
	hide: function()
	{
		if (!this.currentModal) { return; }
		if (this.currentModal.isHidden) { this.currentModal = null; return; }
		
		this.currentModal.hide();
		this.currentModal = null;
	},
	
	destroy: function()
	{
		if (!this.currentModal) { return; }
		
		var id = this.currentModal.id;
		
		this.hide();
		
		$('#' + id).remove();
	}
}, $.EventDispatcher);

/**
 * SINGLETON: OverlayFactory, overlays built to order
 */
jQuery.createSingleton('X.OverlayFactory', function()
{
	this.currentOverlay = null;
},
{
	show: function(type, content, elm)
	{
		var html = [];
		html[html.length] = '<div class="overlay-content">';
		html[html.length] = content;
		html[html.length] = '</div>';
		
		if (!elm) { elm = $(html.join('')).appendTo('#content');}
		else if (typeof(elm) === 'string') { elm = $(elm).html(content); }
		else if (!elm.css) { elm = $(elm).html(content); }
		
		this.hide();
		
		this.currentOverlay = elm;
		
		//$('#screen').show();
		this.currentOverlay.css({ height:'160px' });
		this.currentOverlay.fadeIn('fast');
	},
	
	create: function(cssClassNames, content,  x, y)
	{
	    // Destroy any existing overlay - like the modal, can only have one at a time
	    this.destroy();
	    
	    var classNames = ['overlay'];
		
		if (cssClassNames && cssClassNames.length > 0)
		{
			if (typeof(cssClassNames) == 'string')
			{
				classNames.push(cssClassNames);
			}
			else // Assume an array
			{
				classNames = classNames.concat(cssClassNames);
			}
		}
		
		this.currentOverlay = $('<div class="' + classNames.join(' ') + '">' + content + '</div>');
		$("#content").append(this.currentOverlay);
	},
	
	hide: function()
	{
		if (!this.currentOverlay) { return; }
		this.currentOverlay = null;
	},
	
	destroy: function()
	{
		if (!this.currentOverlay) { return; }
		this.currentOverlay.empty();
		this.currentOverlay.remove();
		this.currentOverlay = null;
	}
});
/**
 * JQUERY Initializer
 */
//jQuery(function($)
//{

/**
 * SINGLETON: PopupFactory, popups at wholesale prices
*/ 
jQuery.createSingleton('X.PopupFactory', function()
{
	this.popups = {};
},
{	
    init: function()
	{	
		$('.popup-opener').click(this._onClick);
	},
	
	_onClick: function(evt)
	{
		evt.preventDefault();
	    var data = $.evalJSON(this.rel);
	    if (!data.id) { data.id = this.id||this.name||''; }		
		X.PopupFactory.create(data);
	},
	
	create: function(data)
	{
	    // data.id is breaking the window.open in ie7 if non-word characters are not removed
	    data.id = (typeof(data.id) !== 'string' || data.id.length === 0)? 'popup' : data.id.replace(/\W/g, '');
		if (typeof(data.url) !== 'string' || data.url.length === 0) { data.url = 'about:blank'; }
		
		var popup = this.popups[data.id];
		if (popup && !popup.win.closed && popup.data.url === data.url)
		{
		    if (popup.win.focus) { popup.win.focus(); }
			return;
		}
		
		var win = $(window);
		
		// Normalize the props
		for (var prop in data)
		{
		    if (data[prop] === 'no' || data[prop] === false)
		    {
		        data[prop] = '0';
		    }
		    else if (data[prop] === 'yes' || data[prop] === true)
		    {
		        data[prop] = '1';
		    }
		}
		
		// Set props defaults
		data = $.extend(
		{
		    top: parseInt(((win.height() / 2) - (data.height / 4))),
		    left: parseInt(((win.width() / 2) - (data.width / 4))),
			width: 600,
			height: 480,
			scrollbars: '0',
			location: '0',
			toolbar: '0',
			menubar: '0',
			directories: '0',
			resizable: '0',
			status: '0'
		}, data);
		
		
		var props = [];
		props[props.length] = 'top=' + data.top;
		props[props.length] = 'left=' + data.left;
		props[props.length] = 'width=' + parseInt(data.width);
		props[props.length] = 'height=' + parseInt(data.height);
		props[props.length] = 'scrollbars=' + data.scrollbars;
		props[props.length] = 'location=' + data.location;
		props[props.length] = 'toolbar=' + data.toolbar;
		props[props.length] = 'menubar=' + data.menubar;
		props[props.length] = 'directories=' + data.directories;
		props[props.length] = 'resizable=' + data.resizable;
		props[props.length] = 'status=' + data.status;
		
		var popup = window.open(data.url, data.id, props.join(','));
		
		this.popups[data.id] = { win: popup, data: data };
		
		if (typeof(popup.focus) === 'function') { popup.focus(); }
	}
});

//});
/**
 * SINGLETON: TooltipFactory, tooltips at wholesale prices
 */
jQuery.createSingleton('X.TooltipFactory', function()
{
	this.pointerOffset = 10;
	
	this.currentTooltip = null;
	this.sticky = false;
	
	this.tooltips = {};
},
{
	init: function()
	{	
		$('.tooltip-click-opener').click(this._onClick);
		$('.tooltip-hover-opener,.tooltip-hover-click-opener').hover(this._onMouseOver, this._onMouseOut);
		$('.tooltip-hover-click-opener').click(this._onHoverClick);
		$('.tooltip-click-mouseout-opener').click(this._onClick).mouseout(this._onMouseOut);
		$('.attr02').hover(this._onHoverLoad, this._onMouseOut);
		
		$(document.body).mousemove(this._onMouseMove).click(this._onDocumentClick);		
	},
	
	_registerTooltip: function(elm)
	{
		var id = elm.attr('id');
		if (!id || this.tooltips[id]) { return; }
		
		//this._resizeTooltip(elm);
		
		this.tooltips[id] = elm;
	},
	
	_resizeTooltip: function(elm)
	{
		// Reset the width of the tooltip
		elm.css('width', 'auto');

		// Ensure that the tooltip is not wider than half of the viewport width
		var viewportW = ($(window).width()/2) - (this.pointerOffset*5);
		if (elm.outerWidth() >= viewportW)
		{
			elm.css('width', viewportW);
		}
	},
	
	_generateTooltip: function(id)
	{
	    var elm = $('#'+id).appendTo(document.body).bgiframe();
		X.TooltipFactory._registerTooltip(elm);
		return X.TooltipFactory.tooltips[id];
	},
	
	_onClick: function(evt)
	{
		evt.preventDefault();
		evt.stopPropagation();
		
		var id = this.name||this.rel||'';
		
		if (id.length === 0) { return; }
		
		var tooltip = X.TooltipFactory.tooltips[id];
		if (!tooltip)
		{
		    tooltip = X.TooltipFactory._generateTooltip(id);
		    if (!tooltip) { return; }
		}
		
		if (X.TooltipFactory.currentTooltip)
		{
			X.TooltipFactory.currentTooltip.hide();
		}
		X.TooltipFactory.currentTooltip = tooltip;
		X.TooltipFactory.show(evt);
	},
	_onHoverLoad: function(evt)
	{
	    evt.preventDefault();
		evt.stopPropagation();
		
		var id = this.name||this.rel||'';
		
		if (id.length === 0) { return; }
		
		var tooltip = X.TooltipFactory.tooltips[id];
		if (!tooltip)
		{
		    tooltip = X.TooltipFactory._generateTooltip(id);
		    if (!tooltip) { return; }
		}
		
		if (X.TooltipFactory.currentTooltip)
		{
			X.TooltipFactory.currentTooltip.hide();
		}
		
		var data = {};
		try
		{
		    data.dealerId = $.evalJSON(this.rel).dealerId;
		}
		catch (ex)
		{
		    return;
		}
		
		X.TooltipFactory.currentTooltip = tooltip;
		
		$('.jsonData').empty();
		
		X.TooltipFactory.show(evt);
		
		$('#loading-tooltip').fadeIn('fast');
		
		data.code = '02';
		
		//alert(configUrlTemplate(serviceUrls.precisionTeam, data.dealerId, data.code));
		
		X.JsonRequestManager.call('get-precision-team-data',
		{
			url: configUrlTemplate(serviceUrls.precisionTeam, data.dealerId, data.code),
			//cache: false,
			success: X.TooltipFactory.write.delegate(this),
			error: function(textStatus, msg) { alert(msg); }
		});
	},
	_onClickLoad: function(evt)
	{
		evt.preventDefault();
		evt.stopPropagation();
		
		var id = this.name||this.rel||'';
		
		if (id.length === 0) { return; }
		
		var tooltip = X.TooltipFactory.tooltips[id];
		if (!tooltip)
		{
		    tooltip = X.TooltipFactory._generateTooltip(id);
		    if (!tooltip) { return; }
		}
		
		if (X.TooltipFactory.currentTooltip)
		{
			X.TooltipFactory.currentTooltip.hide();
		}
		
		var data = {};
		try
		{
		    data.dealerId = $.evalJSON(this.rel).dealerId;
		}
		catch (ex)
		{
		    return;
		}
		
		X.TooltipFactory.currentTooltip = tooltip;
		
		$('.jsonData').empty();
		
		X.TooltipFactory.show(evt);
		
		$('#loading-tooltip').fadeIn('fast');
		
		data.code = '02';
		
		//alert(configUrlTemplate(serviceUrls.precisionTeam, data.dealerId, data.code));
		
		X.JsonRequestManager.call('get-precision-team-data',
		{
			url: configUrlTemplate(serviceUrls.precisionTeam, data.dealerId, data.code),
			//cache: false,
			success: X.TooltipFactory.write.delegate(this),
			error: function(textStatus, msg) { alert(msg); }
		});
	},
	_onHoverClick: function(evt)
	{
		evt.preventDefault();
		evt.stopPropagation();
		
		X.TooltipFactory.sticky = true;
	},
	_onMouseOver: function(evt)
	{
		var id = this.name||this.rel||'';
        	
		if (id.length === 0) { return; }
		
		var tooltip = X.TooltipFactory.tooltips[id];
		if (!tooltip)
		{
		    tooltip = X.TooltipFactory._generateTooltip(id);
		    if (!tooltip) { return; }
		}
				
		if (X.TooltipFactory.sticky) { return; }
		
		if (X.TooltipFactory.currentTooltip)
		{
			X.TooltipFactory.currentTooltip.hide();
		}
		X.TooltipFactory.currentTooltip = tooltip;
		X.TooltipFactory.show(evt);
	},
	_onMouseOut: function(evt)
	{
		var id = this.name||this.rel||'';
        	
		if (id.length === 0 || !X.TooltipFactory.tooltips[id]) { return; }
		
		if (X.TooltipFactory.sticky) { return; }
		
		X.TooltipFactory.hide();
	},
	_onMouseMove: function(evt)
	{
		if (!X.TooltipFactory.currentTooltip) { return; }
		if (X.TooltipFactory.sticky) { return; }
		X.TooltipFactory.currentTooltip.css(X.TooltipFactory._getCalculatedPosition(X.TooltipFactory.currentTooltip, evt));
	},
	_onDocumentClick: function(evt)
	{
		if (!X.TooltipFactory.currentTooltip) { return; }
		X.TooltipFactory.sticky = false;
		X.TooltipFactory.hide();
	},
	_getCalculatedPosition: function(elm, evt)
	{
		if (!elm || !evt) { return {}; }
		
		var win = $(window);
		var viewportW = win.width();
		var viewportH = win.height();
		var w = elm.outerWidth();
		var h = elm.outerHeight();
		var y = evt.pageY;
		var x = evt.pageX;
		var pos = { top: y, left: x };
		if ((x + w + this.pointerOffset) > viewportW)
		{
			pos.left -= (w + this.pointerOffset);
		}
		else
		{
			pos.left += this.pointerOffset;
		}
		if ((y + h) > viewportH)
		{
			pos.top -= h;
		}
		pos.left += 'px';
		pos.top += 'px';
		pos.display = 'block';
		
		return pos;
	},

	hide: function()
	{
		if (!this.currentTooltip) { return; }
		var tooltip = this.currentTooltip;
		this.currentTooltip = null;
		this.sticky = false;
		tooltip.fadeOut('fast');
	},
	
	show: function(evt)
	{
		if (!this.currentTooltip) { return; }
        $(".tooltip").hide();
		this._resizeTooltip(this.currentTooltip);
		this.currentTooltip.css(X.TooltipFactory._getCalculatedPosition(this.currentTooltip, evt)).show();
	},
	
	create: function(id, cssClassNames, content, evt)
	{
		// clean up any lingering tooltips
		this._hideAll();

		var tooltip;
		
		if (!this.tooltips[id])
		{
			var classNames = ['tooltip'];

			if (cssClassNames && cssClassNames.length > 0)
			{
				if (typeof(cssClassNames) == 'string')
				{
					classNames.push(cssClassNames);
				}
				else // Assume an array
				{
					classNames = classNames.concat(cssClassNames);
				}
			}
			
			$('<div id="' + id + '" class="' + classNames.join(' ') + '">' + content + '</div>').appendTo(document.body);
			
			tooltip = $('#'+id);
			
			this._registerTooltip(tooltip);
		}
		else
		{
			tooltip = this.tooltips[id];
		}
		
		if (this.currentTooltip)
		{
			this.currentTooltip.hide();
		}
		
		this.currentTooltip = tooltip;
				
		this.show(evt);
	},
	
	hideAll: function()
	{
	    this._hideAll();
	},
	
	_hideAll: function()
	{
	    var prop, tooltip;
	    for(prop in this.tooltips)
	    {
	        try{
	            tooltip = this.tooltips[prop];
	            if(tooltip.hide)
	            {
	                tooltip.hide();
	            }
	        } catch(err){}
	    }
	    this.currentTooltip = null;
	},
	
	destroy: function()
	{
		if (!this.currentTooltip) { return; }
		this.currentTooltip.empty();
		this.currentTooltip.remove();
		this.currentTooltip = null;
	},
	
	write: function(data)
	{		
		$('#tooltip-02-desc .jsonData').html(data.Description);
		$('#loading-tooltip').fadeOut('fast');
	}
	
	
});
jQuery.createSingleton('jQuery.validation.Messages', function()
{
	/*
	 * The following, site-wide error messages should have the following format:
	 * "[input-name + rule-id] || [rule-id]": "[error-message]"
	 * Some rules only generate one error message while others generate a message
	 * for each input that fails (Required)
	 */
	this.messages = {};
	this.messagesHash = {};
},
{
	registerMessages: function(messages)
	{
		this.messages = jQuery.extend(this.messages, messages);
		this.messagesHash = {};
		for (var prop in this.messages)
		{
			this.messagesHash[this.messages[prop]] = true;
		}
	},
	
	isMessage: function(val)
	{
		/*for (var prop in this.messages)
		{
			if (this.messages[prop] === val) { return true; }
		}
		return false;*/
		return this.messagesHash[val];
	}
});

/*
 * jQuery.validation.Rules
 * 
 * The validation rules object is a simple container for all registered rules objects for an application
 * 
 * For a rule to me made available jQuery.validation.Rules.add() must be called.
 * It is recommended that the constructor make the call to add().
 * 
 * By default the following rules are pre-loaded with default behavior:
 * RequiredCheck, will check an input for a value that is not equal to any default value
 * EmailCheck, will enforce a basic email format
 * ZipcodeCheck, will eforce a zip +5 US zipcode format
 * DateCheck, will check for a valid date string
 * NumberCheck, will check for a proper numerical value
 * PhoneNumberCheck, will enforce a us standard phone format
 */
jQuery.createSingleton('jQuery.validation.Rules', function()
{
	this.rules = {};
	this.ruleIds = [];
},
{
	add: function(rule)
	{
		this.ruleIds.push(rule.id);
		this.rules[rule.id] = rule;
	},
	get: function(id)
	{
		return this.rules[id];
	},
	getRuleIds: function()
	{
		return this.ruleIds;
	}
});

/*
 * jQuery.validation.Group
 * 
 * A validation group is a runtime collection of inputs that are to be validated as a group.
 * A group can either be a form, or a div/container within a form that will enclose the grouped
 * inputs.
 * 
 * A group needs the following configuration parameters:
 * 
 * settings.containerQuery		[required]	jQuery query which will return the container element to search for validation elements in
 * settings.triggerQuery		[required]	jQuery query which will return the element whose event-type (specified by the triggerEventType setting) triggers the validation
 * settings.triggerEventType	[optional]	Event type name to bind to the trigger. Default = 'click'
 * settings.triggerHandler		[optional]	Failure handler funciton
 * settings.failureHandler		[optional]	Failure handler funciton
 * settings.successHandler		[optional]	Success handler funciton
 */
jQuery.createClass('jQuery.validation.Group', function(settings)
{
	settings = jQuery.extend(
	{
		triggerEventType: 'click',
	    triggerHandler: this.defaultTriggerHandler,
		failureHandler: this.defaultFailureHandler,
		successHandler: this.defaultSuccessHandler
	}, settings);
	
	if (!settings.containerQuery) { throw new Error('jQuery.validation.Group(constructor):: settings.containerQuery is a required parameter.'); }
	if (!settings.triggerQuery) { throw new Error('jQuery.validation.Group(constructor):: settings.triggerQuery is a required parameter.'); }
	
	
	this.classNames = '.' + jQuery.validation.Rules.getRuleIds().join(',.');
	this.defaultValues = {};
	this.containerElm = jQuery(settings.containerQuery);
	
	this.elements = jQuery(jQuery.unique(jQuery(this.classNames, this.containerElm)));
	
	var ruleNamesHash = {};
	var ruleNames = [];
	this.elements.each(function(idx)
	{
		var classNames = (this.className || '').split(' ');
		for (var idx = 0, len = classNames.length, ruleName; idx < len; idx++)
		{
			ruleName = classNames[idx];
			if (!jQuery.validation.Rules.rules[ruleName]) { continue; }
			ruleNamesHash[ruleName] = 1;
		}
		// If the text is an error message, reset the value on focus
		if (this.tagName.toLowerCase() === 'textarea' || this.type === 'text' || this.type === 'file')
		{
			jQuery(this).focus(function(evt) { if (this.value.length > 0 && jQuery.validation.Messages.isMessage(this.value)) { this._value = this.value; this.value = ''; } })
		}
	});
	this.ruleNames = [];
	for (var prop in ruleNamesHash)
	{
		this.ruleNames.push(prop);
	}
	
	this.triggerElm = jQuery(settings.triggerQuery);
	
	this.triggerHandler = settings.triggerHandler;
	this.failureHandler = settings.failureHandler;
	this.successHandler = settings.successHandler;
	
	// set up triggers
	this.triggerElm.bind(settings.triggerEventType, this.onTrigger.delegate(this));
	
	var theGroup = this;
	$(':text', this.containerElm).keydown(function(evt)
	{
	    if (evt.keyCode == 13)
        {
            evt.preventDefault();
            evt.stopPropagation();
            theGroup._onTrigger(theGroup);
        }
    });
},
{
    defaultTriggerHandler: function(result)
	{
	    $('.err-container').removeClass('err-container');
		$('.err-field').removeClass('err-field');
		$('.err-message').remove();
	},
	
	defaultFailureHandler: function(result)
	{
		var namesHash = {};
		$('#divError').hide();
		result.container.containerElm.addClass('err-container');
		$('.legend:first', result.container.containerElm).after('<div class="err-message">There was a problem submitting your request</div>');
		
		for (var idx = 0, len = result.errors.length, err, srcElm, name; idx < len; idx++)
		{
			err = result.errors[idx];
			srcElm = err.srcElement.get(0);
			
			name = srcElm.name;
			if (namesHash[name]) { continue; }
			namesHash[name] = true;
			
			err.srcElement.parent().addClass('err-field');
		}
	},
	
	defaultSuccessHandler: function(result)
	{
	    var foundForm = false;
	    var tagName;
		var elm = result.container.containerElm;
		// If the container is not a form
		if (elm.get(0).tagName.toLowerCase() !== 'form')
		{
		    // Check the children for a form
		    elm = elm.find('form:first');
		    if (elm.length === 0)
		    {
		        elm = elm.parents('form:first');
		    }
		    // No form? Check the parents for a form
		    if (elm.length === 0)
		    {
		        //alert('no form');
		        return;
		    }
		}
		elm.submit();
	},
	
	validate: function()
	{
		var result = { success:true };
		var errors = [];
		var rule = null;
		
		for (var idx = 0, len = this.ruleNames.length; idx < len; idx++)
		{
			// for each rule
			rule = jQuery.validation.Rules.get(this.ruleNames[idx]);
			rule.evaluate(this, errors);
		};
		if (errors.length > 0)
		{
			result.success = false;
			result.errors = errors;
		}
		
		return result;
	},
	
	onTrigger: function(evt)
	{
		evt.preventDefault();
		this._onTrigger();
	},
	
	_onTrigger: function()
	{
		this.triggerHandler({ container: this });
		
		var result = this.validate();
		if (result.success)
		{
			this.successHandler({ container: this });
		}
		else
		{
			this.failureHandler({ container: this, errors: result.errors });
		}
	}
});

// ------------------------------------------------------------------------------------------------------------------------------
// Standard Rules Library
// ------------------------------------------------------------------------------------------------------------------------------

/*
 * ABSTRACT CLASS: jQuery.validation.Rule
 * 
 * A validation rule is a .
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.pattern		[optional]	A pattern to be matched. Default = null
 */
jQuery.createClass('jQuery.validation.rule.Rule', function(id, settings)
{
	this.id = id;
	this.settings = jQuery.extend({ pattern:null }, settings);
	if (this.settings.pattern && this.settings.pattern.constructor === RegExp)
	{
		var attributes = '';
		if (this.settings.pattern.global) { attributes += 'g'; }
		if (this.settings.pattern.ignoreCase) { attributes += 'i'; }
		this.settings.pattern.compile(this.settings.pattern.source, attributes);
	}
	jQuery.validation.Rules.add(this);
},
{
	evaluate: function(val)
	{
		if (!this.settings.pattern) { return true; }
		var returnVal = this.settings.pattern.test(val);
		this.settings.pattern.lastIndex = 0;
		return returnVal;
	}
});
jQuery.ns('jQuery.validation.rule.create', function(ruleClassName, id, settings)
{
	if (typeof(jQuery.validation.rule[ruleClassName]) !== 'function')
	{
		throw new Error('jQuery.validation.rule.create:: No Rule with the name "' + ruleClassName + '" exists.');
	}
	return new jQuery.validation.rule[ruleClassName](id, settings);
});

/*
 * SINGLETON: jQuery.validation.rule.RequiredCheck
 * 
 * A RequiredCheck validation rule checks the fields value.
 */
jQuery.createSingleton('jQuery.validation.rule.RequiredCheck', function()
{
	this.base('required');
},
{
	evaluate: function(container, errors)
	{
		var id = this.id;
		try
		{
			// Handle text types inputs and select lists
			jQuery('.required:text,.required:password,.required:hidden,.required:file,select.required,textarea.required', container.containerElm).each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = jQuery.trim(srcEle.val());
				var defaultVal = container.defaultValues[this.name];
				if (val === null || val === '' || val === defaultVal)
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });
				}
			});
			
			// Handle radio button and checkbox groups
			var selections = {};
			jQuery('.required:radio,.required:checkbox', container.containerElm).each(function(idx)
			{
				var selection = selections[this.name];
				if (typeof(selection) === 'undefined')
				{
					selections[this.name] = { selected: this.checked };
				}
				if (selections[this.name].selected) { return true; }
				selections[this.name].selected = this.checked;
			});
			for (selection in selections)
			{
				if (selections[selection].selected) { continue; }
				
				var srcEle = jQuery('.required[name=\'' + selection + '\']', container.containerElm);
				errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[selection + '-' + id] });
			}
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.RequiredCheck.evaluate::' +
				' There was an issue while validating a required check,' +
				' please verify that you are only' + 
				' using the required class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.NumberCheck
 * 
 * A NumberCheck validation rule checks the value to see if it is a valid number
 */
jQuery.createSingleton('jQuery.validation.rule.NumberCheck', function()
{
	this.base('val-number');
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = jQuery.trim(srcEle.val());				
				
				if (!/^[0-9\.\,]+[\,\.]?$/.test(val))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.NumberCheck.evaluate::' +
				' There was an issue while validating a number check,' +
				' please verify that you are only' + 
				' using the number class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.IntegerCheck
 * 
 * A IntegerCheck validation rule checks the value to see if it is a valid Integer
 */
jQuery.createSingleton('jQuery.validation.rule.IntegerCheck', function()
{
	this.base('val-integer');
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = jQuery.trim(srcEle.val());				
				
				if (!/^[0-9\,]+[\,]?$/.test(val))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.NumberCheck.evaluate::' +
				' There was an issue while validating a number check,' +
				' please verify that you are only' + 
				' using the number class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.CurrencyCheck
 * 
 * A CurrencyCheck validation rule checks the value to see if it is a valid currency format
 */
jQuery.createSingleton('jQuery.validation.rule.NumberCheck', function()
{
	this.base('val-currency');
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = jQuery.trim(srcEle.val());				
				
				if (!/^[0-9\.\,\$]+[\,\.]?$/.test(val))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.CurrencyCheck.evaluate::' +
				' There was an issue while validating a currency check,' +
				' please verify that you are only' + 
				' using the number class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.TextArea
 * 
 * A TextArea validation rule allows commonly used characters.
 */
 
jQuery.createSingleton('jQuery.validation.rule.TextAreaCheck', function()
{
	this.base('val-textarea', { pattern: /^([\"\(\)\@\!\$\%\+\=\;\:\?\*\'\#\&\.\,\/\\\sa-zA-Z0-9_-]+)$/ });
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var eleVal = jQuery.trim(srcEle.val());
				var defaultVal = container.defaultValues[this.name];
				if ((!defaultVal || eleVal !== defaultVal) && !scope.base.evaluate(eleVal))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.TextAreaCheck.evaluate::' +
				' There was an issue while validating a textarea check.' +
				' Please verify that you are only using the textarea class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.DateCheck
 * 
 * A DateCheck validation rule checks the value to see if it is a valid date
 */
jQuery.createSingleton('jQuery.validation.rule.DateCheck', function()
{
	this.base('val-date');
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				if (isNaN(new Date(jQuery.trim(srcEle.val()))))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.DateCheck.evaluate::' +
				'There was an issue while validating a date check,' +
				' please verify that you are only' + 
				' using the email class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.EmailCheck
 * 
 * A EmailCheck validation rule checks the value to see if it is a valid email address
 */
jQuery.createSingleton('jQuery.validation.rule.EmailCheck', function()
{
	this.base('val-email', { pattern: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i }); // RFC 2822
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var eleVal = jQuery.trim(srcEle.val());
				var defaultVal = container.defaultValues[this.name];
				if ((!defaultVal || eleVal !== defaultVal) && !scope.base.evaluate(eleVal))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.EmailCheck.evaluate::' +
				' There was an issue while validating a email check.' +
				' Please verify that you are only using the email class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.AlphaNumeric
 * 
 * A AlphaNumeric validation rule checks the value to see if it contains only alphanumeric characters including - and _
 */
 
jQuery.createSingleton('jQuery.validation.rule.AlphaNumeric', function()
{
	this.base('val-alphanum', { pattern: /^([\'\#\.\,\sa-zA-Z0-9_-]+)$/ });
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var eleVal = jQuery.trim(srcEle.val());
				var defaultVal = container.defaultValues[this.name];
				if ((!defaultVal || eleVal !== defaultVal) && !scope.base.evaluate(eleVal))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.AlphaNumeric.evaluate::' +
				' There was an issue while validating an alphanumeric check.' +
				' Please verify that you are only using the alphanumeric class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);


/*
 * SINGLETON: jQuery.validation.rule.ZipcodeCheck
 * 
 * A ZipcodeCheck validation rule checks the value to see if it is a valid zip code
 */
jQuery.createSingleton('jQuery.validation.rule.ZipcodeCheck', function()
{
	this.base('val-zipcode', { pattern: /^\d{5}(-\d{4})?$/ });
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var eleVal = jQuery.trim(srcEle.val());
				if (!scope.base.evaluate(eleVal))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.ZipcodeCheck.evaluate::' +
				' There was an issue while validating a zipcode check.' +
				' Please verify that you are only using the email class on valid inputs.' + 
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * SINGLETON: jQuery.validation.rule.PhoneNumberCheck
 * 
 * A PhoneNumberCheck validation rule checks the value to see if it is a valid phone number
 */
jQuery.createSingleton('jQuery.validation.rule.PhoneNumberCheck', function()
{
	this.base('val-phone-number', { pattern: /^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$/ });
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				if (!scope.base.evaluate.test(jQuery.trim(srcEle.val())))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.PhoneNumberCheck.evaluate::' +
				'There was an issue while validating a phone number check.' +
				' Please verify that you are only using the phone-number class on valid inputs.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.LessThanCheck
 * 
 * A LessThanCheck validation rule checks the fields value against a maximum allowed value.
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.max		[optional]	The maximum numeric value. Default = 1
 */
jQuery.createClass('jQuery.validation.rule.LessThanCheck', function(id, settings)
{
	this.base(id, jQuery.extend({ max: 1 }, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = parseInt(jQuery.trim(srcEle.val()));
				if (isNaN(val) || val >= scope.settings.max)
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.LessThanCheck.evaluate::' +
				' There was an issue while validating a less-than check,' +
				' please verify your input.' +
				' The options object looks like this { max: max-value }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.GreaterThanCheck
 * 
 * A GreaterThanCheck validation rule checks the fields value against a minimum allowed value.
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.min		[optional]	The minimum numeric value. Default = 1
 */
jQuery.createClass('jQuery.validation.rule.GreaterThanCheck', function(id, settings)
{
	this.base(id, jQuery.extend({ min: 1 }, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = parseInt(jQuery.trim(srcEle.val()));
				if (isNaN(val) || val <= scope.settings.min)
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[id] });
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.GreaterThanCheck.evaluate::' +
				' There was an issue while validating a less-than check,' +
				' please verify your input.' +
				' The options object looks like this { min: min-value }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.BetweenCheck
 * 
 * A BetweenCheck validation rule checks the fields value against a minimum and maximum allowed value.
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.min		[optional]	The minimum numeric value. Default = 1
 * settings.max		[optional]	The maximum numeric value. Default = 1
 */
jQuery.createClass('jQuery.validation.rule.BetweenCheck', function(id, settings)
{
	this.base(id, jQuery.extend({ min: 1, max: 1 }, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + this.id + '[value!=\'\']', container.containerElm);
		var id = this.id;
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = parseFloat(srcEle.val().replace(/(\$|\,)/g,''));
				
				if (isNaN(val) || val < scope.settings.min || val > scope.settings.max)
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[id] });
				}
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.BetweenCheck.evaluate::' +
				' There was an issue while validating a between check, please verify your input.' +
				' The options object looks like this { min: min-value, max: max-value }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.MultiSelectCheck
 * 
 * A MultiSelectCheck validation rule checks if there is a number of inputs selected between the supplied minimum and maximum
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.min		[optional]	The minimum number of elements which must be checked/selected. Default = 1
 * settings.max		[optional]	The maximum number of elements which must be checked/selected. Default = 1
 */
jQuery.createClass('jQuery.validation.rule.MultiSelectCheck', function(id, settings)
{
	this.base(id||'val-multi-check', jQuery.extend({ min: 1, max: 1 }, settings));
},
{
	evaluate: function(container, errors)
	{
		var id = this.id;
		try 
		{
			var selected = jQuery('.' + this.id + ':selected,.' + this.id + ':checked', container.containerElm);
			
			if (selected.length > this.settings.max || selected.length < this.settings.min)
			{
				var srcElements = jQuery('.' + this.id, container.containerElm);
				errors.push({ id: id, srcElement: srcElements, message: jQuery.validation.Messages.messages[id] });
			}
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.MultiSelectCheck.evaluate::' +
				' There was an issue while validating a multi-select check, please verify your input.' +
				' The options object looks like this { min: min-selected-count, max: max-selected-count }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.OneOfCheck
 * 
 * A OneOfCheck validation rule checks if the value is one of the values supplied in the settings.includes parameter
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.includes	[required]	An array of values to check against
 */
jQuery.createClass('jQuery.validation.rule.OneOfCheck', function(id, settings)
{
	settings = jQuery.extend({ includes: [] }, settings);
	if (settings.includes.length < 1)
	{
		throw new Error('jQuery.validation.rule.OneOfCheck(constructor):: includes is a required setting');
	}
	settings = jQuery.extend({ pattern: new RegExp('^(' + settings.includes.join('|') + ')$', 'm') });
	
	this.base(id, settings);
},
{
	evaluate: function(container, errors)
	{
		var id = this.id;
		var elm = jQuery('.' + id, container.containerElm);
		var val = elm.val();
		if (val === null)
		{
			return;
		}
		
		try 
		{
			if (typeof(val) === 'string')
			{
				val = jQuery.trim(val);
				if (!this.base.evaluate(val))
				{
					errors.push({ id: id, srcElement: elm, message: jQuery.validation.Messages.messages[id] });
				}
				return errors;
			}
			else if (val.constructor === Array)
			{
				for (var idx = 0, len = val.length, _val; idx < len; idx++)
				{
					_val = jQuery.trim(val[idx]);
					if (!this.base.evaluate(_val))
					{
						errors.push({ id: id, srcElement: elm, message: jQuery.validation.Messages.messages[id] });
						break;
					}
				}
				return errors;
			}
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.OneOfCheck.evaluate::' +
				' There was an issue while validating a one-of check, please verify your input.' +
				' The options object looks like this { includes: [\'valid-value\', \'valid-value\'] }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.NotOneOfCheck
 * 
 * A NotOneOfCheck validation rule checks if the value is not one of the values supplied in the settings.excludes parameter
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.excludes	[required]	An array of values to check against
 */
jQuery.createClass('jQuery.validation.rule.NotOneOfCheck', function(id, settings)
{
	settings = jQuery.extend({ excludes: [] }, settings);
	if (settings.excludes.length < 1)
	{
		throw new Error('jQuery.validation.rule.NotOneOfCheck(constructor):: excludes is a required setting');
	}
	settings = jQuery.extend({ pattern: new RegExp('^(' + settings.excludes.join('|') + ')$', 'm') });
	
	this.base(id, settings);
},
{
	evaluate: function(container, errors)
	{
		var id = this.id;
		var elm = jQuery('.' + id, container.containerElm);
		var val = elm.val();
		if (val === null)
		{
			return;
		}
		
		try 
		{
			if (typeof(val) === 'string')
			{
				val = jQuery.trim(val);
				if (this.base.evaluate(val))
				{
					errors.push({ id: id, srcElement: elm, message: jQuery.validation.Messages.messages[id] });
				}
				return errors;
			}
			else if (val.constructor === Array)
			{
				for (var idx = 0, len = val.length, _val; idx < len; idx++)
				{
					_val = jQuery.trim(val[idx]);
					if (this.base.evaluate(_val))
					{
						errors.push({ id: id, srcElement: elm, message: jQuery.validation.Messages.messages[id] });
						break;
					}
				}
				return errors;
			}
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.NotOneOfCheck.evaluate::' +
				' There was an issue while validating a one-of check, please verify your input.' +
				' The options object looks like this { includes: [\'valid-value\', \'valid-value\'] }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.CharCountCheck
 * 
 * A CharCountCheck validation rule checks the number of characters against the specified min and max parameters
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.min		[optional]	The minimum number of characters to check for. 0 = no minimum. Default = 0
 * settings.max		[optional]	The maximum number of characters to check for. 0 = no maximum. Default = 0
 */
jQuery.createClass('jQuery.validation.rule.CharCountCheck', function(id, settings)
{
	this.base(id||'val-char-count', jQuery.extend({ min: 0, max: 0 }, settings));
},
{
	evaluate: function(container, errors)
	{
		var id = this.id;
		var scope = this;
		
		var elms = jQuery('.' + id + '[value!=\'\']', container.containerElm);
		try 
		{
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				var val = jQuery.trim(srcEle.val());
				
				if ((scope.settings.min < 1 || val.length < scope.settings.min) || (scope.settings.max < 1 || val.length > scope.settings.max))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.CharCountCheck.evaluate::' +
				' There was an issue while validating a char count check, please verify your input.' +
				' The options object looks like this { min: min-value, max: max-value }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.SameAsCheck
 * 
 * A SameAsCheck validation rule compares the field's value against the value of the specified field
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.compareToQuery	[required]	The jQuery selector that will be used to get the element to campare the value against
 */
jQuery.createClass('jQuery.validation.rule.SameAsCheck', function(id, settings)
{
	this.base(id||'val-same-as', jQuery.extend({ compareToQuery: '' }, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var elms = jQuery('.' + scope.id, container.containerElm);
		var id = this.id;
		try 
		{
			var targetEle = jQuery(scope.settings.compareToQuery, container.containerElm);
			elms.each(function(idx)
			{
				var srcEle = jQuery(this);
				if (jQuery.trim(srcEle.val()) !== jQuery.trim(targetEle.val()))
				{
					errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[this.name + '-' + id] });		
				}	
			});
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.SameAsCheck.evaluate::' +
				' There was an issue while validating a same as check, please verify your input.' +
				' The options object looks like this { compareTo: compareToElm }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.PhoneCheck
 * 
 * A PhoneCheck validation rule checks the combined values of the phone fields
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.fieldsQuery	[required]	The jQuery selector that will be used to get the elements
 */
jQuery.createClass('jQuery.validation.rule.PhoneCheck', function(id, settings)
{
	this.base(id||'val-phone', jQuery.extend({ fieldsQuery: '', pattern: /^[2-9]\d{2}-\d{3}-\d{4}$/ }, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var id = this.id;
		try 
		{
			var val = [], _val;
			var srcEle = jQuery(scope.settings.fieldsQuery, container.containerElm);
			var name = srcEle.attr('name');
			srcEle.each(function(idx)
			{
				_val = jQuery.trim(jQuery(this).val());
				if (_val.length === 0) { return true; }
				val.push(_val);
			});
			if (val.length === 0) { return; }
			if (!this.base.evaluate(val.join('-')))
			{
				errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[name + '-' + id] });		
			}
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.PhoneCheck.evaluate::' +
				' There was an issue while validating a same as check, please verify your input.' +
				' The options object looks like this { fieldsQuery: fieldsQuery }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/*
 * CLASS: jQuery.validation.rule.ConditionallyRequired
 * 
 * A ConditionallyRequired validation rule checks the value of another input or inputs.  Then based on the configured value
 * for the andOr property, will trigger a required check on the rule's input.
 * 
 * A rule has the following configuration parameters:
 * 
 * settings.inputs	[required]	The jQuery selector that will select the input to check, if the input has a value, then the input
 * associated with this rule will become required
 * settings.andOr [required, default "and")] If the value is "and", all elements returned by the inputs array must have a vlaue, if
 * the value is "or" then any of the elements need to have a value to trigger the required check on the input. 
 */
jQuery.createClass('jQuery.validation.rule.ConditionallyRequired', function(id, settings)
{
	this.base(id||'val-conditionally-required', jQuery.extend({ andOr: 'and'}, settings));
},
{
	evaluate: function(container, errors)
	{
		var scope = this;
		var id = this.id;
		try 
		{
			var val = [], _val;
			var req = true;
			var srcElms = jQuery(scope.settings.inputs, container.containerElm);
			var len = srcElms.length;
		    if(len == 0) { throw new Error("Found no inputs from selector - " + scope.settings.inputs); }
			srcElms.each(function(idx){
				_val = jQuery.trim($(this).val());
				var defaultVal = container.defaultValues[this.name];
				if (_val === null || _val === '' || _val === defaultVal)
				{
				    if(scope.settings.andOr === "and" || idx === (len-1))
				    {
				        req = false;
				        return false;
				    }
				} 
				else 
				{
				    if(scope.settings.andOr === "or")
				    {
				        return false;
				    }
				}
			});
			var srcEle = jQuery('.' + scope.id, container.containerElm);
			var name = srcEle.attr('name');
			if(req)
			{
				val = jQuery.trim(srcEle.val());
				var defaultVal = container.defaultValues[name];
				if (val === null || val === '' || val === defaultVal)
				{
				    errors.push({ id: id, srcElement: srcEle, message: jQuery.validation.Messages.messages[name + '-' + id] });	
				} 
			}
			
			return errors;
		} 
		catch (err) 
		{
			throw new Error('jQuery.validation.rule.ConditionallyRequired.evaluate::' +
				' There was an issue while validating a same as check, please verify your input.' +
				' The options object looks like this { inputs: [], andOr: ("and", "or") }.' +
				' Reason: ' + err.message);
		}
	}
}, jQuery.validation.rule.Rule);

/**
 * CLASS: JsonRequest
 */
jQuery.createClass('X.JsonRequest', function(id, xhr, options)
{
	this.id = id;
	this.xhr = xhr;
	this.options = options;
	this.aborted = false;
	
	return;
});

/**
 * CLASS: JsonEvent
 */
jQuery.createClass('X.JsonRequestEvent', function(type, textStatus, request)
{
	this.base(type);
	this.textStatus = textStatus;
	this.request = request;
	return this;
}, null, jQuery.Event);

/**
 * SINGLETON: JsonRequestManager
 */
jQuery.createSingleton('X.JsonRequestManager', function()
{
	this.requests = {};
	this.cache = {};
},
{
	/*
	 * options.url
	 * options.cache
	 * options.abort
	 * options.success
	 * options.error
	 * options.timeout
	 */
	call: function(id, options)
	{
		if (!options || !options.url)
		{
			throw new Error('Missing or invalid options parameter.');
		}
		
		// Set defaults
		options = jQuery.extend(
		{
			cache: true,
			abort: true,
			success: function(data, textStatus) {},
			error: function(xhr, textStatus, ex) {},
			timeout: 20000 //ms
		}, options);
		
		//var request = this.requests[id];
		
		//alert(this.requests[id]);
		
		// If data is already return cached data
		if (options.cache && this.cache[options.url])
		{
		    options.success(this.cache[options.url]);
			return;
		}
		
		if (options.abort)
		{
			this.abort(id);
		}
		
		if (!this.requests[id])
		{
			this.requests[id] = {};
		}
$.console.log('X.JsonRequestManager - making ajax request', id);
		this.requests[id][options.url] = new X.JsonRequest(
			id,
			jQuery.ajax(
			{
				success: this._onSuccessHandler.proxy(this, id, options.url),
				error: this._onErrorHandler.proxy(this, id, options.url),
				cache: options.cache,
				dataType: 'text',
				url: options.url,
				timeout: options.timeout
			}),
			options
		);
		
		return this;
	},
	
	abort: function(id)
	{
		var requests = this.requests[id];
		if (!requests) { return; }
		
		var request;
		for (var url in requests)
		{
			request = requests[url];
			if (!request.aborted) { break; }
		}
		if (!request) { return; }
		
		request.aborted = true;
		
		try
		{
			var success = false;
			if (typeof(request.xhr.abort) === 'function')
			{
				request.xhr.abort();
				success = true;
			}
			if (typeof(request.xhr.close) === 'function')
			{
				request.xhr.close();
				success = true;
			}
			
			var textStatus = (success)? 'success' : 'failed';
			this.dispatchEvent(new X.JsonRequestEvent('abort', textStatus, request));
		}
		catch (ex)
		{
			
		}
		
		return this;
	},
	
	abortAll: function()
	{
		for (var id in this.requests)
		{
			this.abort(id);
		}
		
		return this;
	},
	
	_onSuccessHandler: function(data, textStatus, id, url)
	{
$.console.log('X.JsonRequestManager - response received', id);
		var request = this.requests[id][url];
$.console.deleteLinkedLog(id);

$.console.log('X.JsonRequestManager - evaluating data begin', id);      
       
       eval("data = " + data);
        
$.console.log('X.JsonRequestManager - evaluating data end', id);
$.console.deleteLinkedLog(id);
	
		// Cache the result
		if (request.options.cache)
		{
			this.cache[request.options.url] = data || {};
		}
		
		request.options.success(data);
	},
	
	_onErrorHandler: function(xhr, textStatus, ex, id, url)
	{
$.console.log('X.JsonRequestManager - error received', id);
$.console.deleteLinkedLog(id);
		var request = this.requests[id][url];
		
		if (request.aborted) { return; }
		
		var msg = (ex)? ex.message : (textStatus === 'timeout')? 'Timeout! The server is experiencing slower than normal response times.' : 'Unknown Error';
		
		request.options.error(textStatus, msg);
	}
},
jQuery.EventDispatcher);
/* Copyright (c) 2006 Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * See http://kelvinluck.com/assets/jquery/jScrollPane/
 * $Id: jScrollPane.js 19 2008-11-13 06:00:09Z kelvin.luck $
 */

/**
 * Replace the vertical scroll bars on any matched elements with a fancy
 * styleable (via CSS) version. With JS disabled the elements will
 * gracefully degrade to the browsers own implementation of overflow:auto.
 * If the mousewheel plugin has been included on the page then the scrollable areas will also
 * respond to the mouse wheel.
 *
 * @example jQuery(".scroll-pane").jScrollPane();
 *
 * @name jScrollPane
 * @type jQuery
 * @param Object	settings	hash with options, described below.
 *								scrollbarWidth	-	The width of the generated scrollbar in pixels
 *								scrollbarMargin	-	The amount of space to leave on the side of the scrollbar in pixels
 *								wheelSpeed		-	The speed the pane will scroll in response to the mouse wheel in pixels
 *								showArrows		-	Whether to display arrows for the user to scroll with
 *								arrowSize		-	The height of the arrow buttons if showArrows=true
 *								animateTo		-	Whether to animate when calling scrollTo and scrollBy
 *								dragMinHeight	-	The minimum height to allow the drag bar to be
 *								dragMaxHeight	-	The maximum height to allow the drag bar to be
 *								animateInterval	-	The interval in milliseconds to update an animating scrollPane (default 100)
 *								animateStep		-	The amount to divide the remaining scroll distance by when animating (default 3)
 *								maintainPosition-	Whether you want the contents of the scroll pane to maintain it's position when you re-initialise it - so it doesn't scroll as you add more content (default true)
 *								scrollbarOnLeft	-	Display the scrollbar on the left side?  (needs stylesheet changes, see examples.html)
 *								reinitialiseOnImageLoad - Whether the jScrollPane should automatically re-initialise itself when any contained images are loaded
 * @return jQuery
 * @cat Plugins/jScrollPane
 * @author Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 */
jQuery.jScrollPane = {
	active : []
};
jQuery.fn.jScrollPane = function(settings)
{
	settings = jQuery.extend({}, jQuery.fn.jScrollPane.defaults, settings);

	var rf = function() { return false; };
	
	return this.each(
		function()
		{
			var $this = jQuery(this);
			// Switch the element's overflow to hidden to ensure we get the size of the element without the scrollbars [http://plugins.jquery.com/node/1208]
			$this.css('overflow', 'hidden');
			var paneEle = this;
			
			if (jQuery(this).parent().is('.jScrollPaneContainer')) {
				var currentScrollPosition = settings.maintainPosition ? $this.offset({relativeTo:jQuery(this).parent()[0]}).top : 0;
				var $c = jQuery(this).parent();
				var paneWidth = $c.innerWidth();
				var paneHeight = $c.outerHeight();
				var trackHeight = paneHeight;
				jQuery('>.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown', $c).remove();
				$this.css({'top':0});
			} else {
				var currentScrollPosition = 0;
				this.originalPadding = $this.css('paddingTop') + ' ' + $this.css('paddingRight') + ' ' + $this.css('paddingBottom') + ' ' + $this.css('paddingLeft');
				this.originalSidePaddingTotal = (parseInt($this.css('paddingLeft')) || 0) + (parseInt($this.css('paddingRight')) || 0);
				var paneWidth = $this.innerWidth();
				var paneHeight = $this.innerHeight();
				var trackHeight = paneHeight;
				$this.wrap(jQuery('<div class="jScrollPaneContainer" style="width:' + paneWidth + 'px;height:' + paneHeight + 'px;"></div>'));	
			}

			var p = this.originalSidePaddingTotal;
			if (paneWidth < (settings.scrollbarWidth + settings.scrollbarMargin + p))
			{
			    paneWidth = (settings.scrollbarWidth + settings.scrollbarMargin + p);
			}
			var cssToApply = {
				'height':'auto',
				'width':paneWidth - settings.scrollbarWidth - settings.scrollbarMargin - p + 'px'
			}

			if(settings.scrollbarOnLeft) {
				cssToApply.paddingLeft = settings.scrollbarMargin + settings.scrollbarWidth + 'px';
			} else {
				cssToApply.paddingRight = settings.scrollbarMargin + 'px';
			}

			$this.css(cssToApply);

			var contentHeight = $this.outerHeight();
			var percentInView = paneHeight / contentHeight;

			if (percentInView < .99)
			{
				var $container = $this.parent();
				
				var html = [];
				html[html.length] = '<div class="jScrollPaneTrack" style="width:' + settings.scrollbarWidth + 'px;">';
				html[html.length] = '   <div class="jScrollPaneDrag" style="width:' + settings.scrollbarWidth + 'px;">';
				html[html.length] = '       <div class="jScrollPaneDragTop" style="width:' + settings.scrollbarWidth + 'px"></div>';
				html[html.length] = '       <div class="jScrollPaneDragBottom" style="width:' + settings.scrollbarWidth + 'px"></div>';
				html[html.length] = '   </div>';
				html[html.length] = '</div>';
				$container.append(html.join(''));
				
				var $track = jQuery('>.jScrollPaneTrack', $container);
				var $drag = jQuery('.jScrollPaneDrag', $track);
				
				if (settings.showArrows)
				{	
					var currentArrowButton;
					var currentArrowDirection;
					var currentArrowInterval;
					var currentArrowInc;
					var whileArrowButtonDown = function()
					{
						if (currentArrowInc > 4 || currentArrowInc%4==0)
						{
							positionDrag(dragPosition + currentArrowDirection * mouseWheelMultiplier);
						}
						currentArrowInc ++;
					};
					var onArrowMouseUp = function(event)
					{
						jQuery('html').unbind('mouseup', onArrowMouseUp);
						if (this.className === 'jScrollArrowDown')
						{
						    currentArrowButton.removeClass('jScrollActiveArrowDownButton');
						}
						else
						{
						    currentArrowButton.removeClass('jScrollActiveArrowUpButton');
						}
						clearInterval(currentArrowInterval);
						//console.log($(event.target));
						//currentArrowButton.parent().removeClass('jScrollArrowUpClicked jScrollArrowDownClicked');
					};
					var onArrowMouseDown = function()
					{
						//console.log(direction);
						//currentArrowButton = $(this);
						jQuery('html').bind('mouseup', onArrowMouseUp);
						
						if (this.className === 'jScrollActiveArrowDown')
						{
						    currentArrowButton.addClass('jScrollActiveArrowDownButton');
						}
						else
						{
						    currentArrowButton.addClass('jScrollActiveArrowUpButton');
						}
						currentArrowInc = 0;
						whileArrowButtonDown();
						currentArrowInterval = setInterval(whileArrowButtonDown, 100);
					};
					
					var $upArrow, $downArrow;
					$container.append(
					    $upArrow = (
					        jQuery('<a href="#" class="jScrollArrowUp" style="width:' + settings.scrollbarWidth + 'px;">Scroll up</a>')
					            .bind('mousedown', function(evt)
							    {
							        evt.preventDefault();
								    currentArrowButton = jQuery(this);
								    currentArrowDirection = -1;
								    onArrowMouseDown();
								    this.blur();
							    })
							    .bind('click', rf)
							    .appendTo($container)
					    ),
					    $downArrow = (
					        jQuery('<a href="#" class="jScrollArrowDown" style="width:' + settings.scrollbarWidth + 'px;">Scroll down</a>')
					            .bind('mousedown', function(evt)
							    {
							        evt.preventDefault();
								    currentArrowButton = jQuery(this);
								    currentArrowDirection = 1;
								    onArrowMouseDown();
								    this.blur();
							    })
							    .bind('click', rf)
							    .appendTo($container)
					    )
					);
					    
					if (settings.arrowSize)
					{
						trackHeight = paneHeight - settings.arrowSize - settings.arrowSize;
						$track.css({'height': trackHeight+'px', top:settings.arrowSize+'px'})
					}
					else
					{
						var topArrowHeight = $upArrow.height();
						settings.arrowSize = topArrowHeight;
						trackHeight = paneHeight - topArrowHeight - $downArrow.height();
						$track.css({'height': trackHeight+'px', top:topArrowHeight+'px'})
					}
				}
				
				var $pane = jQuery(this).css({'position':'absolute', 'overflow':'visible'});
				
				var currentOffset;
				var maxY;
				var mouseWheelMultiplier;
				// store this in a seperate variable so we can keep track more accurately than just updating the css property..
				var dragPosition = 0;
				var dragMiddle = percentInView*paneHeight/2;
				
				// pos function borrowed from tooltip plugin and adapted...
				var getPos = function (evt, c)
				{
					var p = c == 'X' ? 'Left' : 'Top';
					return evt['page' + c] || (evt['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;
				};
				
				var ignoreNativeDrag = function() {	return false; };
				
				var initDrag = function()
				{
					ceaseAnimation();
					currentOffset = $drag.offset(false);
					currentOffset.top -= dragPosition;
					maxY = trackHeight - $drag[0].offsetHeight;
					mouseWheelMultiplier = 2 * settings.wheelSpeed * maxY / contentHeight;
				};
				
				var onStartDrag = function(event)
				{
					initDrag();
					dragMiddle = getPos(event, 'Y') - dragPosition - currentOffset.top;
					jQuery('html').bind('mouseup', onStopDrag).bind('mousemove', updateScroll);
					if (jQuery.browser.msie) {
						jQuery('html').bind('dragstart', ignoreNativeDrag).bind('selectstart', ignoreNativeDrag);
					}
					return false;
				};
				var onStopDrag = function()
				{
				    jQuery('html').unbind('mouseup', onStopDrag).unbind('mousemove', updateScroll);
					dragMiddle = percentInView*paneHeight/2;
					if (jQuery.browser.msie) {
						jQuery('html').unbind('dragstart', ignoreNativeDrag).unbind('selectstart', ignoreNativeDrag);
					}
				};
				var positionDrag = function(destY)
				{
					destY = destY < 0 ? 0 : (destY > maxY ? maxY : destY);
					dragPosition = destY;
					$drag.css({'top':destY+'px'});
					var p = destY / maxY;
					$pane.css({'top':((paneHeight-contentHeight)*p) + 'px'});
					$this.trigger('scroll');
					if (settings.showArrows)
					{
						$upArrow[destY == 0 ? 'addClass' : 'removeClass']('disabled');
						$downArrow[destY == maxY ? 'addClass' : 'removeClass']('disabled');
					}
				};
				var updateScroll = function(e)
				{
					positionDrag(getPos(e, 'Y') - currentOffset.top - dragMiddle);
				};
				
				var dragH = Math.max(Math.min(percentInView*(paneHeight-settings.arrowSize*2), settings.dragMaxHeight), settings.dragMinHeight);
				
				$drag.css({'height':dragH+'px'}).bind('mousedown', onStartDrag);
				
				var trackScrollInterval;
				var trackScrollInc;
				var trackScrollMousePos;
				var doTrackScroll = function()
				{
					if (trackScrollInc > 8 || trackScrollInc%4==0) {
						positionDrag((dragPosition - ((dragPosition - trackScrollMousePos) / 2)));
					}
					trackScrollInc ++;
				};
				var onStopTrackClick = function()
				{
					clearInterval(trackScrollInterval);
					jQuery('html')
					    .unbind('mouseup', onStopTrackClick)
					    .unbind('mousemove', onTrackMouseMove);
				};
				var onTrackMouseMove = function(event)
				{
					trackScrollMousePos = getPos(event, 'Y') - currentOffset.top - dragMiddle;
				};
				var onTrackClick = function(event)
				{
					initDrag();
					onTrackMouseMove(event);
					trackScrollInc = 0;
					jQuery('html').mouseup(onStopTrackClick).mousemove(onTrackMouseMove);
					trackScrollInterval = setInterval(doTrackScroll, 100);
					doTrackScroll();
				};
				
				$track.bind('mousedown', onTrackClick);
				
				$container.bind(
					'mousewheel',
					function (event, delta)
					{
						initDrag();
						ceaseAnimation();
						var d = dragPosition;
						positionDrag(dragPosition - delta * mouseWheelMultiplier);
						var dragOccured = d != dragPosition;
						return !dragOccured;
					}
				);

				var _animateToPosition;
				var _animateToInterval;
				function animateToPosition()
				{
					var diff = (_animateToPosition - dragPosition) / settings.animateStep;
					if (diff > 1 || diff < -1) {
						positionDrag(dragPosition + diff);
					} else {
						positionDrag(_animateToPosition);
						ceaseAnimation();
					}
				}
				var ceaseAnimation = function()
				{
					if (_animateToInterval) {
						clearInterval(_animateToInterval);
						delete _animateToPosition;
					}
				};
				var scrollTo = function(pos, preventAni)
				{
					if (typeof pos == "string") {
						$e = jQuery(pos, this);
						if (!$e.length) return;
						pos = $e.offset().top - $this.offset().top;
					}
					ceaseAnimation();
					var destDragPosition = -pos/(paneHeight-contentHeight) * maxY;
					if (preventAni || !settings.animateTo) {
						positionDrag(destDragPosition);
					} else {
						_animateToPosition = destDragPosition;
						_animateToInterval = setInterval(animateToPosition, settings.animateInterval);
					}
				};
				$this[0].scrollTo = scrollTo;
				
				$this[0].scrollBy = function(delta)
				{
					var currentPos = -parseInt($pane.css('top')) || 0;
					scrollTo(currentPos + delta);
				};
				
				initDrag();
				
				scrollTo(-currentScrollPosition, true);
			    
			    // Deal with it when the user tabs to a link or form element within this scrollpane
			    //'a,:input'
			    $this.find('a, :input').focus(
					function(event)
					{
					    var eleTop = $(this).position().top;
						var viewportTop = -parseInt($pane.css('top')) || 0;
						var maxVisibleEleTop = viewportTop + paneHeight;
						var eleInView = eleTop > viewportTop && eleTop < maxVisibleEleTop;
						if (!eleInView)
						{
							$container.scrollTop(0);
							var destPos = eleTop - settings.scrollbarMargin;
							if (eleTop > viewportTop) { // element is below viewport - scroll so it is at bottom.
								destPos += $(this).height() + 15+ settings.scrollbarMargin - paneHeight;
							}
							scrollTo(destPos);
						}
					}
				);
				
				/*
				
				if (location.hash) {
					// the timeout needs to be longer in IE when not loading from cache...
					setTimeout(function() {
						$(location.hash, $this).trigger('focus');
					}, $.browser.msie ? 100 : 0);
				}
				
				// use event delegation to listen for all clicks on links and hijack them if they are links to
				// anchors within our content...
				$(document).click(
					function(e)
					{
						$target = $(e.target);
						if ($target.is('a')) {
							var h = $target.attr('href');
							//console.log(h);
							if (h.substr(0, 1) == '#') {
								$linkedEle = $(h, $this);
								//console.log($linkedEle);
								if ($linkedEle.length) {
									$linkedEle.trigger('focus');
									return false;
								}
							}
						}
					}
				);*/
				
				jQuery.jScrollPane.active.push($this[0]);
				
			}
			else
			{
			    if (paneWidth <= this.originalSidePaddingTotal)
			    {
			        paneWidth = this.originalSidePaddingTotal;
			    }
				$this.css(
					{
						'height':paneHeight+'px',
						'width':paneWidth-this.originalSidePaddingTotal+'px',
						'padding':this.originalPadding
					}
				);
				// remove from active list?
			}
			
		}
	)
};

jQuery.fn.jScrollPane.defaults = {
	scrollbarWidth : 10,
	scrollbarMargin : 5,
	wheelSpeed : 18,
	showArrows : false,
	arrowSize : 0,
	animateTo : false,
	dragMinHeight : 1,
	dragMaxHeight : 99999,
	animateInterval : 100,
	animateStep: 3,
	maintainPosition: true,
	scrollbarOnLeft: false,
	reinitialiseOnImageLoad: false
};

// clean up the scrollTo expandos
jQuery(window)
	.bind('unload', function() {
		var els = jQuery.jScrollPane.active; 
		for (var i=0; i<els.length; i++) {
			els[i].scrollTo = els[i].scrollBy = null;
		}
	}
);
/* Copyright (c) 2006 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-12-14 23:57:10 -0600 (Fri, 14 Dec 2007) $
 * $Rev: 4163 $
 *
 * Version: 3.0
 * 
 * Requires: $ 1.2.2+
 */
(function($){$.event.special.mousewheel={setup:function(){var handler=$.event.special.mousewheel.handler;if($.browser.mozilla)$(this).bind('mousemove.mousewheel',function(event){$.data(this,'mwcursorposdata',{pageX:event.pageX,pageY:event.pageY,clientX:event.clientX,clientY:event.clientY});});if(this.addEventListener)this.addEventListener(($.browser.mozilla?'DOMMouseScroll':'mousewheel'),handler,false);else
this.onmousewheel=handler;},teardown:function(){var handler=$.event.special.mousewheel.handler;$(this).unbind('mousemove.mousewheel');if(this.removeEventListener)this.removeEventListener(($.browser.mozilla?'DOMMouseScroll':'mousewheel'),handler,false);else
this.onmousewheel=function(){};$.removeData(this,'mwcursorposdata');},handler:function(event){var args=Array.prototype.slice.call(arguments,1);event=$.event.fix(event||window.event);$.extend(event,$.data(this,'mwcursorposdata')||{});var delta=0,returnValue=true;if(event.wheelDelta)delta=event.wheelDelta/120;if(event.detail)delta=-event.detail/3;if($.browser.opera)delta=-event.wheelDelta;event.data=event.data||{};event.type="mousewheel";args.unshift(delta);args.unshift(event);return $.event.handle.apply(this,args);}};$.fn.extend({mousewheel:function(fn){return fn?this.bind("mousewheel",fn):this.trigger("mousewheel");},unmousewheel:function(fn){return this.unbind("mousewheel",fn);}});})(jQuery);
jQuery.createClass('X.Loading', function(elm)
{
	this.elm = elm;
},
{
	start: function()
	{
		this.elm.show();
		return this;
	},
	stop: function()
	{
	    this.elm.hide(); //fadeOut('slow');
		return this;
	}
});

jQuery.createSingleton('X.LoadingManager', function()
{
	this._loaders = {};
},
{
	start: function(id)
	{
	    this.toggle(id, 'start');
	},
	stop: function(id)
	{
		this.toggle(id, 'stop');
	},
	toggle: function(id, action)
	{
		if (typeof(id) === 'undefined' || id === null)
		{
		    throw new Error('X.LoadingManager.toggle(id: \'' + id + '\', action: \'' + action + '\'):: id is a required parameter.');
		    return;
		}
		
		if (!this._loaders[id] && !this._create(id)) { return; }
	    this._loaders[id][action]();
	},
	_create: function(id)
	{
	    var elm = jQuery('#'+id);
	    if (elm.length === 0) { return false; }
	    this._loaders[id] = new X.Loading(elm);
	    return true;
	}
});
window.serviceUrls = {};
window.modelYear = '2009';

// Calculator
serviceUrls.getProductLineDetails = '/tools/shopping/GetProductLineDetails.aspx?ProductLineName={arguments[1]}';
serviceUrls.calculatorHandlerReverse = '/tools/shopping/CalculatorHandler.aspx?mode={arguments[1]}&mp={arguments[2]}&lt={arguments[3]}&dp={arguments[4]}&nc={arguments[5]}';
serviceUrls.calculatorHandlerLease = '/tools/shopping/CalculatorHandler.aspx?&mode={arguments[1]}&mid={arguments[2]}&lt={arguments[3]}&m={arguments[4]}&esp={arguments[5]}&etv={arguments[6]}&b={arguments[7]}&dp={arguments[8]}';
serviceUrls.calculatorHandlerFinance = '/tools/shopping/CalculatorHandler.aspx?&mode={arguments[1]}&apr={arguments[2]}&ft={arguments[3]}&esp={arguments[4]}&etv={arguments[5]}&b={arguments[6]}&dp={arguments[7]}';

// Map
serviceUrls.dealerMapHandler = '/tools/dealerlocator/DealerMapHandler.aspx?did={arguments[1]}';
serviceUrls.dealerDirectionsHandler = '/tools/dealerlocator/DealerDirectionsHandler.aspx?did={arguments[1]}&a={arguments[2]}&c={arguments[3]}&s={arguments[4]}&z={arguments[5]}';

//email
serviceUrls.emailHandler = '/controls/SendMail.ashx?&Name={arguments[1]}&FromEmail={arguments[2]}&ToEmail={arguments[3]}&Comments={arguments[4]}&reqURL={arguments[5]}';

//precision team icon
serviceUrls.precisionTeam = '/tools/dealerlocator/AttributeDetailsHandler.aspx?dealerId={arguments[1]}&code={arguments[2]}';

///<referencepath="~/js/reference.js"/>

$.createSingleton('X.Omniture',
// Constructor
function() {
	this.keyRE = /omnikey\-(\w+)/g;
	this.keyRE.compile(this.keyRE.source, this.keyRE.options);
	
	this._queue = []; // stores calls until the omniture object is ready
	this._defaults = {}; // stores data defaults for the page
	this._lastPropsSet = [];
	
	this._useIFrame = false;
	this._forceQueuing = this._forceQueuingFlag = true;
	
	this.data = {};
},
// Prototype
{
    // Called form page docuemnt ready event handler,
    // Bind's click events to elements with omniture class
    // Also sets the defaults
    init: function() {
		$('.omniture,.omniture-page').each(function(idx) {
			X.Omniture._registerElm(this);
		});
		
		//window.setTimeout(X.Omniture.onExecuteQueue.delegate(X.Omniture), 10000);
	},
	
	onPageLoad: function() {
	    if (this._forceQueuing) {
	        setTimeout(this.onDelayedPageLoad.delegate(this), 100);
	    }
	    else {
	        this.onDelayedPageLoad();
	    }
    },
    
	onDelayedPageLoad: function() {
	    if (!this._useIFrame) {
            // not using console as acura does 		   
            //$.console.log('begin loading s_code.js', 'loading_scode');
            $.ajax({
                type: "GET",
                url: "/js/s_code.js",
                //$.getScript('/js/s_code.js', function() { $.console.log('end loading s_code.js', 'loading_scode'); X.Omniture.onExecuteQueue(); });
                //$.getScript('/js/s_code.js', function() { X.Omniture.onExecuteQueue(); });
                //success: function() { $.console.log('end loading s_code.js', 'loading_scode'); X.Omniture.onExecuteQueue(); },
                success: function() { X.Omniture.onExecuteQueue(); },
                dataType: "script",
                cache: true
            });
		}
		else {
		    $('<iframe src="/Omni.html" id="_omni_iframe_" name="_omni_iframe_" style="display:none;"></iframe>').appendTo($(document.body));
		    this.onExecuteQueue();
		}
    },
	
	/*onPageUnload: function()
	{
	    //if (!this._forceQueuingFlag) { return; }
	    this.onExecuteQueue();
	},*/
	
	// Set Ominture defaults
	setDefaults: function(props) {
		props = this._getValidData(props);
	    if (!props) { return; }
	    this._defaults = props.data;
	},
	
	// Registers a set of omniture tags data
	register: function(data) {
		if (!data) { return; }
		this.data = data;
	},
	
	// * Called via element click handler for element's with .omniture
    // * class passing in the key (extracted from omnikey-XXX class)
    // *  props.linkName
	// *  props.key
	// *  props.data
	// *
    trigger: function(props, obj, type) {
		if (!props.linkName || props.linkName === '#') {
	         props.linkName = location.href;
	    }
        if (this.update(props)) {
		    var o = this._getObject();
		    
		    //$.console.log('X.Omniture.trigger() - begin call');
		    //o.tl(true, 'o', props.linkName); //window.setTimeout(function() { }, 0);
            // exit link
            if (obj && type === 'e') {
                o.tl(obj, type);
            }
            // download link
            else if (obj && type === 'd') {
            o.tl(obj, type, props.data.fileName);
            }

            else {
                o.tl(true, 'o', props.linkName);
            }
		    //$.console.log('X.Omniture.trigger() - end call');
		}
	},
	
	// Trigger's omniture's page load
	triggerPageLoad: function(data) {
	    var props = { data: data, pageLoad: true };
	    if (this.update(props)) {    		    
		    var o = this._getObject();
		    
		    //$.console.log('X.Omniture.triggerPageLoad() - begin call');
		    var s_code = o.t(); //window.setTimeout(function() { o.t(); }, 0); // TODO - write response into document
		    //$.console.log('X.Omniture.triggerPageLoad() - end call');
		    
		    return s_code;
		}
		return '';
	},
	
	// Called via the trigger and triggerPageLoad methods,
	// as well as in page after the X.Omniture.register() method
	update: function(props) {
		if (typeof(props) === 'string') {
	        props = { key: props };
	    }
	    
	    props = this._getValidData(props);
	    
	    if (!props || !props.data) { return false; }
		
		var propNames = [];
		
		// Uppercase the values
		for (var prop in props.data) {
		    propNames[propNames.length] = prop;
		    
		    if (typeof(props.data[prop]) !== 'string') { continue; }
		    props.data[prop] = props.data[prop].toUpperCase();
		}
		
		// Ensure we have default values where the values do not exist
		props.data = $.extend({}, this._defaults, props.data);
		
		// reset the omniture object
		this._clearProps();
		
		// Add the newly set prop to the last set props
		this._lastPropsSet = propNames;
		
		// If ominiture is not loaded, add the object to the queue, and exit
		if (!this._isOmnitureLoaded()) {
		    this._queue[this._queue.length] = props;
		    return false;
		}
		
		// Set all of our properties in the window.s object
		this._setObjProps(props.data);
		
		return true;
	},
	
	// Returns the Omniture object
	_getObject: function() {
	    if (this._forceQueuing) { return null; }
	    
        if (this._useIFrame) {
	        var iframeElm = $('#_omni_iframe_')[0];
	        if (!iframeElm || !iframeElm.contentWindow) { return null; }
	        iframeElm = iframeElm.contentWindow;
	        return (iframeElm && iframeElm.s)? iframeElm.s : null;
	    }
	    else {
	        return window.s || null;
	    }
	},
	
	// Determines if omniture has been loaded
	_isOmnitureLoaded: function() {
	    var o = this._getObject();
	    return (o !== null);
	},
	
	// Set the actual Omniture object's properties
	_setObjProps: function(data) {
	    var o = this._getObject();
		for (var prop in data) {
		    o[prop] = data[prop];
		}
	},
	
	// onExecuteQueue, loop through the queue of calls, and call them
	// ONLY CALLED AFTER OMNITURE IS AVAILABLE IN THE PAGE
	// ONLY GETS CALLED FROM window.onload
	onExecuteQueue: function() {
	    this._forceQueuing = false;
	    
	    if (!this._isOmnitureLoaded()) { return; }
	    
	    var len = this._queue.length;
	    if (len === 0) { return; }
	    
	    // loop through each item in the queue, and call omniture
	    for (var idx = 0, props; idx < len; idx++) {
	        props = this._queue[idx];
	        
	        // Clear out the previously set props (if any)
	        if (idx > 0) {
	            this._clearProps();
	        }
	        
	        // Get the names for the last call
	        this._lastPropsSet = [];
	        for (var prop in props.data) {
		        this._lastPropsSet[this._lastPropsSet.length] = prop;
		    }
	        
	        this._setObjProps(props.data);
	        
	        var o = this._getObject();
	        if (props.pageLoad) {
	            //$.console.log('X.Omniture.onExecuteQueue() t() - begin call');
		        o.t(); // TODO - write response into document
	            //$.console.log('X.Omniture.onExecuteQueue() t() - end call');
		    }
	        else {
	            //$.console.log('X.Omniture.onExecuteQueue() tl() - begin call');
		        o.tl(true, 'o', props.linkName);
		        //$.console.log('X.Omniture.onExecuteQueue() tl() - end call');
	        }
	    }
	    
	    this._queue = [];
	    
	    //alert('end making queued calls');
	},
	
	// Clear out the Omniture object's last set properties
	_clearProps: function() {
	    if (!this._isOmnitureLoaded()) { return; }
	    
	    var len = this._lastPropsSet.length;
	    if (len > 0) {
	        var o = this._getObject();
	        for (var idx = 0, prop; idx < len; idx++) {
	            prop = this._lastPropsSet[idx];
	            try {
	                o[prop] = {};
	                delete o[prop];
	            }
	            catch (ex) {
	                o[prop] = '';
	            }
	        }
	    }
	    this._lastPropsSet = [];
	},
	
	// Checks to see if the props object passed in has a data prop, and if not
	// sets it to the key
	_getValidData: function(props) {
	    // If we don't have data being passed in,
	    // then look it up via the key
	    // If there is no data for the key, then this is an invalid call, exit
	    if (!props.data) {
	        if (!props.key) { return null; }
	        
	        // 'k' is our key prefix
		    props.data = this.data['k' + props.key];
		    if (!props.data) { return null; }
		}
		return props;
	},
	
	// Register's an element's click event to the _handleEvent method
	_registerElm: function(elm) {
		var matches = this.keyRE.exec(elm.className);		
		this.keyRE.lastIndex = 0;
		if (!matches || matches.length < 2) { return; }
		
		var key = matches[1];
		$(elm).click(this._handleEvent.proxy(elm, key));
	},
	
	// Handles a omniture trackLink event
	_handleEvent: function(evt, key) {
	    if (!$(this).hasClass('omniture-page')) {
	        X.Omniture.trigger({ linkName: this.href, key: key });
	    }
	    else {
	        X.Omniture.triggerPageLoad(X.Omniture._getValidData({ key: key }).data);
	    }
	}
});

X.Omniture.init();

$(window)
    .load(X.Omniture.onPageLoad.delegate(X.Omniture))
    //.unload(X.Omniture.onPageUnload.delegate(X.Omniture));
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
