/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;



/**
 * 
 * Copyright 2007
 * 
 * Paulius Uza
 * http://www.uza.lt
 * 
 * Dan Florio
 * http://www.polygeek.com
 * 
 * Project website:
 * http://code.google.com/p/custom-context-menu/
 * 
 * --
 * RightClick for Flash Player. 
 * Version 0.6.2
 * 
 */

var RightClick = {
	/**
	 *  Constructor
	 */ 
	init: function () {
		this.FlashObjectID = "index";
		this.FlashContainerID = "flashcontent";
		this.Cache = this.FlashObjectID;
		if(window.addEventListener){
			 window.addEventListener("mousedown", this.onGeckoMouse(), true);
		} else {
			document.getElementById(this.FlashContainerID).onmouseup = function() { document.getElementById(RightClick.FlashContainerID).releaseCapture(); }
			document.oncontextmenu = function(){ if(window.event.srcElement.id == RightClick.FlashObjectID) { return false; } else { RightClick.Cache = "nan"; }}
			document.getElementById(this.FlashContainerID).onmousedown = RightClick.onIEMouse;
		}
	},
	/**
	 * GECKO / WEBKIT event overkill
	 * @param {Object} eventObject
	 */
	killEvents: function(eventObject) {
		if(eventObject) {
			if (eventObject.stopPropagation) eventObject.stopPropagation();
			if (eventObject.preventDefault) eventObject.preventDefault();
			if (eventObject.preventCapture) eventObject.preventCapture();
	   		if (eventObject.preventBubble) eventObject.preventBubble();
		}
	},
	/**
	 * GECKO / WEBKIT call right click
	 * @param {Object} ev
	 */
	onGeckoMouse: function(ev) {
	  	return function(ev) {
	    if (ev.button != 0) {
			RightClick.killEvents(ev);
			if(ev.target.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
	    		RightClick.call();
			}
			RightClick.Cache = ev.target.id;
		}
	  }
	},
	/**
	 * IE call right click
	 * @param {Object} ev
	 */
	onIEMouse: function() {
	  	if (event.button > 1) {
			if(window.event.srcElement.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
				RightClick.call(); 
			}
			document.getElementById(RightClick.FlashContainerID).setCapture();
			if(window.event.srcElement.id)
			RightClick.Cache = window.event.srcElement.id;
		}
	},
	/**
	 * Main call to Flash External Interface
	 */
	call: function() {
		document.getElementById(this.FlashObjectID).rightClick();
	}
}











//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

var MooTools={version:"1.2dev",build:"1475"};var Native=function(J){J=J||{};var F=J.afterImplement||function(){};var G=J.generics;G=(G!==false);var H=J.legacy;
var E=J.initialize;var B=J.protect;var A=J.name;var C=E||H;C.constructor=Native;C.$family={name:"native"};if(H&&E){C.prototype=H.prototype;}C.prototype.constructor=C;
if(A){var D=A.toLowerCase();C.prototype.$family={name:D};Native.typize(C,D);}var I=function(M,K,N,L){if(!B||L||!M.prototype[K]){M.prototype[K]=N;}if(G){Native.genericize(M,K,B);
}F.call(M,K,N);return M;};C.implement=function(L,K,N){if(typeof L=="string"){return I(this,L,K,N);}for(var M in L){I(this,M,L[M],K);}return this;};C.alias=function(K,M,L){K=this.prototype[K];
if(K){I(this,M,K,L);}return this;};return C;};Native.implement=function(D,C){for(var B=0,A=D.length;B<A;B++){D[B].implement(C);}};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments);
return B.prototype[C].apply(D.shift(),D);};}};Native.typize=function(A,B){if(!A.type){A.type=function(C){return($type(C)===B);};}};(function(B){for(var A in B){Native.typize(B[A],A.toLowerCase());
}})({Boolean:Boolean,Native:Native,Object:Object});(function(B){for(var A in B){new Native({name:A,initialize:B[A],protect:true});}})({String:String,Function:Function,Number:Number,Array:Array,RegExp:RegExp,Date:Date});
(function(C,B){for(var D=0,A=B.length;D<A;D++){Native.genericize(C,B[D],true);}return arguments.callee;})(Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","toString","valueOf","indexOf","lastIndexOf"])(String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]);
function $chk(A){return !!(A||A===0);}function $clear(A){clearTimeout(A);clearInterval(A);return null;}function $defined(A){return(A!=undefined);}function $empty(){}function $arguments(A){return function(){return arguments[A];
};}function $lambda(A){return(typeof A=="function")?A:function(){return A;};}function $extend(C,A){for(var B in (A||{})){C[B]=A[B];}return C;}function $unlink(C){var B=null;
switch($type(C)){case"object":B={};for(var E in C){B[E]=$unlink(C[E]);}break;case"array":B=[];for(var D=0,A=C.length;D<A;D++){B[D]=$unlink(C[D]);}break;
default:return C;}return B;}function $merge(){var E={};for(var D=0,A=arguments.length;D<A;D++){var B=arguments[D];if($type(B)!="object"){continue;}for(var C in B){var G=B[C],F=E[C];
E[C]=(F&&$type(G)=="object"&&$type(F)=="object")?$merge(F,G):$unlink(G);}}return E;}function $pick(){for(var B=0,A=arguments.length;B<A;B++){if($defined(arguments[B])){return arguments[B];
}}return null;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);}function $splat(B){var A=$type(B);return(A)?((A!="array"&&A!="arguments")?[B]:B):[];
}var $time=Date.now||function(){return new Date().getTime();};function $try(){for(var B=0,A=arguments.length;B<A;B++){try{return arguments[B]();}catch(C){}}return null;
}function $type(A){if(A==undefined){return false;}if(A.$family){return(A.$family.name=="number"&&!isFinite(A))?false:A.$family.name;}if(A.nodeName){switch(A.nodeType){case 1:return"element";
case 3:return(/\S/).test(A.nodeValue)?"textnode":"whitespace";}}else{if(typeof A.length=="number"){if(A.callee){return"arguments";}else{if(A.item){return"collection";
}}}}return typeof A;}var Hash=new Native({name:"Hash",initialize:function(A){if($type(A)=="hash"){A=$unlink(A.getClean());}for(var B in A){this[B]=A[B];
}return this;}});Hash.implement({getLength:function(){var B=0;for(var A in this){if(this.hasOwnProperty(A)){B++;}}return B;},forEach:function(B,C){for(var A in this){if(this.hasOwnProperty(A)){B.call(C,this[A],A,this);
}}},getClean:function(){var B={};for(var A in this){if(this.hasOwnProperty(A)){B[A]=this[A];}}return B;}});Hash.alias("forEach","each");function $H(A){return new Hash(A);
}Array.implement({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);}}});Array.alias("forEach","each");function $A(C){if(C.item){var D=[];
for(var B=0,A=C.length;B<A;B++){D[B]=C[B];}return D;}return Array.prototype.slice.call(C);}function $each(C,B,D){var A=$type(C);((A=="arguments"||A=="collection"||A=="array")?Array:Hash).each(C,B,D);
}$A=function(D,F,C){if(Browser.Engine.trident&&$type(D)=="collection"){F=F||0;if(F<0){F=D.length+F;}C=C||(D.length-F);var E=[];for(var B=0;B<C;B++){E[B]=D[F++];
}return E;}F=(F||0)+((F<0)?D.length:0);var A=((!$chk(C))?D.length:C)+F;return Array.prototype.slice.call(D,F,A);};(function(){var B=[Array,Function,String,RegExp,Number];
for(var C=0,A=B.length;C<A;C++){B[C].extend=B[C].implement;}})();var Browser=new Hash({Engine:{name:"unknown",version:""},Platform:{name:(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime)},Plugins:{}});
if(window.opera){Browser.Engine={name:"presto",version:(document.getElementsByClassName)?950:925};}else{if(window.ActiveXObject){Browser.Engine={name:"trident",version:(window.XMLHttpRequest)?5:4};
}else{if(!navigator.taintEnabled){Browser.Engine={name:"webkit",version:(Browser.Features.xpath)?420:419};}else{if(document.getBoxObjectFor!=null){Browser.Engine={name:"gecko",version:(document.getElementsByClassName)?19:18};
}}}}Browser.Engine[Browser.Engine.name]=Browser.Engine[Browser.Engine.name+Browser.Engine.version]=true;if(window.orientation!=undefined){Browser.Platform.name="ipod";
}Browser.Platform[Browser.Platform.name]=true;Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");
});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var A=($try(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(A[0]||0+"."+A[1]||0),build:parseInt(A[2]||0)};
})();function $exec(B){if(!B){return B;}if(window.execScript){window.execScript(B);}else{var A=document.createElement("script");A.setAttribute("type","text/javascript");
A.text=B;document.head.appendChild(A);document.head.removeChild(A);}return B;}Native.UID=1;var $uid=(Browser.Engine.trident)?function(A){return(A.uid||(A.uid=[Native.UID++]))[0];
}:function(A){return A.uid||(A.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:window.Window,initialize:function(A){$uid(A);if(!A.Element){A.Element=$empty;
if(Browser.Engine.webkit){A.document.createElement("iframe");}A.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};}return $extend(A,Window.Prototype);
},afterImplement:function(B,A){window[B]=Window.Prototype[B]=A;}});Window.Prototype={$family:{name:"window"}};new Window(window);var Document=new Native({name:"Document",legacy:window.Document,initialize:function(A){$uid(A);
A.head=A.getElementsByTagName("head")[0];A.html=A.getElementsByTagName("html")[0];A.window=A.defaultView||A.parentWindow;if(Browser.Engine.trident4){$try(function(){A.execCommand("BackgroundImageCache",false,true);
});}return $extend(A,Document.Prototype);},afterImplement:function(B,A){document[B]=Document.Prototype[B]=A;}});Document.Prototype={$family:{name:"document"}};
new Document(document);window.extend=document.extend=function(A){for(var B in A){this[B]=A[B];}};window.extend(Browser.Engine);window.ie=window.trident;
window.ie6=window.trident4;window.ie7=window.trident5;Array.implement({every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;
}}return true;},filter:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},clean:function(){return this.filter($arguments(0));
},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;}}return -1;},map:function(D,E){var C=[];
for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);}return C;},some:function(C,D){for(var B=0,A=this.length;B<A;B++){if(C.call(D,this[B],B,this)){return true;
}}return false;},associate:function(C){var D={},B=Math.min(this.length,C.length);for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},link:function(C){var A={};
for(var E=0,B=this.length;E<B;E++){for(var D in C){if(C[D](this[E])){A[D]=this[E];delete C[D];break;}}}return A;},contains:function(A,B){return this.indexOf(A,B)!=-1;
},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;
},include:function(A){if(!this.contains(A)){this.push(A);}return this;},merge:function(C){for(var B=0,A=C.length;B<A;B++){this.include(C[B]);}return this;
},erase:function(B){for(var A=this.length;A--;A){if(this[A]===B){this.splice(A,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var D=[];
for(var B=0,A=this.length;B<A;B++){var C=$type(this[B]);if(!C){continue;}D=D.concat((C=="array"||C=="collection"||C=="arguments")?Array.flatten(this[B]):this[B]);
}return D;},hexToRgb:function(B){if(this.length!=3){return null;}var A=this.map(function(C){if(C.length==1){C+=C;}return C.toInt(16);});return(B)?A:"rgb("+A+")";
},rgbToHex:function(D){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;A++){var C=(this[A]-0).toString(16);
B.push((C.length==1)?"0"+C:C);}return(D)?B:"#"+B.join("");}});Array.implement({copy:function(B,A){return $A(this,B,A);}});Array.alias("erase","remove");
Function.implement({extend:function(A){for(var B in A){this[B]=A[B];}return this;},create:function(B){var A=this;B=B||{};return function(D){var C=B.arguments;
C=$defined(C)?$splat(C):Array.slice(arguments,(B.event)?1:0);if(B.event){C=[D||window.event].extend(C);}var E=function(){return A.apply(B.bind||null,C);
};if(B.delay){return setTimeout(E,B.delay);}if(B.periodical){return setInterval(E,B.periodical);}if(B.attempt){return $try(E);}return E();};},pass:function(A,B){return this.create({arguments:A,bind:B});
},attempt:function(A,B){return this.create({arguments:A,bind:B,attempt:true})();},bind:function(B,A){return this.create({bind:B,arguments:A});},bindWithEvent:function(B,A){return this.create({bind:B,event:true,arguments:A});
},delay:function(B,C,A){return this.create({delay:B,bind:C,arguments:A})();},periodical:function(A,C,B){return this.create({periodical:A,bind:C,arguments:B})();
},run:function(A,B){return this.apply(B,$splat(A));}});Function.extend({bindAsEventListener:function(B,A){return this.create({bind:B,event:true,"arguments":A});
}});Function.empty=$empty;Number.implement({limit:function(B,A){return Math.min(A,Math.max(B,this));},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;
},times:function(B,C){for(var A=0;A<this;A++){B.call(C,A,this);}},toFloat:function(){return parseFloat(this);},toInt:function(A){return parseInt(this,A||10);
}});Number.alias("times","each");(function(B){var A={};B.each(function(C){if(!Number[C]){A[C]=function(){return Math[C].apply(null,[this].concat($A(arguments)));
};}});Number.implement(A);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);String.implement({test:function(A,B){return((typeof A=="string")?new RegExp(A,B):A).test(this);
},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A="";
var C=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C);
}}return C;},substitute:function(A,B){return this.replace(B||/\\?\{([^}]+)\}/g,function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:"";
});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null;
},hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},merge:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C);
},this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null;
},set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this);
return this;},include:function(B,C){var A=this[B];if(!$defined(A)){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this));
},this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false;
}}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[];
Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(){var A=[];
Hash.each(this,function(C,B){$splat(C).each(function(D){A.push(B+"="+encodeURIComponent(D));});});return A.join("&");}});Hash.alias("keyOf","indexOf").alias("hasValue","contains");
Hash.alias("getKeys","keys").alias("getValues","values").alias("has","hasKey");var Abstract=Hash;var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;
A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type;var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;
var L=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111;if(D>0&&D<13){L="f"+D;}}L=L||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){var I={x:A.pageX||A.clientX+F.document.documentElement.scrollLeft,y:A.pageY||A.clientY+F.document.documentElement.scrollTop};
var C={x:A.pageX?A.pageX-F.pageXOffset:A.clientX,y:A.pageY?A.pageY-F.pageYOffset:A.clientY};if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;
}var E=(A.which==3)||(A.button==2);var K=null;if(J.match(/over|out/)){switch(J){case"mouseover":K=A.relatedTarget||A.fromElement;break;case"mouseout":K=A.relatedTarget||A.toElement;
}if(!(function(){while(K&&K.nodeType==3){K=K.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){K=false;}}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:K,target:G,code:B,key:L,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey});
}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault();
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
}else{this.event.returnValue=false;}return this;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(){for(var D in this){this[D]=$unlink(this[D]);
}this.parent=null;for(var E in Class.Mutators){if(!this[E]){continue;}Class.Mutators[E](this,this[E]);delete this[E];}this.constructor=A;var C=(arguments[0]!==$empty&&this.initialize)?this.initialize.apply(this,arguments):this;
if(this.options&&this.options.initialize){this.options.initialize.call(this);}return C;};$extend(A,this);A.constructor=Class;A.prototype=B;return A;}});
Class.implement({implement:function(){Class.Mutators.Implements(this.prototype,Array.slice(arguments));return this;}});Class.Mutators={};Class.Mutators.Implements=function(A,B){$splat(B).each(function(C){$extend(A,($type(C)=="class")?new C($empty):C);
});};Class.Mutators.Extends=function(C,A){A=new A($empty);for(var E in A){var B=A[E];var D=C[E];C[E]=(function(G,H){if($defined(H)&&G!=H){var F=$type(H);
if(F!=$type(G)){return H;}switch(F){case"function":return function(){H.parent=this.parent=G.bind(this);var I=H.apply(this,arguments);this.parent=H.parent;
return I;};case"object":return $merge(G,H);default:return H;}}return G;})(B,D);}};Class.empty=$empty;Class.prototype.extend=function(A){A.Extends=this;
return new Class(A);};var Chain=new Class({chain:function(){this.$chain=(this.$chain||[]).extend(arguments);return this;},callChain:function(){return(this.$chain&&this.$chain.length)?this.$chain.shift().apply(this,arguments):false;
},clearChain:function(){if(this.$chain){this.$chain.empty();}return this;}});var Events=new Class({addEvent:function(C,B,A){if(B!=$empty){this.$events=this.$events||{};
this.$events[C]=this.$events[C]||[];this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);
}return this;},fireEvent:function(C,B,A){if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();
},this);return this;},removeEvent:function(B,A){if(!this.$events||!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;
},removeEvents:function(C){for(var D in this.$events){if(C&&C!=D){continue;}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]);}}return this;
}});var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;
}this.addEvent(A,this.options[A]);delete this.options[A];}return this;}});Document.implement({newElement:function(A,B){if(Browser.Engine.trident&&B){["name","type","checked"].each(function(C){if(!B[C]){return ;
}A+=" "+C+'="'+B[C]+'"';if(C!="checked"){delete B[C];}});A="<"+A+">";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A);
},getDocument:function(){return this;},getWindow:function(){return this.defaultView||this.parentWindow;},purge:function(){var C=this.getElementsByTagName("*");
for(var B=0,A=C.length;B<A;B++){memfree(C[B]);}}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A);
if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){if(!Array[A]){Elements.implement(A,Elements.multi(A));
}Element.Prototype[A]=B;}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var E=Array.link(arguments,{properties:Object.type,iframe:$defined});
var C=E.properties||{};var B=$(E.iframe)||false;var D=C.onload||$empty;delete C.onload;C.id=C.name=$pick(C.id,C.name,B.id,B.name,"IFrame_"+$time());B=new Element(B||"iframe",C);
var A=function(){var F=$try(function(){return B.contentWindow.location.host;});if(F&&F==window.location.host){B.window=B.contentWindow;var H=new Window(B.window);
var G=new Document(B.window.document);$extend(H.Element.prototype,Element.Prototype);}D.call(B.contentWindow,B.contentWindow.document);};(!window.frames[C.id])?B.addListener("load",A):A();
return B;}});var Elements=new Native({initialize:function(F,B){B=$extend({ddup:true,cash:true},B);F=F||[];if(B.ddup||B.cash){var G={},E=[];for(var C=0,A=F.length;
C<A;C++){var D=$.element(F[C],!B.cash);if(B.ddup){if(G[D.uid]){continue;}G[D.uid]=true;}E.push(D);}F=E;}return(B.cash)?$extend(F,this):F;}});Elements.implement({filterBy:function(A){if(!A){return this;
}return new Elements(this.filter((typeof A=="string")?function(B){return B.match(A);}:A));}});Elements.multi=function(A){return function(){var B=[];var F=true;
for(var D=0,C=this.length;D<C;D++){var E=this[D][A].apply(this[D],arguments);B.push(E);if(F){F=($type(E)=="element");}}return(F)?new Elements(B):B;};};
Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B);return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);
}var F=[];var C=Array.flatten(arguments);for(var D=0,B=C.length;D<B;D++){var E=C[D];switch($type(E)){case"element":E=[E];break;case"string":E=this.document.getElements(E,true);
break;default:E=false;}if(E){F.extend(E);}}return new Elements(F);},getDocument:function(){return this.document;},getWindow:function(){return this;}});
$.string=function(C,A,B){C=B.getElementById(C);return(C)?$.element(C,A):null;};$.element=function(A,C){$uid(A);if(!C&&!A.$family&&!(/^object|embed$/i).test(A.tagName)){var B=Element.Prototype;
for(var D in B){A[D]=B[D];}}return A;};$.object=function(C,A,B){if(C.toElement){return $.element(C.toElement(B),A);}return null;};$.textnode=$.whitespace=$.window=$.document=$arguments(0);
Native.implement([Element,Document],{getElement:function(A,B){return $(this.getElements(A,true)[0]||null,B);},getElements:function(A,D){A=A.split(",");
var C=[];var B=(A.length>1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D});
}});Element.Storage={get:function(A){return(this[A]||(this[A]={}));}};Element.Inserters=new Hash({before:function(B,A){if(A.parentNode){A.parentNode.insertBefore(B,A);
}},after:function(B,A){if(!A.parentNode){return ;}var C=A.nextSibling;(C)?A.parentNode.insertBefore(B,C):A.parentNode.appendChild(B);},bottom:function(B,A){A.appendChild(B);
},top:function(B,A){var C=A.firstChild;(C)?A.insertBefore(B,C):A.appendChild(B);}});Element.Inserters.inside=Element.Inserters.bottom;Element.Inserters.each(function(C,B){var A=B.capitalize();
Element.implement("inject"+A,function(D){Element.Inserters[B](this,$(D,true));return this;});Element.implement("grab"+A,function(D){Element.Inserters[B]($(D,true),this);
return this;});});Element.implement({getDocument:function(){return this.ownerDocument;},getWindow:function(){return this.ownerDocument.getWindow();},getElementById:function(D,C){var B=this.ownerDocument.getElementById(D);
if(!B){return null;}for(var A=B.parentNode;A!=this;A=A.parentNode){if(!A){return null;}}return $.element(B,C);},set:function(D,B){switch($type(D)){case"object":for(var C in D){this.set(C,D[C]);
}break;case"string":var A=Element.Properties.get(D);(A&&A.set)?A.set.apply(this,Array.slice(arguments,1)):this.setProperty(D,B);}return this;},get:function(B){var A=Element.Properties.get(B);
return(A&&A.get)?A.get.apply(this,Array.slice(arguments,1)):this.getProperty(B);},erase:function(B){var A=Element.Properties.get(B);(A&&A.erase)?A.erase.apply(this,Array.slice(arguments,1)):this.removeProperty(B);
return this;},match:function(A){return(!A||Element.get(this,"tag")==A);},inject:function(B,A){Element.Inserters.get(A||"bottom")(this,$(B,true));return this;
},wraps:function(B,A){B=$(B,true);return this.replaces(B).grab(B);},grab:function(B,A){Element.Inserters.get(A||"bottom")($(B,true),this);return this;},appendText:function(B,A){return this.grab(this.getDocument().newTextNode(B),A);
},adopt:function(){Array.flatten(arguments).each(function(A){A=$(A,true);if(A){this.appendChild(A);}},this);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
},clone:function(D,C){switch($type(this)){case"element":var H={};for(var G=0,E=this.attributes.length;G<E;G++){var B=this.attributes[G],L=B.nodeName.toLowerCase();
var K=(L=="style"&&this.style)?this.style.cssText:B.nodeValue;if(!$chk(K)||L=="uid"||(L=="id"&&!C)){continue;}if(K!="inherit"&&["string","number"].contains($type(K))){H[L]=K;
}}var J=new Element(this.nodeName.toLowerCase(),H);if(D!==false){for(var I=0,F=this.childNodes.length;I<F;I++){var A=Element.clone(this.childNodes[I],true,C);
if(A){J.grab(A);}}}return J;case"textnode":return document.newTextNode(this.nodeValue);}return null;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this,A);
return this;},hasClass:function(A){return this.className.contains(A," ");},addClass:function(A){if(!this.hasClass(A)){this.className=(this.className+" "+A).clean();
}return this;},removeClass:function(A){this.className=this.className.replace(new RegExp("(^|\\s)"+A+"(?:\\s|$)"),"$1").clean();return this;},toggleClass:function(A){return this.hasClass(A)?this.removeClass(A):this.addClass(A);
},getComputedStyle:function(C){var A=null;if(this.currentStyle){A=this.currentStyle[C.camelCase()];}else{var B=this.getWindow().getComputedStyle(this,null);
if(B){A=B.getPropertyValue([C.hyphenate()]);}}return A;},empty:function(){$A(this.childNodes).each(function(A){Element.empty(A);this.removeChild(A);memfree(A);
},this);return this;},destroy:function(){memfree(this.empty().dispose());return null;},toQueryString:function(){var A=[];this.getElements("input, select, textarea",true).each(function(D){var B=D.name,C=D.type,E=Element.get(D,"value");
if(E===false||!B||D.disabled){return ;}$splat(E).each(function(F){A.push(B+"="+encodeURIComponent(F));});});return A.join("&");},getProperty:function(C){var B=Element.Attributes,A=B.Props[C];
var D=(A)?this[A]:this.getAttribute(C,2);return(B.Bools[C])?!!D:D;},getProperties:function(){var A=$A(arguments);return A.map(function(B){return this.getProperty(B);
},this).associate(A);},setProperty:function(D,E){var C=Element.Attributes,B=C.Props[D],A=$defined(E);if(B&&C.Bools[D]){E=(E||!A)?true:false;}else{if(!A){return this.removeProperty(D);
}}(B)?this[B]=E:this.setAttribute(D,E);return this;},setProperties:function(A){for(var B in A){this.setProperty(B,A[B]);}return this;},removeProperty:function(D){var C=Element.Attributes,B=C.Props[D],A=(B&&C.Bools[D]);
(B)?this[B]=(A)?false:"":this.removeAttribute(D);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;}});
(function(){var A=function(D,B,I,C,F,H){var E=D[I||B];var G=[];while(E){if(E.nodeType==1&&(!C||Element.match(E,C))){G.push(E);if(!F){break;}}E=E[B];}return(F)?new Elements(G,{ddup:false,cash:!H}):$(G[0],H);
};Element.implement({getPrevious:function(B,C){return A(this,"previousSibling",null,B,false,C);},getAllPrevious:function(B,C){return A(this,"previousSibling",null,B,true,C);
},getNext:function(B,C){return A(this,"nextSibling",null,B,false,C);},getAllNext:function(B,C){return A(this,"nextSibling",null,B,true,C);},getFirst:function(B,C){return A(this,"nextSibling","firstChild",B,false,C);
},getLast:function(B,C){return A(this,"previousSibling","lastChild",B,false,C);},getParent:function(B,C){return A(this,"parentNode",null,B,false,C);},getParents:function(B,C){return A(this,"parentNode",null,B,true,C);
},getChildren:function(B,C){return A(this,"nextSibling","firstChild",B,true,C);},hasChild:function(B){B=$(B,true);return(!!B&&$A(this.getElementsByTagName(B.tagName)).contains(B));
}});})();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";
}};Element.Properties.value={get:function(){switch(Element.get(this,"tag")){case"select":var A=[];Array.each(this.options,function(B){if(B.selected){A.push(B.value);
}});return(this.multiple)?A:A[0];case"input":if(["checkbox","radio"].contains(this.type)&&!this.checked){return false;}default:return $pick(this.value,false);
}}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};Element.Properties.href={get:function(){return(!this.href)?null:this.href.replace(new RegExp("^"+document.location.protocol+"//"+document.location.host),"");
}};Element.Properties.html={set:function(){return this.innerHTML=Array.flatten(arguments).join("");}};Element.implement({getText:function(){return this.get("text");
},setText:function(A){return this.set("text",A);},setHTML:function(){return this.set("html",arguments);},getHTML:function(){return this.get("html");},getTag:function(){return this.get("tag");
}});Native.implement([Element,Window,Document],{addListener:function(B,A){if(this.addEventListener){this.addEventListener(B,A,false);}else{this.attachEvent("on"+B,A);
}return this;},removeListener:function(B,A){if(this.removeEventListener){this.removeEventListener(B,A,false);}else{this.detachEvent("on"+B,A);}return this;
},retrieve:function(B,A){var D=Element.Storage.get(this.uid);var C=D[B];if($defined(A)&&!$defined(C)){C=D[B]=A;}return $pick(C);},store:function(B,A){var C=Element.Storage.get(this.uid);
C[B]=A;return this;},eliminate:function(A){var B=Element.Storage.get(this.uid);delete B[A];return this;}});Element.Attributes=new Hash({Props:{html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident)?"innerText":"textContent"},Bools:["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"],Camels:["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]});
(function(B){var C=B.Bools,A=B.Camels;B.Bools=C=C.associate(C);Hash.extend(Hash.merge(B.Props,C),A.associate(A.map(function(D){return D.toLowerCase();})));
B.erase("Camels");})(Element.Attributes);function memfree(A){if(!A||!A.tagName){return ;}if(Browser.Engine.trident&&(/object/i).test(A.tagName)){for(var B in A){if(typeof A[B]=="function"){A[B]=$empty;
}}Element.dispose(A);}if(A.removeEvents){A.removeEvents();}}window.addListener("unload",function(){document.purge();if(Browser.Engine.trident){CollectGarbage();
}});Element.extend=Element.implement;Elements.extend=Elements.implement;Element.implement({getFormElements:function(){return this.getElements("input, textarea, select");
},replaceWith:function(A){A=$(A);this.parentNode.replaceChild(A,this);return A;},removeElements:function(){return this.dispose();},getValue:function(){return this.get("value");
}});Element.alias("dispose","remove").alias("getLast","getLastChild");Element.Properties.events={set:function(A){this.addEvents(A);}};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});
H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this;}H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);
}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J);}return false;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F]||0;
if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow());if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(D,C){var B=this.retrieve("events");
if(!B||!B[D]){return this;}var G=B[D].keys.indexOf(C);if(G==-1){return this;}var A=B[D].keys.splice(G,1)[0];var F=B[D].values.splice(G,1)[0];var E=Element.Events.get(D);
if(E){if(E.onRemove){E.onRemove.call(this,C);}D=E.base||D;}return(Element.NativeEvents[D])?this.removeListener(D,F):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);
}return this;},removeEvents:function(B){var A=this.retrieve("events");if(!A){return this;}if(!B){for(var C in A){this.removeEvents(C);}A=null;}else{if(A[B]){while(A[B].keys[0]){this.removeEvent(B,A[B].keys[0]);
}A[B]=null;}}return this;},fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})();
},this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E);
},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:1,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
(function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C));
};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});
})();Event.keys=Event.Keys;Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";
}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";
}this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true);
},getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat";
}B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E;
}).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity");
case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue;
}for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/);
if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0;
B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px";
}if(Browser.Engine.presto&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]);
}return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});
Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles;
var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color";
F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});Element.implement({setOpacity:function(A){return this.set("opacity",A);
}});(function(){var A={style:function(D,C){return Element.getComputedStyle(D,C).toInt()||0;},borders:function(C){if(B.body(C)){return{x:0,y:0};}return(Browser.Engine.trident)?A.clientPosition(C):{x:A.style(C,"border-left-width"),y:A.style(C,"border-top-width")};
},margins:function(C){if(B.body(C)){return{x:0,y:0};}return{x:A.style(C,"margin-left"),y:A.style(C,"margin-top")};},offsetParent:function(C){if(B.body(C)){return null;
}if(!Browser.Engine.trident){return $(C.offsetParent);}while((C=C.parentNode)){if(B.positioned(C)){return $(C);}}return null;},offsetPosition:function(C){return{x:C.offsetLeft,y:C.offsetTop};
},offsetSize:function(C){return{x:C.offsetWidth,y:C.offsetHeight};},scrollSize:function(C){return{x:C.scrollWidth,y:C.scrollHeight};},scrollPosition:function(C){return{x:C.scrollLeft,y:C.scrollTop};
},clientPosition:function(C){return{x:C.clientLeft,y:C.clientTop};},clientSize:function(C){return{x:C.clientWidth,y:C.clientHeight};}};var B={body:function(D){var C=D.tagName.toLowerCase();
return(C=="body"||C=="html");},positioned:function(C){if(B.body(C)){return true;}return(Element.getComputedStyle(C,"position")!="static");}};Element.implement({positioned:function(){return B.positioned(this);
},getOffsetParent:function(){return A.offsetParent(this);},getSize:function(){if(B.body(this)){return this.getWindow().getSize();}return A.offsetSize(this);
},getScrollSize:function(){if(B.body(this)){return this.getWindow().getScrollSize();}return A.scrollSize(this);},getScroll:function(){if(B.body(this)){return this.getWindow().getScroll();
}return A.scrollPosition(this);},scrollTo:function(C,D){if(B.body(this)){this.getWindow().scrollTo(C,D);}else{this.scrollLeft=C;this.scrollTop=D;}return this;
},getPosition:function(G,D){if(B.body(this)){return{x:0,y:0};}var E=this,C=A.offsetPosition(E);while((E=E.offsetParent)&&!B.body(E)){var I=A.borders(E),F=A.offsetPosition(E);
C.x+=F.x+I.x;C.y+=F.y+I.y;}if(G===true){var H=A.borders(this);C.x+=H.x;C.y+=H.y;}G=$(G);var J=(G)?G.getPosition(true):{x:0,y:0};return{x:C.x-J.x,y:C.y-J.y};
},getCoordinates:function(E){if(B.body(this)){return this.getWindow().getCoordinates();}var C=this.getPosition(E),D=A.offsetSize(this);var F={left:C.x,top:C.y,width:D.x,height:D.y};
F.right=F.left+F.width;F.bottom=F.top+F.height;return F;},getRelativePosition:function(){return this.getPosition(A.offsetParent(this));},computePosition:function(D){var C=A.margins(this);
return{left:D.x-C.x,top:D.y-C.y};},position:function(C){return this.setStyles(this.computePosition(C));}});Native.implement([Window,Document],{getSize:function(){var F=this.getDocument(),E=this.getWindow(),D=F.documentElement,C=F.body;
if(Browser.Engine.webkit419){return{x:E.innerWidth,y:E.innerHeight};}if(Browser.Engine.presto925){return A.clientSize(C);}return A.clientSize(D);},getScroll:function(){var D=this.getWindow(),C=this.getDocument().documentElement;
return{x:$pick(D.pageXOffset,C.scrollLeft),y:$pick(D.pageYOffset,C.scrollTop)};},getScrollSize:function(){var E=this.getDocument(),D=E.documentElement,C=E.body;
if(Browser.Engine.trident){return{x:Math.max(D.clientWidth,D.scrollWidth),y:Math.max(D.clientHeight,D.scrollHeight)};}if(Browser.Engine.webkit){return A.scrollSize(C);
}return A.scrollSize(D);},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var C=this.getSize();return{top:0,left:0,bottom:C.y,right:C.x,height:C.y,width:C.x};
}});})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(",");
var C,E={};for(var D=0,B=H.length;D<B;D++){var A=H[D],F=Selectors.Utils.search(this,A,E);if(D!=0&&F.item){F=$A(F);}C=(D==0)?F:(C.item)?$A(C).concat(F):C.concat(F);
}return new Elements(C,{ddup:(H.length>1),cash:!G});}});Element.implement({match:function(B){if(!B){return true;}var D=Selectors.Utils.parseTagAndID(B);
var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true;
}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)["']?(.*?)["']?)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};
Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F];
}var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0;
if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"};
break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"};
break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E];
}var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[4],C=D[5],J=D[6];if(I){H.classes.push(I);
}else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B});
}}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null;
}return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false];
},filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length;
D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D];
if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=B.getElementById(D,true);
return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(J,I,O){var B=[];var C=I.trim().replace(Selectors.RegExps.splitter,function(Z,Y,X){B.push(Y);
return":)"+X;}).split(":)");var K,F,E,V;for(var U=0,Q=C.length;U<Q;U++){var T=C[U];if(U==0&&Selectors.RegExps.quick.test(T)){K=J.getElementsByTagName(T);
continue;}var A=B[U-1];var L=Selectors.Utils.parseTagAndID(T);var W=L[0],M=L[1];if(U==0){K=Selectors.Utils.getByTagAndID(J,W,M);}else{var D={},H=[];for(var S=0,R=K.length;
S<R;S++){H=Selectors.Getters[A](H,K[S],W,M,D);}K=H;}var G=Selectors.Utils.parseSelector(T);if(G){E=[];for(var P=0,N=K.length;P<N;P++){V=K[P];if(Selectors.Utils.filter(V,G,O)){E.push(V);
}}K=E;}}return K;}};Selectors.Getters={" ":function(H,G,I,A,E){var D=Selectors.Utils.getByTagAndID(G,I,A);for(var C=0,B=D.length;C<B;C++){var F=D[C];if(Selectors.Utils.chk(F,E)){H.push(F);
}}return H;},">":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;E<D;E++){var B=C[E];if(B.parentNode==G&&Selectors.Utils.chk(B,F)){H.push(B);
}}return H;},"+":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(Selectors.Utils.chk(B,D)&&Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}break;}}return C;},"~":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(!Selectors.Utils.chk(B,D)){break;}if(Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}}}return C;}};Selectors.Filters={byTag:function(B,A){return(A=="*"||(B.tagName&&B.tagName.toLowerCase()==A));},byID:function(A,B){return(!B||(A.id&&A.id==B));
},byClass:function(B,A){return(B.className&&B.className.contains(A," "));},byPseudo:function(A,D,C,B){return D.call(A,C,B);},byAttribute:function(C,D,B,E){var A=Element.prototype.getProperty.call(C,D);
if(!A){return false;}if(!B||E==undefined){return true;}switch(B){case"=":return(A==E);case"*=":return(A.contains(E));case"^=":return(A.substr(0,E.length)==E);
case"$=":return(A.substr(A.length-E.length)==E);case"!=":return(A!=E);case"~=":return A.contains(E," ");case"|=":return A.contains(E,"-");}return false;
}};Selectors.Pseudo=new Hash({empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(A){return !Element.match(this,A);},contains:function(A){return(this.innerText||this.textContent||"").contains(A);
},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
}}return true;},"only-child":function(){var B=this;while((B=B.previousSibling)){if(B.nodeType==1){return false;}}var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
}}return true;},"nth-child":function(G,E){G=(G==undefined)?"n":G;var C=Selectors.Utils.parseNthArgument(G);if(C.special!="n"){return Selectors.Pseudo[C.special].call(this,C.a,E);
}var F=0;E.positions=E.positions||{};var D=$uid(this);if(!E.positions[D]){var B=this;while((B=B.previousSibling)){if(B.nodeType!=1){continue;}F++;var A=E.positions[$uid(B)];
if(A!=undefined){F=A+F;break;}}E.positions[D]=F;}return(E.positions[D]%C.a==C.b);},index:function(A){var B=this,C=0;while((B=B.previousSibling)){if(B.nodeType==1&&++C>A){return false;
}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A);},odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);
}});Native.implement([Element,Document],{getElementsByClassName:function(A){return this.getElements("."+A);},getElementsBySelector:function(A){return this.getElements(A);
}});Elements.implement({filterByTag:function(A){return this.filterBy(A);},filterByClass:function(A){return this.filterBy("."+A);},filterById:function(A){return this.filterBy("#"+A);
},filterByAttribute:function(B,A,C){return this.filterBy("["+B+(A||"")+(C||"")+"]");}});var $E=function(A,B){return($(B)||document).getElement(A);};var $ES=function(A,B){return($(B)||document).getElements(A);
};Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this);}}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;
window.fireEvent("domready");document.fireEvent("domready");};switch(Browser.Engine.name){case"webkit":(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50);
})();break;case"trident":var A=document.createElement("div");(function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();
}))?B():arguments.callee.delay(50);})();break;default:window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}})();var JSON=new Hash({encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';
case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]";case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);
}});return"{"+A+"}";case"number":case"boolean":return String(B);case false:return"null";}return null;},$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16);
},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;
}return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Json=JSON;JSON.toString=JSON.encode;
JSON.evaluate=JSON.decode;var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B;
this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path;
}if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure";
}this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C);
};Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};Cookie.set=function(B,C,A){return new Cookie(B,A).write(C);
};Cookie.get=function(A){return new Cookie(A).read();};Cookie.remove=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={};
var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments);
};})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J='<object id="'+B+'"';for(var I in H){J+=" "+I+'="'+H[I]+'"';}J+=">";for(var C in E){J+='<param name="'+C+'" value="'+E[C]+'" />';
}J+="</object>";this.object=(A||new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A);
return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(A){return Swiff.remote(this.toElement(),A);}});Swiff.CallBacks={};
Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore",transition:function(A){return -(Math.cos(Math.PI*A)-1)/2;
}},initialize:function(A){this.subject=this.subject||this;this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();
var B=this.options.wait;if(B===false){this.options.link="cancel";}},step:function(){var A=$time();if(A<this.time+this.options.duration){var B=this.options.transition((A-this.time)/this.options.duration);
this.set(this.compute(this.from,this.to,B));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(A){return A;},compute:function(C,B,A){return Fx.compute(C,B,A);
},check:function(){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.start.bind(this,arguments));
return false;}return false;},start:function(B,A){if(!this.check(B,A)){return this;}this.from=B;this.to=A;this.time=0;this.startTimer();this.onStart();return this;
},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();}return this;},onStart:function(){this.fireEvent("onStart",this.subject);
},onComplete:function(){this.fireEvent("onComplete",this.subject);if(!this.callChain()){this.fireEvent("onChainComplete",this.subject);}},onCancel:function(){this.fireEvent("onCancel",this.subject).clearChain();
},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;
this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);
return true;}});Fx.compute=function(C,B,A){return(B-C)*A+C;};Fx.Durations={"short":250,normal:500,"long":1000};Fx.implement({custom:function(B,A){return this.start(B,A);
},clearTimer:function(){return this.cancel();},stop:function(){return this.cancel();}});Fx.Base=Fx;Fx.CSS=new Class({Extends:Fx,prepare:function(D,E,B){B=$splat(B);
var C=B[1];if(!$chk(C)){B[1]=B[0];B[0]=D.getStyle(E);}var A=B.map(this.parse);return{from:A[0],to:A[1]};},parse:function(A){A=$lambda(A)();A=(typeof A=="string")?A.split(" "):$splat(A);
return A.map(function(C){C=String(C);var B=false;Fx.CSS.Parsers.each(function(F,E){if(B){return ;}var D=F.parse(C);if($chk(D)){B={value:D,parser:F};}});
B=B||{value:C,parser:Fx.CSS.Parsers.String};return B;});},compute:function(D,C,B){var A=[];(Math.min(D.length,C.length)).times(function(E){A.push({value:D[E].parser.compute(D[E].value,C[E].value,B),parser:D[E].parser});
});A.$family={name:"fx:css:value"};return A;},serve:function(C,B){if($type(C)!="fx:css:value"){C=this.parse(C);}var A=[];C.each(function(D){A=A.concat(D.parser.serve(D.value,B));
});return A;},render:function(A,D,C,B){A.setStyle(D,this.serve(C,B));},search:function(A){var C={},B=document.domain;Array.each(document.styleSheets,function(F,E){var D=F.href;
if(D.match("://")&&!D.match(B)){return ;}var G=F.rules||F.cssRules;Array.each(G,function(I,H){if(!I.style||!I.selectorText||!I.selectorText.test("^"+A+"$")){return ;
}Element.Styles.each(function(K,J){if(!I.style[J]||Element.ShortStyles[J]){return ;}K=String(I.style[J]);C[J]=(K.test(/^rgb/))?K.rgbToHex():K;});});});
return C;}});Fx.CSS.Parsers=new Hash({Color:{parse:function(A){if(A.match(/^#[0-9a-f]{3,6}$/i)){return A.hexToRgb(true);}return((A=A.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[A[1],A[2],A[3]]:false;
},compute:function(C,B,A){return C.map(function(E,D){return Math.round(Fx.compute(C[D],B[D],A));});},serve:function(A){return A.map(Number);}},Number:{parse:function(A){return parseFloat(A);
},compute:function(C,B,A){return Fx.compute(C,B,A);},serve:function(B,A){return(A)?B+A:B;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});
Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);arguments.callee.parent(A);},set:function(B,A){if(arguments.length==1){A=B;
B=this.property||this.options.property;}this.render(this.element,B,A,this.options.unit);return this;},start:function(C,E,D){if(!this.check(C,E,D)){return this;
}var B=Array.flatten(arguments);this.property=this.options.property||B.shift();var A=this.prepare(this.element,this.property,B);return arguments.callee.parent(A.from,A.to);
}});Element.Properties.tween={set:function(A){var B=this.retrieve("tween");if(B){B.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("tween")){if(A||!this.retrieve("tween:options")){this.set("tween",A);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));
}return this.retrieve("tween");}};Element.implement({tween:function(A,C,B){this.get("tween").start(arguments);return this;},fade:function(C){var E=this.get("tween"),D="opacity",A;
C=$pick(C,"toggle");switch(C){case"in":E.start(D,1);break;case"out":E.start(D,0);break;case"show":E.set(D,1);break;case"hide":E.set(D,0);break;case"toggle":var B=this.retrieve("fade:flag",this.get("opacity")==1);
E.start(D,(B)?0:1);this.store("fade:flag",!B);A=true;break;default:E.start(D,arguments);}if(!A){this.eliminate("fade:flag");}return this;},highlight:function(C,A){if(!A){A=this.retrieve("highlight:original",this.getStyle("background-color"));
A=(A=="transparent")?"#fff":A;}var B=this.get("tween");B.start("background-color",C||"#ffff88",A).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
B.callChain();}.bind(this));return this;}});Fx.Style=function(B,C,A){return new Fx.Tween(B,$extend({property:C},A));};Element.implement({effect:function(B,A){return new Fx.Tween(this,$extend({property:B},A));
}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);arguments.callee.parent(A);},set:function(A){if(typeof A=="string"){A=this.search(A);
}for(var B in A){this.render(this.element,B,A[B],this.options.unit);}return this;},compute:function(E,D,C){var A={};for(var B in E){A[B]=arguments.callee.parent(E[B],D[B],C);
}return A;},start:function(B){if(!this.check(B)){return this;}if(typeof B=="string"){B=this.search(B);}var E={},D={};for(var C in B){var A=this.prepare(this.element,C,B[C]);
E[C]=A.from;D[C]=A.to;}return arguments.callee.parent(E,D);}});Element.Properties.morph={set:function(A){var B=this.retrieve("morph");if(B){B.cancel();
}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},A));},get:function(A){if(A||!this.retrieve("morph")){if(A||!this.retrieve("morph:options")){this.set("morph",A);
}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));}return this.retrieve("morph");}};Element.implement({morph:function(A){this.get("morph").start(A);
return this;}});Fx.Styles=Fx.Morph;Element.implement({effects:function(A){return new Fx.Morph(this,A);}});(function(){var A=Fx.prototype.initialize;Fx.prototype.initialize=function(B){A.call(this,B);
var C=this.options.transition;if(typeof C=="string"&&(C=C.split(":"))){var D=Fx.Transitions;D=D[C[0]]||D[C[0].capitalize()];if(C[1]){D=D["ease"+C[1].capitalize()+(C[2]?C[2].capitalize():"")];
}this.options.transition=D;}};})();Fx.Transition=function(B,A){A=$splat(A);return $extend(B,{easeIn:function(C){return B(C,A);},easeOut:function(C){return 1-B(1-C,A);
},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;}});};Fx.Transitions=new Hash({linear:$arguments(0)});Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);
}};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));
},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;
1;B+=A,A/=2){if(D>=(7-4*B)/11){C=-Math.pow((11-6*B-11*D)/4,2)+A*A;break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);
}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request();
this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ;
}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};
this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300));
},processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts);
},success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("onComplete",arguments).fireEvent("onSuccess",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("onComplete").fireEvent("onFailure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B);
return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.send.bind(this,arguments));return false;}return false;},send:function(D){if(!this.check(D)){return this;
}this.running=true;var E=$type(D);if(E=="string"||E=="element"){D={data:D};}var A=this.options;D=$extend({data:A.data,url:A.url,method:A.method},D);var G=D.data,C=D.url,H=D.method;
switch($type(G)){case"element":G=$(G).toQueryString();break;case"object":case"hash":G=Hash.toQueryString(G);}if(this.options.emulation&&["put","delete"].contains(H)){var B="_method="+H;
G=(G)?B+"&"+G:B;H="post";}if(this.options.urlEncoded&&H=="post"){var F=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+F);
}if(G&&H=="get"){C=C+(C.contains("?")?"&":"?")+G;G=null;}this.xhr.open(H.toUpperCase(),C,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);
this.headers.each(function(J,I){if(!$try(function(){this.xhr.setRequestHeader(I,J);return true;}.bind(this))){this.fireEvent("onException",[e,I,J]);}},this);
this.fireEvent("onRequest");this.xhr.send(G);if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;
}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;this.xhr=new Browser.Request();this.fireEvent("onCancel");return this;}});(function(){var A={};
["get","post","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined});return this.send($extend(C,{method:B.toLowerCase()}));
};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send");if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A));
},get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options")));
}return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Object.toQueryString=Hash.toQueryString;
var XHR=new Class({Extends:Request,options:{update:false},initialize:function(B,A){arguments.callee.parent(A);this.url=B;},request:function(A){return this.send(this.url,A||this.options.data);
},send:function(A,B){if(!this.check(A,B)){return this;}return arguments.callee.parent({url:A,data:B});},success:function(B,A){B=this.processScripts(B);
if(this.options.update){$(this.options.update).empty().set("html",B);}this.onSuccess(B,A);},failure:function(){this.fireEvent("onFailure",this.xhr);}});
var Ajax=XHR;Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D="<root>"+C+"</root>",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM");
G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length;
F<E;F++){var H=Element.clone(D.childNodes[F],true,true);if(H){A.grab(H);}}return A;})||A.set("html",C);},success:function(D){var C=this.options,B=this.response;
B.html=D.stripScripts(function(E){B.javascript=E;});var A=this.processHTML(B.html);B.tree=A.childNodes;B.elements=A.getElements("*");if(C.filter){B.tree=B.elements.filterBy(C.filter);
}if(C.update){$(C.update).empty().adopt(B.tree);}if(C.evalScripts){$exec(B.javascript);}this.onSuccess(B.tree,B.elements,B.html,B.javascript);}});Element.Properties.load={set:function(A){var B=this.retrieve("load");
if(B){send.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},A));},get:function(A){if(A||!this.retrieve("load")){if(A||!this.retrieve("load:options")){this.set("load",A);
}this.store("load",new Request.HTML(this.retrieve("load:options")));}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));
return this;}});Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(A){arguments.callee.parent(A);this.headers.extend({Accept:"application/json","X-Request":"JSON"});
},success:function(A){this.response.json=JSON.decode(A,this.options.secure);this.onSuccess(this.response.json,A);}});JSON.Remote=new Class({options:{key:"json"},Extends:Request.JSON,initialize:function(B,A){arguments.callee.parent(A);
this.onComplete=$empty;this.url=B;},send:function(A){if(!this.check(A)){return this;}return arguments.callee.parent({url:this.url,data:{json:Json.encode(A)}});
},failure:function(){this.fireEvent("onFailure",this.xhr);}});Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical"},initialize:function(B,A){this.addEvent("onComplete",function(){this.open=(this.wrapper["offset"+this.layout.capitalize()]!=0);
if(this.open&&Browser.Engine.webkit419){this.element.dispose().inject(this.wrapper);}},true);this.element=this.subject=$(B);arguments.callee.parent(A);
var C=this.element.retrieve("wrapper");this.wrapper=C||new Element("div",{styles:$extend(this.element.getStyles("margin","position"),{overflow:"hidden"})}).wraps(this.element);
this.element.store("wrapper",this.wrapper).setStyle("margin",0);this.now=[];this.open=true;},vertical:function(){this.margin="margin-top";this.layout="height";
this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";this.layout="width";this.offset=this.element.offsetWidth;},set:function(A){this.element.setStyle(this.margin,A[0]);
this.wrapper.setStyle(this.layout,A[1]);return this;},compute:function(D,C,B){var A=[];(2).times(function(E){A[E]=Fx.compute(D[E],C[E],B);});return A;},start:function(B,E){if(!this.check(B,E)){return this;
}this[E||this.options.mode]();var D=this.element.getStyle(this.margin).toInt();var C=this.wrapper.getStyle(this.layout).toInt();var A=[[D,C],[0,this.offset]];
var G=[[D,C],[-this.offset,0]];var F;switch(B){case"in":F=A;break;case"out":F=G;break;case"toggle":F=(this.wrapper["offset"+this.layout.capitalize()]==0)?A:G;
}return arguments.callee.parent(F[0],F[1]);},slideIn:function(A){return this.start("in",A);},slideOut:function(A){return this.start("out",A);},hide:function(A){this[A||this.options.mode]();
this.open=false;return this.set([-this.offset,0]);},show:function(A){this[A||this.options.mode]();this.open=true;return this.set([0,this.offset]);},toggle:function(A){return this.start("toggle",A);
}});Element.Properties.slide={set:function(B){var A=this.retrieve("slide");if(A){A.cancel();}return this.eliminate("slide").store("slide:options",$extend({link:"cancel"},B));
},get:function(A){if(A||!this.retrieve("slide")){if(A||!this.retrieve("slide:options")){this.set("slide",A);}this.store("slide",new Fx.Slide(this,this.retrieve("slide:options")));
}return this.retrieve("slide");}};Element.implement({slide:function(D,E){D=D||"toggle";var B=this.get("slide"),A;switch(D){case"hide":B.hide(E);break;case"show":B.show(E);
break;case"toggle":var C=this.retrieve("slide:flag",B.open);B[(C)?"slideOut":"slideIn"](E);this.store("slide:flag",!C);A=true;break;default:B.start(D,E);
}if(!A){this.eliminate("slide:flag");}return this;}});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(B,A){this.element=this.subject=$(B);
arguments.callee.parent(A);var D=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=$(this.element.getDocument().body);}var C=this.element;
if(this.options.wheelStops){this.addEvent("onStart",function(){C.addEvent("mousewheel",D);},true);this.addEvent("onComplete",function(){C.removeEvent("mousewheel",D);
},true);}},set:function(){var A=Array.flatten(arguments);this.element.scrollTo(A[0],A[1]);},compute:function(D,C,B){var A=[];(2).times(function(E){A.push(Fx.compute(D[E],C[E],B));
});return A;},start:function(C,H){if(!this.check(C,H)){return this;}var E=this.element.getSize(),F=this.element.getScrollSize(),B=this.element.getScroll(),D={x:C,y:H};
for(var G in D){var A=F[G]-E[G];if($chk(D[G])){D[G]=($type(D[G])=="number")?D[G].limit(0,A):A;}else{D[G]=B[G];}D[G]+=this.options.offset[G];}return arguments.callee.parent([B.x,B.y],[D.x,D.y]);
},toTop:function(){return this.start(false,0);},toLeft:function(){return this.start(0,false);},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom");
},toElement:function(B){var A=$(B).getPosition(this.element);return this.start(A.x,A.y);}});Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(B,A){this.elements=this.subject=$$(B);
arguments.callee.parent(A);},compute:function(G,H,I){var C={};for(var D in G){var A=G[D],E=H[D],F=C[D]={};for(var B in A){F[B]=arguments.callee.parent(A[B],E[B],I);
}}return C;},set:function(B){for(var C in B){var A=B[C];for(var D in A){this.render(this.elements[C],D,A[D],this.options.unit);}}return this;},start:function(C){if(!this.check(C)){return this;
}var H={},I={};for(var D in C){var F=C[D],A=H[D]={},G=I[D]={};for(var B in F){var E=this.prepare(this.elements[D],B,F[B]);A[B]=E.from;G[B]=E.to;}}return arguments.callee.parent(H,I);
}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,modifiers:{x:"left",y:"top"}},initialize:function(){var B=Array.link(arguments,{options:Object.type,element:$defined});
this.element=$(B.element);this.document=this.element.getDocument();this.setOptions(B.options||{});var A=$type(this.options.handle);this.handles=(A=="array"||A=="collection")?$$(this.options.handle):$(this.options.handle)||this.element;
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
return this;},start:function(C){this.fireEvent("onBeforeStart",this.element);this.mouse.start=C.page;var A=this.options.limit;this.limit={x:[],y:[]};for(var D in this.options.modifiers){if(!this.options.modifiers[D]){continue;
}if(this.options.style){this.value.now[D]=this.element.getStyle(this.options.modifiers[D]).toInt();}else{this.value.now[D]=this.element[this.options.modifiers[D]];
}if(this.options.invert){this.value.now[D]*=-1;}this.mouse.pos[D]=C.page[D]-this.value.now[D];if(A&&A[D]){for(var B=2;B--;B){if($chk(A[D][B])){this.limit[D][B]=$lambda(A[D][B])();
}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});
this.document.addEvent(this.selection,this.bound.eventStop);},check:function(A){var B=Math.round(Math.sqrt(Math.pow(A.page.x-this.mouse.start.x,2)+Math.pow(A.page.y-this.mouse.start.y,2)));
if(B>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("onStart",this.element).fireEvent("onSnap",this.element);
}},drag:function(A){this.mouse.now=A.page;for(var B in this.options.modifiers){if(!this.options.modifiers[B]){continue;}this.value.now[B]=this.mouse.now[B]-this.mouse.pos[B];
if(this.options.invert){this.value.now[B]*=-1;}if(this.options.limit&&this.limit[B]){if($chk(this.limit[B][1])&&(this.value.now[B]>this.limit[B][1])){this.value.now[B]=this.limit[B][1];
}else{if($chk(this.limit[B][0])&&(this.value.now[B]<this.limit[B][0])){this.value.now[B]=this.limit[B][0];}}}if(this.options.grid[B]){this.value.now[B]-=(this.value.now[B]%this.options.grid[B]);
}if(this.options.style){this.element.setStyle(this.options.modifiers[B],this.value.now[B]+this.options.unit);}else{this.element[this.options.modifiers[B]]=this.value.now[B];
}}this.fireEvent("onDrag",this.element);},cancel:function(A){this.document.removeEvent("mousemove",this.bound.check);this.document.removeEvent("mouseup",this.bound.cancel);
if(A){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("onCancel",this.element);}},stop:function(A){this.document.removeEvent(this.selection,this.bound.eventStop);
this.document.removeEvent("mousemove",this.bound.drag);this.document.removeEvent("mouseup",this.bound.stop);if(A){this.fireEvent("onComplete",this.element);
}}});Element.implement({makeResizable:function(A){return new Drag(this,$merge({modifiers:{x:"width",y:"height"}},A));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false},initialize:function(C,B){arguments.callee.parent(C,B);
this.droppables=$$(this.options.droppables);this.container=$(this.options.container);var A=(this.element.positioned())?this.element.getStyle("position"):"absolute";
if(this.element.getStyle("left")=="auto"||this.element.getStyle("top")=="auto"){this.element.position(this.element.getRelativePosition());}this.element.setStyle("position",A);
},start:function(B){if(this.overed){this.overed.fireEvent("leave",[this.element,this]);this.overed=null;}if(this.container){var D=this.element,J=this.container,E=J.getCoordinates(D.getOffsetParent()),F={},A={};
["top","right","bottom","left"].each(function(K){F[K]=J.getStyle("padding-"+K).toInt();A[K]=D.getStyle("margin-"+K).toInt();},this);var C=D.offsetWidth+A.left+A.right,I=D.offsetHeight+A.top+A.bottom;
var H=[E.left+F.left,E.right-F.right-C];var G=[E.top+F.top,E.bottom-F.bottom-I];this.options.limit={x:H,y:G};}arguments.callee.parent(B);},checkAgainst:function(B){B=B.getCoordinates();
var A=this.mouse.now;return(A.x>B.left&&A.x<B.right&&A.y<B.bottom&&A.y>B.top);},checkDroppables:function(){var A=this.droppables.filter(this.checkAgainst,this).getLast();
if(this.overed!=A){if(this.overed){this.overed.fireEvent("leave",[this.element,this]);}this.overed=A?A.fireEvent("over",[this.element,this]):null;}},drag:function(A){arguments.callee.parent(A);
if(this.droppables.length){this.checkDroppables();}},stop:function(A){this.checkDroppables();if(this.overed){this.overed.fireEvent("drop",[this.element,this]);
}else{this.element.fireEvent("emptydrop",this);}return arguments.callee.parent(A);}});Element.implement({makeDraggable:function(A){return new Drag.Move(this,A);
}});var Color=new Native({initialize:function(B,C){if(arguments.length>=3){C="rgb";B=Array.slice(arguments,0,3);}else{if(typeof B=="string"){if(B.match(/rgb/)){B=B.rgbToHex().hexToRgb(true);
}else{if(B.match(/hsb/)){B=B.hsbToRgb();}else{B=B.hexToRgb(true);}}}}C=C||"rgb";switch(C){case"hsb":var A=B;B=B.hsbToRgb();B.hsb=A;break;case"hex":B=B.hexToRgb(true);
break;}B.rgb=B.slice(0,3);B.hsb=B.hsb||B.rgbToHsb();B.hex=B.rgbToHex();return $extend(B,this);}});Color.implement({mix:function(){var A=Array.slice(arguments);
var C=($type(A.getLast())=="number")?A.pop():50;var B=this.slice();A.each(function(D){D=new Color(D);for(var E=0;E<3;E++){B[E]=Math.round((B[E]/100*(100-C))+(D[E]/100*C));
}});return new Color(B,"rgb");},invert:function(){return new Color(this.map(function(A){return 255-A;}));},setHue:function(A){return new Color([A,this.hsb[1],this.hsb[2]],"hsb");
},setSaturation:function(A){return new Color([this.hsb[0],A,this.hsb[2]],"hsb");},setBrightness:function(A){return new Color([this.hsb[0],this.hsb[1],A],"hsb");
}});function $RGB(C,B,A){return new Color([C,B,A],"rgb");}function $HSB(C,B,A){return new Color([C,B,A],"hsb");}function $HEX(A){return new Color(A,"hex");
}Array.implement({rgbToHsb:function(){var B=this[0],C=this[1],J=this[2];var G,F,H;var I=Math.max(B,C,J),E=Math.min(B,C,J);var K=I-E;H=I/255;F=(I!=0)?K/I:0;
if(F==0){G=0;}else{var D=(I-B)/K;var A=(I-C)/K;var L=(I-J)/K;if(B==I){G=L-A;}else{if(C==I){G=2+D-L;}else{G=4+A-D;}}G/=6;if(G<0){G++;}}return[Math.round(G*360),Math.round(F*100),Math.round(H*100)];
},hsbToRgb:function(){var C=Math.round(this[2]/100*255);if(this[1]==0){return[C,C,C];}else{var A=this[0]%360;var E=A%60;var F=Math.round((this[2]*(100-this[1]))/10000*255);
var D=Math.round((this[2]*(6000-this[1]*E))/600000*255);var B=Math.round((this[2]*(6000-this[1]*(60-E)))/600000*255);switch(Math.floor(A/60)){case 0:return[C,B,F];
case 1:return[D,C,F];case 2:return[F,C,B];case 3:return[F,D,C];case 4:return[B,F,C];case 5:return[C,F,D];}}return false;}});String.implement({rgbToHsb:function(){var A=this.match(/\d{1,3}/g);
return(A)?hsb.rgbToHsb():null;},hsbToRgb:function(){var A=this.match(/\d{1,3}/g);return(A)?A.hsbToRgb():null;}});var Group=new Class({initialize:function(){this.instances=Array.flatten(arguments);
this.events={};this.checker={};},addEvent:function(B,A){this.checker[B]=this.checker[B]||{};this.events[B]=this.events[B]||[];if(this.events[B].contains(A)){return false;
}else{this.events[B].push(A);}this.instances.each(function(C,D){C.addEvent(B,this.check.bind(this,[B,C,D]));},this);return this;},check:function(C,A,B){this.checker[C][B]=true;
var D=this.instances.every(function(F,E){return this.checker[C][E]||false;},this);if(!D){return ;}this.checker[C]={};this.events[C].each(function(E){E.call(this,this.instances,A);
},this);}});Hash.Cookie=new Class({Extends:Cookie,options:{autoSave:true},initialize:function(B,A){this.parent(B,A);this.load();},save:function(){var A=JSON.encode(this.hash);
if(!A||A.length>4096){return false;}if(A=="{}"){this.dispose();}else{this.write(A);}return true;},load:function(){this.hash=new Hash(JSON.decode(this.read(),true));
return this;}});Hash.Cookie.implement((function(){var A={};Hash.each(Hash.prototype,function(C,B){A[B]=function(){var D=C.apply(this.hash,arguments);if(this.options.autoSave){this.save();
}return D;};});return A;})());var Sortables=new Class({Implements:[Events,Options],options:{snap:4,handle:false,revert:false,constrain:false,cloneOpacity:0.7,elementOpacity:0.3},initialize:function(A,B){this.setOptions(B);
this.elements=[];this.lists=[];this.idle=true;this.addLists($$($(A)||A));if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert));
}},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(A){this.elements.push(A);
var C=A.retrieve("sortables:start",this.start.bindWithEvent(this,A));var B=A.retrieve("sortables:insert",this.insert.bind(this,A));(this.options.handle?A.getElement(this.options.handle)||A:A).addEvent("mousedown",C);
A.addEvent("over",B);},this);return this;},addLists:function(){Array.flatten(arguments).each(function(A){this.lists.push(A);this.addItems(A.getChildren());
A.addEvent("over",A.retrieve("sortables:insert",this.insert.bind(this,[A,"inside"])));},this);return this;},removeItems:function(){var A=[];Array.flatten(arguments).each(function(B){A.push(B);
this.elements.erase(B);var D=B.retrieve("sortables:start");var C=B.retrieve("sortables:insert");(this.options.handle?B.getElement(this.options.handle)||B:B).removeEvent("mousedown",D);
B.removeEvent("over",C);},this);return A;},removeLists:function(){var A=[];Array.flatten(arguments).each(function(B){A.push(B);this.lists.erase(B);this.removeItems(B.getChildren());
B.removeEvent("over",B.retrieve("sortables:insert"));},this);return A;},getClone:function(A){return A.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden"}).inject(this.list).position(A.getRelativePosition());
},getDroppables:function(){var A=this.list.getChildren();if(!this.options.constrain){A=this.lists.concat(A).erase(this.list);}return A.erase(this.clone).erase(this.element);
},insert:function(B,A){if(A){this.list=B;this.drag.droppables=this.getDroppables();}A=A||(this.element.getAllPrevious().contains(B)?"before":"after");this.element.inject(B,A);
this.fireEvent("onSort",[this.element,this.clone]);},start:function(B,A){if(!this.idle){return ;}this.idle=false;this.element=A;this.opacity=A.get("opacity");
this.list=A.getParent();this.clone=this.getClone(A);this.drag=this.clone.makeDraggable({snap:this.options.snap,container:this.options.constrain&&this.clone.getParent(),droppables:this.getDroppables(),onStart:function(){B.stop();
this.clone.set("opacity",this.options.cloneOpacity);this.element.set("opacity",this.options.elementOpacity);this.fireEvent("onStart",[this.element,this.clone]);
}.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});this.drag.start(B);},end:function(){this.element.set("opacity",this.opacity);
this.drag.detach();if(this.effect){var A=this.element.getStyles("width","height");var B=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent),this.clone.getParent().positioned());
this.effect.element=this.clone;this.effect.start({top:B.top,left:B.left,width:A.width,height:A.height,opacity:0.25}).chain(this.reset.bind(this));}else{this.reset();
}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("onComplete",this.element);},serialize:function(C,A){var B=this.lists.map(function(D){return D.getChildren().map(A||function(F,E){return F.get("id");
},this);},this);if(this.lists.length==1){C=0;}return $chk(C)&&C>=0&&C<this.lists.length?B[C]:B;}});var Tips=new Class({Implements:[Events,Options],options:{onShow:function(A){A.setStyle("visibility","visible");
},onHide:function(A){A.setStyle("visibility","hidden");},maxTitleChars:30,showDelay:100,hideDelay:100,className:null,offsets:{x:16,y:16},fixed:false},initialize:function(){var C=Array.link(arguments,{options:Object.type,elements:$defined});
this.setOptions(C.options);this.tip=new Element("div").inject(document.body);if(this.options.className){this.tip.addClass(this.options.className);}var B=new Element("div",{"class":"tip-top"}).inject(this.tip);
this.container=new Element("div",{"class":"tip"}).inject(this.tip);var A=new Element("div",{"class":"tip-bottom"}).inject(this.tip);this.tip.setStyles({position:"absolute",top:0,left:0,visibility:"hidden"});
if(C.elements){this.attach(C.elements);}},attach:function(A){$$(A).each(function(D){var G=D.retrieve("tip:title",D.get("title"));var F=D.retrieve("tip:text",D.get("rel")||D.get("href"));
var E=D.retrieve("tip:enter",this.elementEnter.bindWithEvent(this,D));var C=D.retrieve("tip:leave",this.elementLeave.bindWithEvent(this,D));D.addEvents({mouseenter:E,mouseleave:C});
if(!this.options.fixed){var B=D.retrieve("tip:move",this.elementMove.bindWithEvent(this,D));D.addEvent("mousemove",B);}D.store("tip:native",D.get("title"));
D.erase("title");},this);return this;},detach:function(A){$$(A).each(function(C){C.removeEvent("mouseenter",C.retrieve("tip:enter")||$empty);C.removeEvent("mouseleave",C.retrieve("tip:leave")||$empty);
C.removeEvent("mouseleave",C.retrieve("tip:move")||$empty);C.eliminate("tip:enter").eliminate("tip:leave").eliminate("tip:move");var B=C.retrieve("tip:native");
if(B){C.set("title",B);}});return this;},elementEnter:function(B,A){this.container.empty();var D=A.retrieve("tip:title");if(D){this.titleElement=new Element("div",{"class":"tip-title"}).inject(this.container);
this.fill(this.titleElement,D);}var C=A.retrieve("tip:text");if(C){this.textElement=new Element("div",{"class":"tip-text"}).inject(this.container);this.fill(this.textElement,C);
}this.timer=$clear(this.timer);this.timer=this.show.delay(this.options.showDelay,this);this.position((!this.options.fixed)?B:{page:A.getPosition()});},elementLeave:function(A){$clear(this.timer);
this.timer=this.hide.delay(this.options.hideDelay,this);},elementMove:function(A){this.position(A);},position:function(D){var B=window.getSize(),A=window.getScroll();
var E={x:this.tip.offsetWidth,y:this.tip.offsetHeight};var C={x:"left",y:"top"};for(var F in C){var G=D.page[F]+this.options.offsets[F];if((G+E[F]-A[F])>B[F]){G=D.page[F]-this.options.offsets[F]-E[F];
}this.tip.setStyle(C[F],G);}},fill:function(A,B){(typeof B=="string")?A.set("html",B):A.adopt(B);},show:function(){this.fireEvent("onShow",this.tip);},hide:function(){this.fireEvent("onHide",this.tip);
}});var SmoothScroll=new Class({Extends:Fx.Scroll,initialize:function(B,C){C=C||document;var E=C.getDocument(),D=C.getWindow();arguments.callee.parent(E,B);
this.links=(this.options.links)?$$(this.options.links):$$(E.links);var A=D.location.href.match(/^[^#]*/)[0]+"#";this.links.each(function(G){if(G.href.indexOf(A)!=0){return ;
}var F=G.href.substr(A.length);if(F&&$(F)){this.useLink(G,F);}},this);if(!Browser.Engine.webkit419){this.addEvent("onComplete",function(){D.location.hash=this.anchor;
},true);}},useLink:function(B,A){B.addEvent("click",function(C){this.anchor=A;this.toElement(A);C.stop();}.bind(this));}});var Slider=new Class({Implements:[Events,Options],options:{onTick:function(A){if(this.options.snap){A=this.toPosition(this.step);
}this.knob.setStyle(this.property,A);},snap:false,offset:0,range:false,wheel:false,steps:100,mode:"horizontal"},initialize:function(E,A,D){this.setOptions(D);
this.element=$(E);this.knob=$(A);this.previousChange=this.previousEnd=this.step=-1;this.element.addEvent("mousedown",this.clickedElement.bind(this));if(this.options.wheel){this.element.addEvent("mousewheel",this.scrolledElement.bindWithEvent(this));
}var F,B={},C={x:false,y:false};switch(this.options.mode){case"vertical":this.axis="y";this.property="top";F="offsetHeight";break;case"horizontal":this.axis="x";
this.property="left";F="offsetWidth";}this.half=this.knob[F]/2;this.full=this.element[F]-this.knob[F]+(this.options.offset*2);this.min=$chk(this.options.range[0])?this.options.range[0]:0;
this.max=$chk(this.options.range[1])?this.options.range[1]:this.options.steps;this.range=this.max-this.min;this.steps=this.options.steps||this.full;this.stepSize=Math.abs(this.range)/this.steps;
this.stepWidth=this.stepSize*this.full/Math.abs(this.range);this.knob.setStyle("position","relative").setStyle(this.property,-this.options.offset);C[this.axis]=this.property;
B[this.axis]=[-this.options.offset,this.full-this.options.offset];this.drag=new Drag(this.knob,{snap:0,limit:B,modifiers:C,onDrag:this.draggedKnob.bind(this),onStart:this.draggedKnob.bind(this),onComplete:function(){this.draggedKnob();
this.end();}.bind(this)});if(this.options.snap){this.drag.options.grid=Math.ceil(this.stepWidth);this.drag.options.limit[this.axis][1]=this.full;}},set:function(A){if(!((this.range>0)^(A<this.min))){A=this.min;
}if(!((this.range>0)^(A>this.max))){A=this.max;}this.step=Math.round(A);this.checkStep();this.end();this.fireEvent("onTick",this.toPosition(this.step));
return this;},clickedElement:function(C){var B=this.range<0?-1:1;var A=C.page[this.axis]-this.element.getPosition()[this.axis]-this.half;A=A.limit(-this.options.offset,this.full-this.options.offset);
this.step=Math.round(this.min+B*this.toStep(A));this.checkStep();this.end();this.fireEvent("onTick",A);},scrolledElement:function(A){var B=(this.options.mode=="horizontal")?(A.wheel<0):(A.wheel>0);
this.set(B?this.step-this.stepSize:this.step+this.stepSize);A.stop();},draggedKnob:function(){var B=this.range<0?-1:1;var A=this.drag.value.now[this.axis];
A=A.limit(-this.options.offset,this.full-this.options.offset);this.step=Math.round(this.min+B*this.toStep(A));this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;
this.fireEvent("onChange",this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("onComplete",this.step+"");
}},toStep:function(A){var B=(A+this.options.offset)*this.stepSize/this.full*this.steps;return this.options.steps?Math.round(B-=B%this.stepSize):B;},toPosition:function(A){return(this.full*Math.abs(this.min-A))/(this.steps*this.stepSize)-this.options.offset;
}});var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(A,B){this.element.scrollTo(A,B);}},initialize:function(B,A){this.setOptions(A);
this.element=$(B);this.listener=($type(this.element)!="element")?$(this.element.getDocument().body):this.element;this.timer=null;},start:function(){this.coord=this.getCoords.bind(this);
this.listener.addEvent("mousemove",this.coord);},stop:function(){this.listener.removeEvent("mousemove",this.coord);this.timer=$clear(this.timer);},getCoords:function(A){this.page=(this.listener.get("tag")=="body")?A.client:A.page;
if(!this.timer){this.timer=this.scroll.periodical(50,this);}},scroll:function(){var B=this.element.getSize(),A=this.element.getScroll(),E=this.element.getPosition(),D={x:0,y:0};
for(var C in this.page){if(this.page[C]<(this.options.area+E[C])&&A[C]!=0){D[C]=(this.page[C]-this.options.area-E[C])*this.options.velocity;}else{if(this.page[C]+this.options.area>(B[C]+E[C])&&B[C]+B[C]!=A[C]){D[C]=(this.page[C]-B[C]+this.options.area-E[C])*this.options.velocity;
}}}if(D.y||D.x){this.fireEvent("onChange",[A.x+D.x,A.y+D.y]);}}});var Asset=new Hash({javascript:function(F,D){D=$extend({onload:$empty,document:document,check:$lambda(true)},D);
var B=new Element("script",{src:F,type:"text/javascript"});var E=D.onload.bind(B),A=D.check,G=D.document;delete D.onload;delete D.check;delete D.document;
B.addEvents({load:E,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){E();}}}).setProperties(D);if(Browser.Engine.webkit419){var C=(function(){if(!$try(A)){return ;
}$clear(C);E();}).periodical(50);}return B.inject(G.head);},css:function(B,A){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:B},A)).inject(document.head);
},image:function(C,B){B=$merge({onload:$empty,onabort:$empty,onerror:$empty},B);var D=new Image();var A=$(D)||new Element("img");["load","abort","error"].each(function(E){var F="on"+E;
var G=B[F];delete B[F];D[F]=function(){if(!D){return ;}if(!A.parentNode){A.width=D.width;A.height=D.height;}D=D.onload=D.onabort=D.onerror=null;G.delay(1,A,A);
A.fireEvent(E,A,1);};});D.src=A.src=C;if(D&&D.complete){D.onload.delay(1);}return A.setProperties(B);},images:function(D,C){C=$merge({onComplete:$empty,onProgress:$empty},C);
if(!D.push){D=[D];}var A=[];var B=0;D.each(function(F){var E=new Asset.image(F,{onload:function(){C.onProgress.call(this,B,D.indexOf(F));B++;if(B==D.length){C.onComplete();
}}});A.push(E);});return new Elements(A);}});var Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,fixedHeight:false,fixedWidth:false,wait:false,alwaysHide:false},initialize:function(){var C=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined});
arguments.callee.parent(C.elements,C.options);this.togglers=$$(C.togglers);this.container=$(C.container);this.previous=-1;if(this.options.alwaysHide){this.options.wait=true;
}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;
}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";
}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var B=0,A=this.togglers.length;B<A;B++){this.addSection(this.togglers[B],this.elements[B]);
}this.elements.each(function(E,D){if(this.options.show===D){this.fireEvent("onActive",[this.togglers[D],E]);}else{for(var F in this.effects){E.setStyle(F,0);
}}},this);if($chk(this.options.display)){this.display(this.options.display);}},addSection:function(E,C,G){E=$(E);C=$(C);var F=this.togglers.contains(E);
var B=this.togglers.length;this.togglers.include(E);this.elements.include(C);if(B&&(!F||G)){G=$pick(G,B-1);E.inject(this.togglers[G],"before");C.inject(E,"after");
}else{if(this.container&&!F){E.inject(this.container);C.inject(this.container);}}var A=this.togglers.indexOf(E);E.addEvent("click",this.display.bind(this,A));
if(this.options.height){C.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(this.options.width){C.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
}C.fullOpacity=1;if(this.options.fixedWidth){C.fullWidth=this.options.fixedWidth;}if(this.options.fixedHeight){C.fullHeight=this.options.fixedHeight;}C.setStyle("overflow","hidden");
if(!F){for(var D in this.effects){C.setStyle(D,0);}}return this;},display:function(A){A=($type(A)=="element")?this.elements.indexOf(A):A;if((this.timer&&this.options.wait)||(A===this.previous&&!this.options.alwaysHide)){return this;
}this.previous=A;var B={};this.elements.each(function(E,D){B[D]={};var C=(D!=A)||(this.options.alwaysHide&&(E.offsetHeight>0));this.fireEvent(C?"onBackground":"onActive",[this.togglers[D],E]);
for(var F in this.effects){B[D][F]=C?0:E[this.effects[F]];}},this);return this.start(B);}});


/* -----------------------------------------------------------------

	Script: 
		mocha.js version 0.8
	
	Copyright:
		Copyright (c) 2007-2008 Greg Houston, <http://greghoustondesign.com/>
	
	License:
		MIT-style license

	Contributors:
		Scott F. Frederick
		Joel Lindau
	
   ----------------------------------------------------------------- */

var MochaUI = new Class({
	options: {
		// Global options for windows:
		// Some of these options can be overriden for individual windows in newWindow()
		resizable:         true,
		draggable:         true,
		minimizable:       true,  // Requires dock
		maximizable:       true,  // Requires desktop
		closable:          true,
		effects:           true,  // Toggles the majority of window fade and move effects
		minWidth:          250,   // Minimum width of windows when resized
		maxWidth:          2500,  // Maximum width of windows when resized
		minHeight:         100,	  // Minimum height of windows when resized	
		maxHeight:         2000,  // Maximum height of windows when resized
		// Style options:
		headerHeight:      25,    // Height of window titlebar	
		footerHeight:      26, 		
		cornerRadius:      9,
		bodyBgColor:	   '#fff',           // Body background color - Hex			
		headerStartColor:  [250, 250, 250],  // Header gradient's top color - RGB
		headerStopColor:   [228, 228, 228],  // Header gradient's bottom color	
		footerBgColor:     [246, 246, 246],	 // Background color of the main canvas shape
		minimizeColor:     [231, 231, 209],  // Minimize button color
		maximizeColor:     [217, 229, 217],  // Maximize button color
		closeColor:        [229, 217, 217],  // Close button color
		resizableColor:    [209, 209, 209],  // Resizable icon color
		// Cascade options:
		desktopTopOffset:  20,    // Use a negative number if neccessary to place first window where you want it
		desktopLeftOffset: 290,
		mochaTopOffset:    70,    // Initial vertical spacing of each window
		mochaLeftOffset:   70,    // Initial horizontal spacing of each window
		// Naming options:
		// If you change the IDs of the Mocha Desktop containers in your HTML, you need to change them here as well.
		desktop:           'mochaDesktop',
		desktopHeader:     'mochaDesktopHeader',
		desktopNavBar:     'mochaDesktopNavbar',
		pageWrapper:       'mochaPageWrapper', 
		dock:              'mochaDock'		
	},
	initialize: function(options){
		this.setOptions(options);
		// Private properties
		this.ieSupport          = 'excanvas' // Makes it easier to switch between Excanvas and Moocanvas for testing
		this.indexLevel         = 1;  // Used for z-Index
		this.windowIDCount      = 0;		
		this.myTimer 			= ''; // Used with accordian
		this.iconAnimation      = ''; // Used with loading icon
		this.mochaControlsWidth = 0;
		this.minimizebuttonX    = 0;  // Minimize button horizontal position
		this.maximizebuttonX    = 0;  // Maximize button horizontal position
		this.closebuttonX       = 0;  // Close button horizontal position
		this.shadowWidth        = 3;
		this.shadowOffset       = this.shadowWidth * 2;		
		this.HeaderFooterShadow = this.options.headerHeight + this.options.footerHeight + this.shadowOffset;
	
		this.desktop       = $(this.options.desktop);
		this.desktopHeader = $(this.options.desktopHeader);
		this.desktopNavBar = $(this.options.desktopNavBar);
		this.pageWrapper   = $(this.options.pageWrapper);		
		this.dock          = $(this.options.dock);
		
		this.dockVisible   = this.dock ? true : false;   // True when dock is visible, false when not
		this.dockAutoHide  = false;  // True when dock autohide is set to on, false if set to off

		if ( this.dock ) { this.initializeDock(); }
		
		this.setDesktopSize();	
		this.newWindowsFromXHTML();		
		this.modalInitialize();		
		this.menuInitialize();
		
		// Resize desktop, page wrapper, modal overlay, and maximized windows when browser window is resized
		window.onresize = function(){ this.onBrowserResize(); }.bind(this);		
		
	},
	menuInitialize: function(){
		// Fix for dropdown menus in IE6
		if (Browser.Engine.trident4 && this.desktopNavBar){
			this.desktopNavBar.getElements('li').each(function(element) {
				element.addEvent('mouseenter', function(){
					this.addClass('ieHover');
				})
				element.addEvent('mouseleave', function(){
					this.removeClass('ieHover');
				})
			})
		};		
	},
	modalInitialize: function(){	
		var modalOverlay = new Element('div', {
			'id': 'mochaModalOverlay',
			'styles': {
				'height': document.getCoordinates().height
			}
		});		
		modalOverlay.injectInside(this.desktop ? this.desktop : document.body);
		
		modalOverlay.setStyle('opacity', .4);
		this.modalOpenMorph = new Fx.Morph($('mochaModalOverlay'), {
				'duration': 200
				});
		this.modalCloseMorph = new Fx.Morph($('mochaModalOverlay'), {
			'duration': 200,
			onComplete: function(){
				$('mochaModalOverlay').setStyle('display', 'none');
			}.bind(this)
		});
	},
	onBrowserResize: function(){
		this.setDesktopSize();
		this.setModalSize();
		// Resize maximized windows to fit new browser window size
		setTimeout( function(){								 
			$$('div.mocha').each(function(el){				
				if (el.isMaximized) {

					var iframe = this.getSubElement(el, 'iframe');						
					if ( iframe ) {
						iframe.setStyle('visibility', 'hidden');
					}
				
					var windowDimensions = document.getCoordinates();
					var contentWrapper = this.getSubElement(el, 'contentWrapper');
					contentWrapper.setStyles({
						'height': (windowDimensions.height - this.options.headerHeight - this.options.footerHeight),
						'width': windowDimensions.width
					});
					
					this.drawWindow(el);						
					if ( iframe ) {
						iframe.setStyles({
							'height': contentWrapper.getStyle('height')
						});
						iframe.setStyle('visibility', 'visible');
					}						
					
				}				
			}.bind(this));
		}.bind(this), 100);
	},
	newWindowsFromXHTML: function(properties, cascade){		
		$$('div.mocha').each(function(el, i) {
			// Get the window title and destroy that element, so it does not end up in window content
			if ( Browser.Engine.presto || Browser.Engine.trident5 )
				el.setStyle('display','block'); // Required by Opera, and probably IE7
			var title = el.getElement('h3.mochaTitle');
			var elDimensions = el.getStyles('height', 'width');
			var properties = {
				id: el.getProperty('id'),
				height: elDimensions.height.toInt(),
				width: elDimensions.width.toInt()
			}
			// If there is a title element, set title and destroy the element so it does not end up in window content
			if ( title ) {
				properties.title = title.innerHTML;
				title.destroy();
			}
			
			/*
			// Make sure there are no null values
			for(var key in properties) {
				if ( !properties[key] )
					delete properties[key];
			} */
			
			// Get content and destroy the element
			properties.content = el.innerHTML;
			el.destroy();
			
			// Create window
			this.newWindow(properties, true);
		}.bind(this));
		
		this.arrangeCascade();
	},
	/*
	
	Method: newWindowsFromJSON
	
	Description: Create one or more windows from JSON data. You can define all the same properties
	             as you can for newWindow. Undefined properties are set to their defaults.
	
	*/	
	newWindowsFromJSON: function(properties){
		properties.each(function(properties) {						 
				this.newWindow(properties);		
		}.bind(this));				
	},		
	/*
	
	Method: newWindow
	
	Arguments: 
		properties
		cascade - boolean - this is set to true for windows parsed from the original XHTML

	*/	
	newWindow: function(properties, cascade){
		

		
		var windowProperties = $extend({
			id:                null,
			title:            'New Window',
			loadMethod:       'html', 	             // html, xhr, or iframe
			content:           '',                   // used if loadMethod is set to 'html'
			contentURL:        'pages/lipsum.html',	 // used if loadMethod is set to 'xhr' or 'iframe'			
			modal:             false,
			width:             300,
			height:            125, 
			x:                 null,
			y:                 null,
			scrollbars:        true,
			draggable:         this.options.draggable,
			resizable:         this.options.resizable,			
			minimizable:       this.options.minimizable,
			maximizable:       this.options.maximizable,
			closable:          this.options.closable,			
			// Styling
			paddingVertical:   10,
			paddingHorizontal: 12,			
			bodyBgColor:       this.options.bodyBgColor,
			headerStartColor:  this.options.headerStartColor,  // Header gradient's top color
			headerStopColor:   this.options.headerStopColor,   // Header gradient's bottom color
			footerBgColor:     this.options.footerBgColor,	   // Background color of the main canvas shape
			minimizeColor:     this.options.minimizeColor,     // Minimize button color
			maximizeColor:     this.options.maximizeColor,     // Maximize button color
			closeColor:        this.options.closeColor,        // Close button color
			resizableColor:    this.options.resizableColor,    // Resizable icon color
			// Events
			onContentLoaded:   $empty,  // Event, fired when content is successfully loaded via XHR
			onFocus:           $empty,  // Event, fired when the window is focused
			onResize:          $empty,  // Event, fired when the window is resized
			onMinimize:        $empty,  // Event, fired when the window is minimized
			onMaximize:        $empty,  // Event, fired when the window is maximized
			onClose:           $empty,  // Event, fired just before the window is closed
			onCloseComplete:   $empty   // Event, fired after the window is closed
		}, properties || {});
		var windowEl = $(windowProperties.id);
		
		// Check if window already exists and is not in progress of closing down
		if ( windowEl && !windowEl.isClosing ) {
			if ( windowEl.isMinimized )	// If minimized -> restore
				this.restoreMinimized(windowEl);
			else // else focus
				setTimeout(function(){ this.focusWindow(windowEl); }.bind(this),10);			
			return;
		}
		
		// Create window div
		var windowEl = new Element('div', {
			'class': 'mocha',			
			'id':    windowProperties.id && windowProperties.id != null ? windowProperties.id : 'win' + (++this.windowIDCount),
			'styles': {
				'width':   windowProperties.width,
				'height':  windowProperties.height,
				'display': 'block'
			}
		});
		
		// Part of fix for scrollbar issues in Mac FF2
		if (Browser.Platform.mac && Browser.Engine.gecko){
			windowEl.setStyle('position', 'fixed');	
		}
		
		if (windowProperties.loadMethod == 'iframe') {
			// Iframes have their own scrollbars and padding.
			windowProperties.scrollbars = false;
			windowProperties.paddingVertical = 0;
			windowProperties.paddingHorizontal = 0;
		}
		
		// Extend our window element
		windowEl = $extend(windowEl, {
			// Custom properties
			id:         windowProperties.id,
			oldTop:     0,
			oldLeft:    0,
			oldWidth:   0, // Using this?
			oldHeight:  0,
			iconAnimation: $empty,
			modal:      windowProperties.modal,
			scrollbars: windowProperties.scrollbars,
			contentBorder: null,
			// Always use close buttons for modal windows
			closable:   windowProperties.closable || windowProperties.modal,
			resizable:  windowProperties.resizable && !windowProperties.modal,
			draggable:  windowProperties.draggable && !windowProperties.modal,
			// Minimizable, dock is required and window cannot be modal
			minimizable: this.dock && windowProperties.minimizable && !windowProperties.modal,
			// Maximizable, desktop is required
			maximizable: this.desktop && windowProperties.maximizable && !windowProperties.modal,
			iframe: windowProperties.loadMethod == 'iframe' ? true : false,
			isMaximized: false,
			isMinimized: false,
			// Custom styling			
			headerStartColor:  windowProperties.headerStartColor,  // Header gradient's top color
			headerStopColor:   windowProperties.headerStopColor,   // Header gradient's bottom color
			footerBgColor:     windowProperties.footerBgColor,	   // Background color of the main canvas shape
			minimizeColor:     windowProperties.minimizeColor,     // Minimize button color
			maximizeColor:     windowProperties.maximizeColor,     // Maximize button color
			closeColor:        windowProperties.closeColor,        // Close button color
			resizableColor:    windowProperties.resizableColor,    // Resizable icon color				
			// Custom events
			onFocus:           windowProperties.onFocus,
			onResize:          windowProperties.onResize,
			onMinimize:        windowProperties.onMinimize,
			onMaximize:        windowProperties.onMaximize,
			onClose:           windowProperties.onClose,
			onCloseComplete:   windowProperties.onCloseComplete
		});

		// Insert sub elements inside windowEl and cache them locally while creating the new window 
		var subElements = this.insertWindowElements(windowEl, windowProperties.height, windowProperties.width);
		
		// Set title
		subElements.title.setHTML(windowProperties.title);

		// Add content to window		
		switch(windowProperties.loadMethod) {
			case 'xhr':
				new Request({
					url: windowProperties.contentURL,
					onRequest: function(){
						this.showLoadingIcon(subElements.canvasIcon);
					}.bind(this),
					onFailure: function(){						
						subElements.content.setHTML('<p><strong>Error Loading XMLHttpRequest</strong></p><p>Make sure all of your content is uploaded to your server, and that you are attempting to load a document from the same domain as this page. XMLHttpRequests will not work on your local machine.</p>');
						this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
					}.bind(this),
					onSuccess: function(response) {						
						subElements.content.setHTML(response);
						this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
						windowProperties.onContentLoaded();
					}.bind(this)
				}).get();
				break;
			case 'iframe':
				if ( windowProperties.contentURL == '') {					
					break;
				}				
				subElements.iframe = new Element('iframe', {
					'id': windowEl.id + '_iframe', 
					'class': 'mochaIframe',
					'src': windowProperties.contentURL,
					'marginwidth':  0,
					'marginheight': 0,
					'frameBorder':  0,
					'scrolling':    'auto'
				}).injectInside(subElements.content);
				// Add onload event to iframe so we can stop the loading icon and run onContentLoaded()
				subElements.iframe.addEvent('load', function(e) {
					this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
					windowProperties.onContentLoaded();
				}.bind(this));					
				this.showLoadingIcon(subElements.canvasIcon);				
				break;
			case 'html':
			default:
				subElements.content.setHTML(windowProperties.content);
				windowProperties.onContentLoaded();
				break;
		}

		// Set scrollbars, always use 'hidden' for iframe windows
		subElements.contentWrapper.setStyles({
			'overflow': windowProperties.scrollbars && !windowProperties.iframe ? 'auto' : 'hidden',
			'background': windowProperties.bodyBgColor
		});

		// Set content padding
		subElements.content.setStyles({
			'padding-top': windowProperties.paddingVertical,
			'padding-bottom': windowProperties.paddingVertical,
			'padding-left': windowProperties.paddingHorizontal,
			'padding-right': windowProperties.paddingHorizontal
		});

		// Attach events to the window
		this.attachResizable(windowEl, subElements);
		this.setupEvents(windowEl, subElements);
	
		// Move new window into position. If position not specified by user then center the window on the page		
		var dimensions = document.getCoordinates();
		
		if (!windowProperties.y) {
			var windowPosTop = (dimensions.height * .5) - ((windowProperties.height + this.HeaderFooterShadow) * .5);	
		}
		else {
			var windowPosTop = windowProperties.y		
		}
		
		if (!windowProperties.x) {
			var windowPosLeft =	(dimensions.width * .5) - (windowProperties.width * .5);
		}
		else {
			var windowPosLeft = windowProperties.x	
		}
				
		if (windowEl.modal) {
			$('mochaModalOverlay').setStyle('display', 'block');
			if (this.options.effects == false){			
				$('mochaModalOverlay').setStyle('opacity', .55);
			}
			else {
				this.modalCloseMorph.cancel();
				this.modalOpenMorph.start({
					'opacity': .55
				});
			}
			windowEl.setStyles({
				'top': windowPosTop,
				'left': windowPosLeft,
				'zIndex': 11000
			});			
		}
		else if (cascade == true) {
			// do nothing		
		}
		else if (this.options.effects == false){	
			windowEl.setStyles({
				'top': windowPosTop,
				'left': windowPosLeft
			});
		}
		else {
			windowEl.positionMorph = new Fx.Morph(windowEl, {
				'duration': 300
			});
			windowEl.positionMorph.start({
				'top': windowPosTop,
				'left': windowPosLeft
			});
			setTimeout(function(){ this.focusWindow(windowEl); }.bind(this), 10);			
		}		

		// Inject window into DOM		
		
		windowEl.injectInside(this.desktop ? this.desktop : document.body);
		this.drawWindow(windowEl, subElements);
		
		// Drag.Move() does not work in IE until element has been injected, thus setting here
		this.attachDraggable(windowEl, subElements.titleBar);
		
	},
	/*
	
	Method: closeWindow
	
	Arguments: 
		el: the $(window) to be closed

	Returns:
		true: the window was closed
		false: the window was not closed

	*/
	closeWindow: function(windowEl) {
		// Does window exist and is not already in process of closing ?
		if ( !(windowEl = $(windowEl)) || windowEl.isClosing )
			return;
		
		windowEl.isClosing = true;
		windowEl.onClose();
		
		if (this.options.effects == false){
			if (windowEl.modal) {
				$('mochaModalOverlay').setStyle('opacity', 0);
			}
			windowEl.destroy();
			windowEl.onCloseComplete();			
		}
		else {
			// Redraws IE windows without shadows since IE messes up canvas alpha when you change element opacity
			if (Browser.Engine.trident) this.drawWindow(windowEl, null, false);
			if (windowEl.modal) {
				this.modalCloseMorph.start({
					'opacity': 0
				});
			}		
			var closeMorph = new Fx.Morph(windowEl, {
				duration: 250,
				onComplete: function(){
					windowEl.destroy();
					windowEl.onCloseComplete();
				}.bind(this)
			});
			closeMorph.start({
				'opacity': .4
			});
		}
		return true;
	},
	/*
	
	Method: closeAll
	
	Notes: This closes all the windows

	Returns:
		true: the windows were closed
		false: the windows were not closed

	*/	
	closeAll: function() {
		$$('div.mocha').each(function(el) {
			this.closeWindow(el);
			$$('button.mochaDockButton').destroy();
		}.bind(this));
		
		return true;		
	},
	focusWindow: function(windowEl){
		if ( !(windowEl = $(windowEl)) )
			return;
		// Only focus when needed
		if ( windowEl.getStyle('zIndex').toInt() == this.indexLevel )
			return;
		this.indexLevel++;
		windowEl.setStyle('zIndex', this.indexLevel);
		windowEl.onFocus();
	},
	maximizeWindow: function(windowEl) {
		// If window no longer exists or is maximized, stop
		if ( !(windowEl = $(windowEl)) || windowEl.isMaximized )
			return;
		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');
		windowEl.onMaximize();
		
		// Save original position, width and height
		windowEl.oldTop = windowEl.getStyle('top');
		windowEl.oldLeft = windowEl.getStyle('left');
		contentWrapper.oldWidth = contentWrapper.getStyle('width');
		contentWrapper.oldHeight = contentWrapper.getStyle('height');
		
		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
		}		

		var windowDimensions = document.getCoordinates();

		if (this.options.effects == false){	
			windowEl.setStyles({
				'top': -this.shadowWidth,
				'left': -this.shadowWidth
			});
			contentWrapper.setStyles({
				'height': windowDimensions.height - this.options.headerHeight - this.options.footerHeight,
				'width':  windowDimensions.width
			});			
			this.drawWindow(windowEl);
			// Show iframe
			if ( windowEl.iframe ) {
				this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
			}			
		}
		else {
			var maximizeMorph = new Fx.Morph(windowEl, { 
				'duration': 200,
				'onComplete': function(windowEl){					
					contentWrapper.setStyles({
						'height': (windowDimensions.height - this.options.headerHeight - this.options.footerHeight),
						'width':  windowDimensions.width
					});
					this.drawWindow(windowEl);
					// Show iframe
					if ( windowEl.iframe ) {
						this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
					}				
				}.bind(this)
			});
			maximizeMorph.start({
				'top':  -this.shadowWidth, // Takes shadow width into account
				'left': -this.shadowWidth // Takes shadow width into account
			});
		}		
		
		windowEl.isMaximized = true;
	},
	restoreWindow: function(windowEl) {
		// Window exists and is maximized ?
		if ( !(windowEl = $(windowEl)) || !windowEl.isMaximized )
			return;
			
		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
		}				
		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');
		contentWrapper.setStyles({
			'width':  contentWrapper.oldWidth,
			'height': contentWrapper.oldHeight
		});

		windowEl.isMaximized = false;
		this.drawWindow(windowEl);
		
		if (this.options.effects == false){	
			windowEl.setStyles({
				'top': windowEl.oldTop,
				'left': windowEl.oldLeft
			});		
		}
		else {
			var mochaMorph = new Fx.Morph(windowEl, { 
				'duration':   150,
				'onComplete': function(el){
					if ( windowEl.iframe ) {
						this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
					}
				}.bind(this)	
			});
			mochaMorph.start({
				'top': windowEl.oldTop,
				'left': windowEl.oldLeft
			});
		}
	},
	minimizeWindow: function(windowEl) {
		// What if there is no dock, react how ?? ignore request?
		if ( !(windowEl = $(windowEl)) || !this.dock)
			return;

		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
		}

		var title = this.getSubElement(windowEl, 'title');
		var mochaContentWrapper = windowEl.getElement('.mochaContentWrapper');
		var titleText = title.innerHTML;
		windowEl.onMinimize();
		
		// Hide window and add to dock
		windowEl.setStyle('visibility', 'hidden');
		
		 // Fixes a scrollbar issue in Mac FF2
		if (Browser.Platform.mac && Browser.Engine.gecko){
			this.getSubElement(windowEl, 'contentWrapper').setStyle('overflow', 'hidden');
		}		
		
		windowEl.isMinimized = true;
		var dockButton = new Element('button', {
			'id': windowEl.id + '_dockButton',
			'class': 'mochaDockButton',
			'title': titleText
		}).setHTML(titleText.substring(0,13) + (titleText.length > 13 ? '...' : '')).injectInside($(this.dock));
		dockButton.addEvent('click', function(event) {
			this.restoreMinimized(windowEl);
		}.bind(this));
		// Fixes a scrollbar issue in Mac FF2.
		// Have to use timeout because window gets focused when you click on the minimize button 	
		setTimeout(function(){ windowEl.setStyle('zIndex', 1); }.bind(this),100); 
	},
	restoreMinimized: function(windowEl) {
		
		 // Part of Mac FF2 scrollbar fix
		if (windowEl.scrollbars == true && windowEl.iframe == false){ 
			this.getSubElement(windowEl, 'contentWrapper').setStyle('overflow', 'auto');		
		}
		
		windowEl.setStyle('visibility', 'visible');
		
		// Show iframe
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
		}

		windowEl.isMinimized = false;
		this.focusWindow(windowEl);
		this.dock.getElementById(windowEl.id + '_dockButton').destroy();
	},
		
	/* -- START Private Methods -- */
	
	/*
		Method: getSubElement()
		Description: 
			Get a single subElement within windowEl. Subelements have IDs that are made up of the windowEl ID plus
			an element key. e.g., myWindow_content or myWindow_iframe.
			Might rename these parentWindow and childElements in the future.
		Arguments: 
			windowEl, subElementKey
		Returns:
			subElement
	*/
		
	getSubElement: function(windowEl, subElementKey) {
		return windowEl.getElementById((windowEl.id + '_' + subElementKey));
	},
	/*
		Method: getSubElements()
		Description:
			Get subElements within windowEl referenced in array subElementsKeys 
		Arguments:
			windowEl, subElementKeys
		Returns:
			Object, where elements are object.key
	*/
	getSubElements: function(windowEl, subElementKeys) {
		var subElements = {};
		subElementKeys.each(function(key) {
			subElements[key] = this.getSubElement(windowEl, key);
		}.bind(this));
		return subElements;
	},
	/*
		Method: setupControlEvents()
		Usage: internal

		Arguments:
			windowEl
	*/
	setupEvents: function(windowEl, subElements) {
		/*if ( !subElements )
			subElements = this.getSubElements(windowEl, ['closeButton','minimizeButton','maximizeButton']);*/
		
		// Set events
		// Note: if a button does not exist, its due to properties passed to newWindow() stating otherwice
		if ( subElements.closeButton )
			subElements.closeButton.addEvent('click', function() { this.closeWindow(windowEl); }.bind(this));
		
		if ( !windowEl.modal )		
			windowEl.addEvent('click', function() { this.focusWindow(windowEl); }.bind(this));
		
		if ( subElements.minimizeButton )
			subElements.minimizeButton.addEvent('click', function() { this.minimizeWindow(windowEl); }.bind(this));
		
		if ( subElements.maximizeButton ) {
			subElements.maximizeButton.addEvent('click', function() { 
				if ( windowEl.isMaximized ) {
					this.restoreWindow(windowEl);
					subElements.maximizeButton.setProperty('title', 'Maximize');
				} else {
					this.maximizeWindow(windowEl); 
					subElements.maximizeButton.setProperty('title', 'Restore');
				}
			}.bind(this));
		}
	},
	/*
		Method: attachDraggable()
		Description: make window draggable
		Usage: internal
		
		Arguments:
			windowEl
	*/
	attachDraggable: function(windowEl, handleEl){
		if ( !windowEl.draggable )
			return;
		new Drag.Move(windowEl, {
			handle: handleEl,
			onStart: function() {
				this.focusWindow(windowEl);
				if ( windowEl.iframe )
					this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
			}.bind(this),
			onComplete: function() {
				if ( windowEl.iframe )
					this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
			}.bind(this)
		});
	},
	/*
		Method: attachResizable()
		Description: make window resizable
		Usage: internal
		
		Arguments:
			windowEl
	*/
	attachResizable: function(windowEl, subElements){
		if ( !windowEl.resizable )
			return;
		subElements.contentWrapper.makeResizable({
			handle: subElements.resizeHandle,
			modifiers: {
				x: 'width',
				y: 'height'
			},
			limit: {
				x: [this.options.minWidth, this.options.maxWidth],
				y: [this.options.minHeight, this.options.maxHeight]
			},
			onStart: function() {
				this.cacheSubElements = this.getSubElements(windowEl, ['title', 'content', 'canvas', 'contentWrapper', 'overlay', 'titleBar', 'iframe', 'zIndexFix']);
				if ( this.cacheSubElements.iframe )
					this.cacheSubElements.iframe.setStyle('visibility', 'hidden');
			}.bind(this),
			onDrag: function() {
				this.drawWindow(windowEl, this.cacheSubElements);
			}.bind(this),
			onComplete: function() {
				if ( this.cacheSubElements.iframe )
					this.cacheSubElements.iframe.setStyle('visibility', 'visible');
				delete this.cacheSubElements;
				this.cacheSubElements = null;
				windowEl.onResize();
			}.bind(this)
		});
	},
	setDesktopSize: function(){
		var windowDimensions = document.getCoordinates();
		
		if ( this.desktop ){
			this.desktop.setStyle('height', windowDimensions.height);
		}
		
		// Set pageWrapper height so the dock doesn't cover the pageWrapper scrollbars.

		if ( this.pageWrapper && this.desktopHeader) {
			var pageWrapperHeight = (windowDimensions.height - this.desktopHeader.offsetHeight - (this.dockVisible ? this.dock.offsetHeight : 0));	
			if ( pageWrapperHeight < 0 ) {
				pageWrapperHeight = 0;
			}
			this.pageWrapper.setStyle('height', pageWrapperHeight + 'px');
		}
	},	
	setModalSize: function(){
		$('mochaModalOverlay').setStyle('height', document.getCoordinates().height);
	},
	/*
		Method: insertWindowElements
		Arguments:
			windowEl
		Returns:
			object containing all elements created within [windowEl]
	*/
	insertWindowElements: function(windowEl, height, width){
		var subElements = {};
		
		if (Browser.Engine.trident4){
			subElements.zIndexFix = new Element('iframe', {
				'class': 'zIndexFix',
				'scrolling': 'no',
				'marginWidth': 0,
				'marginHeight': 0,
				'src': '',
				'id': windowEl.id + '_zIndexFix'
			}).injectInside(windowEl);
		}
			
		subElements.overlay = new Element('div', {
			'class': 'mochaOverlay',
			'id': windowEl.id + '_overlay'
		}).injectInside(windowEl);
		
		//Insert mochaTitlebar
		subElements.titleBar = new Element('div', {
			'class': 'mochaTitlebar',
			'id': windowEl.id + '_titleBar',
			'styles': {
				'cursor': windowEl.draggable ? 'move' : 'default'
			}
		}).injectTop(subElements.overlay);

		// Create window header
		subElements.title = new Element('h3', {
			'class': 'mochaTitle',
			'id': windowEl.id + '_title'
		}).injectInside(subElements.titleBar);
		
		windowEl.contentBorder = new Element('div', {
			'class': 'mochaContentBorder',
			'id': this.options.id + '_contentBorder'
		}).injectInside(subElements.overlay);			
		
		subElements.contentWrapper = new Element('div', {
			'class': 'mochaContentWrapper',
			'id': windowEl.id + '_contentWrapper',
			'styles': {
				'width': width + 'px',
				'height': height + 'px'
			}
		}).injectInside(windowEl.contentBorder);
		
		subElements.content = new Element('div', {
			'class': 'mochaContent',
			'id': windowEl.id + '_content'
		}).injectInside(subElements.contentWrapper);
		
		//Insert canvas
		subElements.canvas = new Element('canvas', {
			'class': 'mochaCanvas',
			'width': 1,
			'height': 1,
			'id': windowEl.id + '_canvas'
		}).injectInside(windowEl);
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if ( Browser.Engine.trident && this.ieSupport == 'excanvas'  ) {			
			G_vmlCanvasManager.initElement(subElements.canvas);
			// This is odd, .getContext() method does not exist before retrieving the
			// element via getElement
			subElements.canvas = windowEl.getElement('.mochaCanvas');			
		}		
		
		//Insert resize handles
		if (windowEl.resizable){
			subElements.resizeHandle = new Element('div', {
				'class': 'resizeHandle',
				'id': windowEl.id + '_resizeHandle'
			}).injectAfter(subElements.overlay);
			
			if ( Browser.Engine.trident )
				subElements.resizeHandle.setStyle('zIndex', 2);
		}
		
		//Insert mochaTitlebar controls
		subElements.controls = new Element('div', {
			'class': 'mochaControls',
			'id': windowEl.id + '_controls'
		}).injectAfter(subElements.overlay);
		
		//Insert close button
		if (windowEl.closable){
			subElements.closeButton = new Element('div', {
				'class': 'mochaClose',
				'title': 'Close Window',
				'id': windowEl.id + '_closeButton'
			}).injectInside(subElements.controls);
		}				

		//Insert maximize button
		if (windowEl.maximizable){
			subElements.maximizeButton = new Element('div', {
				'class': 'maximizeToggle',
				'title': 'Maximize',
				'id': windowEl.id + '_maximizeButton'
			}).injectInside(subElements.controls);
		}
		//Insert minimize button
		if (windowEl.minimizable){
			subElements.minimizeButton = new Element('div', {
				'class': 'minimizeToggle',
				'title': 'Minimize',
				'id': windowEl.id + '_minimizeButton'
			}).injectInside(subElements.controls);
		}
		
		//Insert canvas
		subElements.canvasIcon = new Element('canvas', {
			'class': 'mochaLoadingIcon',
			'width': 18,
			'height': 18,
			'id': windowEl.id + '_canvasIcon'
		}).injectBottom(windowEl);	
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if (Browser.Engine.trident && this.ieSupport == 'excanvas') {
			G_vmlCanvasManager.initElement(subElements.canvasIcon);
			// This is odd, .getContext() method does not exist before retrieving the
			// element via getElement
			subElements.canvasIcon = windowEl.getElement('.mochaLoadingIcon');			
		}		
		
		if ( Browser.Engine.trident ) {
			subElements.controls.setStyle('zIndex', 2)
			subElements.overlay.setStyle('zIndex', 2)
		}
		
		// For Mac Firefox 2 to help reduce scrollbar bugs in that browser
		if (Browser.Platform.mac && Browser.Engine.gecko)
			subElements.overlay.setStyle('overflow', 'auto');
		this.setMochaControlsWidth(windowEl, subElements);
		return subElements;
	},	
	/*
	
	Method: drawWindow
	
	Arguments: 
		windowEl: the $(window)
		subElements: children of $(window)
		shadows: (boolean) false will draw a window without shadows
		
	Notes: This is where we create the canvas GUI	

	*/	
	drawWindow: function(windowEl, subElements, shadows) {
		if ( !subElements ) {
			subElements = this.getSubElements(windowEl, ['title', 'content', 'canvas', 'contentWrapper', 'overlay', 'titleBar', 'iframe', 'zIndexFix']);
		}
		
		windowEl.contentBorder.setStyles({
			'width': subElements.contentWrapper.offsetWidth
		});			

		// Resize iframe when window is resized
		if ( windowEl.iframe ) {
			subElements.iframe.setStyles({
				'height': subElements.contentWrapper.offsetHeight
			});
		}
		
		var mochaHeight = subElements.contentWrapper.getStyle('height').toInt() + this.HeaderFooterShadow;		
		var mochaWidth = subElements.contentWrapper.getStyle('width').toInt() + this.shadowOffset;
			
		subElements.overlay.setStyle('height', mochaHeight);
		windowEl.setStyle('height', mochaHeight);
		
		// If opera height and width must be set like this, when resizing:
		subElements.canvas.height = Browser.Engine.webkit ? 4000 : mochaHeight;
		subElements.canvas.width = Browser.Engine.webkit ? 2000 : mochaWidth;
		
		// Part of the fix for IE6 select z-index bug and FF on Mac scrollbar z-index bug
		if ( Browser.Engine.trident4 ){
			subElements.zIndexFix.setStyles({
				'width': mochaWidth,
				'height': mochaHeight
			})
		}

		// Set width		
		windowEl.setStyle('width', mochaWidth);
		subElements.overlay.setStyle('width', mochaWidth); 
		subElements.titleBar.setStyles({
			'width': mochaWidth - this.shadowOffset,
			'height': this.options.headerHeight
		});	

		// Draw shapes
		var ctx = subElements.canvas.getContext('2d');
		var dimensions = document.getCoordinates();
		ctx.clearRect(0, 0, dimensions.width, dimensions.height);
		
		// This is the drop shadow. It is created onion style with three layers
		if ( shadows != false ) {
			this.roundedRect(ctx, 0, 0, mochaWidth, mochaHeight, this.options.cornerRadius, [0, 0, 0], 0.06); 
			this.roundedRect(ctx, 1, 1, mochaWidth - 2, mochaHeight - 2, this.options.cornerRadius, [0, 0, 0], 0.08);
			this.roundedRect(ctx, 2, 2, mochaWidth - 4, mochaHeight - 4, this.options.cornerRadius, [0, 0, 0], 0.3); 
		}
		
		// Mocha body
		this.bodyRoundedRect(
			ctx,							 // context		
			3,                               // x
			2,                               // y			
			mochaWidth - this.shadowOffset,  // width
			mochaHeight - this.shadowOffset, // height
			this.options.cornerRadius,       // corner radius
			windowEl.footerBgColor           // Footer color			
		);
		
		// Mocha header
		this.topRoundedRect(				
			ctx,							 // context
			3,                               // x
			2,                               // y
			mochaWidth - this.shadowOffset,  // width
			this.options.headerHeight,       // height
			this.options.cornerRadius,       // corner radius
			windowEl.headerStartColor,       // Header gradient's top color
			windowEl.headerStopColor         // Header gradient's bottom color
		);		

		// Calculate X position for controlbuttons
		this.closebuttonX = mochaWidth - (windowEl.closable ? 15 : -4);
		this.maximizebuttonX = this.closebuttonX - (windowEl.maximizable ? 19 : 0);
		this.minimizebuttonX = this.maximizebuttonX - (windowEl.minimizable ? 19 : 0);
		
		if ( windowEl.closable )
			this.closebutton(ctx, this.closebuttonX, 15, windowEl.closeColor, 1.0);
		if ( windowEl.maximizable )
			this.maximizebutton(ctx, this.maximizebuttonX, 15, windowEl.maximizeColor, 1.0);
		if ( windowEl.minimizable )
			this.minimizebutton(ctx, this.minimizebuttonX, 15, windowEl.minimizeColor, 1.0); // Minimize
		if ( windowEl.resizable ) 
			this.triangle(ctx, mochaWidth - 20, mochaHeight - 20, 12, 12, windowEl.resizableColor, 1.0); // Resize handle
		
		// Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7.
		this.triangle(ctx, 0, 0, 10, 10, windowEl.resizableColor, 0); 

	},
	// Window body
	bodyRoundedRect: function(ctx, x, y, width, height, radius, rgb){
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ', 100)';
		ctx.beginPath();
		ctx.moveTo(x, y + radius);
		ctx.lineTo(x, y + height - radius);
		ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
		ctx.lineTo(x + width - radius, y + height);
		ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},	
	roundedRect: function(ctx, x, y, width, height, radius, rgb, a){
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.beginPath();
		ctx.moveTo(x, y + radius);
		ctx.lineTo(x, y + height - radius);
		ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
		ctx.lineTo(x + width - radius, y + height);
		ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},	
	// Window header with gradient background
	topRoundedRect: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor){

		// Create gradient
		if (Browser.Engine.presto != null ){
			var lingrad = ctx.createLinearGradient(0, 0, 0, this.options.headerHeight + 2);
		}
		else {
			var lingrad = ctx.createLinearGradient(0, 0, 0, this.options.headerHeight);
		}

		lingrad.addColorStop(0, 'rgba(' + headerStartColor.join(',') + ', 100)');
		lingrad.addColorStop(1, 'rgba(' + headerStopColor.join(',') + ', 100)');
		ctx.fillStyle = lingrad;

		// Draw header
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.lineTo(x, y + height);
		ctx.lineTo(x + width, y + height);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},
	// Resize handle
	triangle: function(ctx, x, y, width, height, rgb, a){
		ctx.beginPath();
		ctx.moveTo(x + width, y);
		ctx.lineTo(x, y + height);
		ctx.lineTo(x + width, y + height);
		ctx.closePath();
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	drawCircle: function(ctx, x, y, diameter, rgb, a){
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, diameter, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	maximizebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, 7, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// X sign
		ctx.beginPath();
		ctx.moveTo(x, y - 4);
		ctx.lineTo(x, y + 4);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x - 4, y);
		ctx.lineTo(x + 4, y);
		ctx.stroke();
	},
	closebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, 7, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// Plus sign
		ctx.beginPath();
		ctx.moveTo(x - 3, y - 3);
		ctx.lineTo(x + 3, y + 3);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x + 3, y - 3);
		ctx.lineTo(x - 3, y + 3);
		ctx.stroke();
	},
	minimizebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x,y);
		ctx.arc(x,y,7,0,Math.PI*2,true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// Minus sign
		ctx.beginPath();
		ctx.moveTo(x - 4, y);
		ctx.lineTo(x + 4, y);
		ctx.stroke();
	},
	hideLoadingIcon: function(canvas) {
		$(canvas).setStyle('display', 'none');		
		$clear(canvas.iconAnimation);
	},	
	/*
	
	Method: showLoadingIcon	

	*/	 
	showLoadingIcon: function(canvas) {
		$(canvas).setStyles({
			'display': 'block'
		});		
		var t = 1;	  	
		var iconAnimation = function(canvas){ 
			var ctx = $(canvas).getContext('2d');
			ctx.clearRect(0, 0, 18, 18); // Clear canvas
			ctx.save();
			ctx.translate(9, 9);
			ctx.rotate(t*(Math.PI / 8));	
			var color = 0;
			for (i=0; i < 8; i++){ // Draw individual dots
				color = Math.floor(255 / 8 * i);
				ctx.fillStyle = "rgb(" + color + "," + color + "," + color + ")";  	
				ctx.rotate(-Math.PI / 4);
				ctx.beginPath();
				ctx.arc(0, 7, 2, 0, Math.PI*2, true);
				ctx.fill();
			}
    		ctx.restore();			
			t++;			
		}.bind(this);
		canvas.iconAnimation = iconAnimation.periodical(125, this, canvas);
	},	
	setMochaControlsWidth: function(windowEl, subElements){
		var controlWidth = 14;
		var marginWidth = 5;
		this.mochaControlsWidth = 0;
		if ( windowEl.minimizable )
			this.mochaControlsWidth += (marginWidth + controlWidth);
		if ( windowEl.maximizable ) {
			this.mochaControlsWidth += (marginWidth + controlWidth);
			subElements.maximizeButton.setStyle('margin-left', marginWidth);
		}
		if ( windowEl.closable ) {
			this.mochaControlsWidth += (marginWidth + controlWidth);
			subElements.closeButton.setStyle('margin-left', marginWidth);
		}
		subElements.controls.setStyle('width', this.mochaControlsWidth);
	},
	initializeDock: function (){
			this.dock.setStyles({
				'display':  'block',		   
				'position': 'absolute',
				'top':      null,
				'bottom':   0,
				'left':     0
			});		
		// Probably: this event should be added/removed when toggling AutoHide, since we dont need it when AutoHide is turned off
		// this.dockVisible tracks the status of the dock, so that showing/hiding is not done when not needed
		document.addEvent('mousemove', function(event) {
			if ( !this.dockAutoHide )
				return;
			var ev = new Event(event);
			if ( ev.client.y > (document.getCoordinates().height - 25) ) {
				if ( !this.dockVisible ) {
					this.dock.setStyle('display', 'block'); 
					this.dockVisible = true;
					this.setDesktopSize();
				}
			} else {
				if ( this.dockVisible ) {
					this.dock.setStyle('display', 'none'); 
					this.dockVisible = false;
					this.setDesktopSize();
				}
			}
		}.bind(this));

		// Insert canvas
		var canvas = new Element('canvas', {
			'class':  'mochaCanvas',
			'id':     'dockCanvas',
			'width':  '15',
			'height': '18'
		}).injectInside(this.dock).setStyles({
			position: 'absolute',
			top:      '4px',
			left:     '2px',
			zIndex:   2
		});
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if (Browser.Engine.trident && this.ieSupport == 'excanvas') {
			G_vmlCanvasManager.initElement(canvas);
		}		

		// Position top or bottom selector
		$('mochaDockPlacement').setProperty('title','Position Dock Top');
			
		// Auto Hide toggle switch
		$('mochaDockAutoHide').setProperty('title','Turn Auto Hide On');
		
		// Attach event
		$('mochaDockPlacement').addEvent('click', function(event){
			var ctx = this.dock.getElement('.mochaCanvas').getContext('2d');
			
			// Move dock to top position
			if (this.dock.getStyle('position') != 'relative'){
				this.dock.setStyles({
					'position':      'relative',
					'bottom':         null,
					'border-top':    '1px solid #fff',
					'border-bottom': '1px solid #bbb'
				})
				this.setDesktopSize();
				this.dock.setProperty('dockPosition','Top');	
				this.drawCircle(ctx, 5, 4, 3, [0, 255, 0], 1.0); // green
				this.drawCircle(ctx, 5, 14, 3, [212, 208, 200], 1.0); // gray
				$('mochaDockPlacement').setProperty('title', 'Position Dock Bottom');				
				$('mochaDockAutoHide').setProperty('title', 'Auto Hide Disabled in Top Dock Position');
				this.dockAutoHide = false;
			}
			// Move dock to bottom position
			else {
				this.dock.setStyles({
					'position':      'absolute',
					'bottom':        0,
					'border-top':    '1px solid #bbb',
					'border-bottom': '1px solid #fff'
				})
				this.setDesktopSize();				
				this.dock.setProperty('dockPosition','Bottom');
				this.drawCircle(ctx, 5, 4, 3, [241, 102, 116], 1.0); // orange		
				this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange 
				$('mochaDockPlacement').setProperty('title', 'Position Dock Top');					
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide On');	 		
			}

		}.bind(this));

		// Attach event Auto Hide 
		$('mochaDockAutoHide').addEvent('click', function(event){
			if ( this.dock.getProperty('dockPosition') == 'Top' )
				return false;
			
			var ctx = this.dock.getElement('.mochaCanvas').getContext('2d');
			this.dockAutoHide = !this.dockAutoHide;	// Toggle
			if ( this.dockAutoHide ) {
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide Off');
				this.drawCircle(ctx, 5 , 14, 3, [0, 255, 0], 1.0); // green
			} else {
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide On');
				this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange
			}
		}.bind(this));
		
		this.drawDock(this.dock);		
	},
	drawDock: function (el){
		var ctx = el.getElement('.mochaCanvas').getContext('2d');
		this.drawCircle(ctx, 5 , 4, 3, [241, 102, 116], 1.0);  // orange
		this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange
	},
	dynamicResize: function (windowEl){				
			this.getSubElement(windowEl, 'contentWrapper').setStyle('height', this.getSubElement(windowEl, 'content').offsetHeight);
			this.drawWindow(windowEl);		
	},
	/*
	
	Method: arrangeCascade
	
	*/	
	arrangeCascade: function(){
		var x = this.options.desktopLeftOffset
		var y = this.options.desktopTopOffset;
		$$('div.mocha').each(function(windowEl){
			if (!windowEl.isMinimized && !windowEl.isMaximized){
				this.focusWindow(windowEl);
				x += this.options.mochaLeftOffset;
				y += this.options.mochaTopOffset;
				
				if (this.options.effects == false){	
					windowEl.setStyles({
						'top': y,
						'left': x
					});
				}				
				else {
					var cascadeMorph = new Fx.Morph(windowEl, {
						'duration': 550
					});
					cascadeMorph.start({
						'top': y,
						'left': x
					});
				}
			}
		}.bind(this));
	},
	/*
	
	Method: garbageCleanup
	
	Notes: Empties an all windows of their children, removes and garbages the windows.
	It is does not trigger onClose() or onCloseComplete().
	This is useful to clear memory before the pageUnload. 
	
	*/	
	garbageCleanUp: function() {
		$$('div.mocha').each(function(el) {
			el.destroy();
		}.bind(this));		
	}	
});
MochaUI.implement(new Options);

/* -----------------------------------------------------------------

	MOCHA SCREENS
	Notes: This class can be removed if you are not creating multiple screens/workspaces.

   ----------------------------------------------------------------- */

var MochaScreens = new Class({
	options: {
		defaultScreen: 0 // Default screen	
	},
	initialize: function(options){
		this.setOptions(options);
		this.setScreen(this.options.defaultScreen);
	},
	setScreen: function(index) {
		if ( !$('mochaScreens') )
			return;
		$$('#mochaScreens div.screen').each(function(el,i) {
			el.setStyle('display', i == index ? 'block' : 'none');
		});
	}
});
MochaScreens.implement(new Options);

/* -----------------------------------------------------------------

	MOCHA WINDOW FROM FORM
	Notes: This class can be removed if you are not creating new windows dynamically from a form.

   ----------------------------------------------------------------- */

var MochaWindowForm = new Class({
	options: {
		id: null,
		title: 'New Window',
		loadMethod: 'html', // html, xhr, or iframe
		content: '', // used if loadMethod is set to 'html'
		contentURL: 'pages/lipsum.html', // used if loadMethod is set to 'xhr' or 'iframe'
		modal: false,
		width: 300,
		height: 125,
		scrollbars: true, // true sets the overflow to auto and false sets it to hidden
		x: null, // if x or y is null or modal is false the new window is centered in the browser window
		y: null,
		paddingVertical: 10,
		paddingHorizontal: 12
	},
	initialize: function(options){
		this.setOptions(options);
		this.options.id = 'win' + (++document.mochaUI.windowIDCount);		
		this.options.title = $('mochaNewWindowHeaderTitle').value;
		if ($('htmlLoadMethod').checked){
			this.options.loadMethod = 'html';
		}
		if ($('xhrLoadMethod').checked){
			this.options.loadMethod = 'xhr';
		}
		if ($('iframeLoadMethod').checked){
			this.options.loadMethod = 'iframe';
		}
		this.options.content = $('mochaNewWindowContent').value;
		if ($('mochaNewWindowContentURL').value){
			this.options.contentURL = $('mochaNewWindowContentURL').value;
		}		
		if ($('mochaNewWindowModal').checked) {
			this.options.modal = true;
		}
		this.options.width = $('mochaNewWindowWidth').value.toInt();
		this.options.height = $('mochaNewWindowHeight').value.toInt();	
		this.options.x = $('mochaNewWindowX').value.toInt();
		this.options.y = $('mochaNewWindowY').value.toInt();
		this.options.paddingVertical = $('mochaNewWindowPaddingVertical').value.toInt();
		this.options.paddingHorizontal = $('mochaNewWindowPaddingHorizontal').value.toInt();
		document.mochaUI.newWindow(this.options);		
	}
});
MochaWindowForm.implement(new Options);


/* -----------------------------------------------------------------

	Corner Radius Slider
	Notes: Remove this function and it's reference in onload if you are not
	using the example corner radius slider

   ----------------------------------------------------------------- */

function addSlider(){
	if ($('sliderarea')) {
		mochaSlide = new Slider($('sliderarea'), $('sliderknob'), {
			steps: 20,
			offset: 5,
			onChange: function(pos){
				$('updatevalue').setHTML(pos);
				document.mochaUI.options.cornerRadius = pos;
				$$('div.mocha').each(function(windowEl, i) {
					document.mochaUI.drawWindow(windowEl);
				});
				document.mochaUI.indexLevel++; 
			}
		}).set(document.mochaUI.options.cornerRadius);
	}
}

/* -----------------------------------------------------------------

	Initialize Everything onLoad

   ----------------------------------------------------------------- */

window.addEvent('domready', function(){							 
		document.mochaScreens = new MochaScreens();
		document.mochaUI = new MochaUI();
		attachMochaLinkEvents(); // See mocha-events.js
		addSlider();             // remove this if you remove the example corner radius slider		
});

// This runs when a person leaves your page.
window.addEvent('unload', function(){
		if (document.mochaUI) document.mochaUI.garbageCleanUp();
});




/* -----------------------------------------------------------------

	ATTACH MOCHA LINK EVENTS
	Notes: Here is where you define your windows and the events that open them.
	If you are not using links to run Mocha methods you can remove this function.
	
	If you need to add link events to links within windows you are creating, do
	it in the onContentLoaded function of the new window.

   ----------------------------------------------------------------- */

function attachMochaLinkEvents(){
	
	
	// Examples
	if ($('ajaxpageLink')){ // Associated HTML: <a id="xhrpageLink" href="pages/lipsum.html">XHR Page</a>
		$('ajaxpageLink').addEvent('click', function(e){	
			new Event(e).stop();
			document.mochaUI.newWindow({
				id: 'ajaxpage',
				title: 'Content Loaded with an XMLHttpRequest',
				loadMethod: 'xhr',
				contentURL: 'pages/lipsum.html',
				width: 340,
				height: 150
			});
		});
	}

	if ($('mootoolsLink')){
		$('mootoolsLink').addEvent('click', function(e){	
			new Event(e).stop();
			document.mochaUI.newWindow({
				id: 'mootools',
				title: 'Mootools Forums in an Iframe',
				loadMethod: 'iframe',
				contentURL: 'http://forum.mootools.net/',
				width: 650,
				height: 400,
				scrollbars: false,
				paddingVertical: 0,
				paddingHorizontal: 0
			});
		});
	}

	if ($('spirographLink')){
		$('spirographLink').addEvent('click', function(e){	
			new Event(e).stop();
			document.mochaUI.newWindow({
				id: 'spirograph',
				title: 'Canvas Spirograph in an Iframe',
				loadMethod: 'iframe',
				contentURL: 'pages/spirograph.html',
				width: 340,
				height: 340,
				scrollbars: false,
				paddingVertical: 0,
				paddingHorizontal: 0,
				bgColor: '#c30'
			});
		});
	}
	
	if ($('youTubeLink')) {
		$('youTubeLink').addEvent('click', function(e){
		new Event(e).stop();
			document.mochaUI.newWindow({
				id: 'youTube',
				title: 'YouTube in Iframe',
				loadMethod: 'iframe',
				contentURL: 'pages/youtube.html',
				width: 425,
				height: 355,
				scrollbars: false,
				paddingVertical: 0,
				paddingHorizontal: 0,
				bgColor: '#000'
			});
		});
	}
	
	if ($('anon1Link')){
		$('anon1Link').addEvent('click', function(e){	
			new Event(e).stop();
			document.mochaUI.newWindow({
				title: 'Content Loaded with an XMLHttpRequest',
				loadMethod: 'xhr',
				contentURL: 'pages/lipsum.html',
				width: 340,
				height: 150
			});
		});
	}
	
	if ($('anon2Link')){ 
		$('anon2Link').addEvent('click', function(e){	
			new Event(e).stop();
			document.mochaUI.newWindow({
				title: 'Content Loaded with an XMLHttpRequest',
				loadMethod: 'xhr',
				contentURL: 'pages/lipsum.html',
				width: 340,
				height: 150
			});
		});
	}	
	
}




/* -----------------------------------------------------------------

	Script: 
		mocha.js version 0.8
	
	Copyright:
		Copyright (c) 2007-2008 Greg Houston, <http://greghoustondesign.com/>
	
	License:
		MIT-style license

	Contributors:
		Scott F. Frederick
		Joel Lindau
	
   ----------------------------------------------------------------- */

var MochaUI = new Class({
	options: {
		// Global options for windows:
		// Some of these options can be overriden for individual windows in newWindow()
		resizable:         true,
		draggable:         true,
		minimizable:       true,  // Requires dock
		maximizable:       true,  // Requires desktop
		closable:          true,
		effects:           true,  // Toggles the majority of window fade and move effects
		minWidth:          250,   // Minimum width of windows when resized
		maxWidth:          2500,  // Maximum width of windows when resized
		minHeight:         100,	  // Minimum height of windows when resized	
		maxHeight:         2000,  // Maximum height of windows when resized
		// Style options:
		headerHeight:      25,    // Height of window titlebar	
		footerHeight:      26, 		
		cornerRadius:      9,
		bodyBgColor:	   '#fff',           // Body background color - Hex			
		headerStartColor:  [250, 250, 250],  // Header gradient's top color - RGB
		headerStopColor:   [228, 228, 228],  // Header gradient's bottom color	
		footerBgColor:     [246, 246, 246],	 // Background color of the main canvas shape
		minimizeColor:     [231, 231, 209],  // Minimize button color
		maximizeColor:     [217, 229, 217],  // Maximize button color
		closeColor:        [229, 217, 217],  // Close button color
		resizableColor:    [209, 209, 209],  // Resizable icon color
		// Cascade options:
		desktopTopOffset:  20,    // Use a negative number if necessary to place first window where you want it
		desktopLeftOffset: 290,
		mochaTopOffset:    70,    // Initial vertical spacing of each window
		mochaLeftOffset:   70,    // Initial horizontal spacing of each window
		// Naming options:
		// If you change the IDs of the Mocha Desktop containers in your HTML, you need to change them here as well.
		desktop:           'mochaDesktop',
		desktopHeader:     'mochaDesktopHeader',
		desktopNavBar:     'mochaDesktopNavbar',
		pageWrapper:       'mochaPageWrapper', 
		dock:              'mochaDock'		
	},
	initialize: function(options){
		this.setOptions(options);
		// Private properties
		this.minimizeOffset     = 10;			
		this.ieSupport          = 'excanvas' // Makes it easier to switch between Excanvas and Moocanvas for testing
		this.indexLevel         = 100;  // Used for z-Index
		this.windowIDCount      = 0;		
		this.myTimer 			= ''; // Used with accordian
		this.iconAnimation      = ''; // Used with loading icon
		this.mochaControlsWidth = 0;
		this.minimizebuttonX    = 0;  // Minimize button horizontal position
		this.maximizebuttonX    = 0;  // Maximize button horizontal position
		this.closebuttonX       = 0;  // Close button horizontal position
		this.shadowWidth        = 3;
		this.shadowOffset       = this.shadowWidth * 2;
		this.HeaderFooterShadow = this.options.headerHeight + this.options.footerHeight + this.shadowOffset;
	
		this.desktop       = $(this.options.desktop);
		this.desktopHeader = $(this.options.desktopHeader);
		this.desktopNavBar = $(this.options.desktopNavBar);
		this.pageWrapper   = $(this.options.pageWrapper);		
		this.dock          = $(this.options.dock);
		
		this.dockVisible   = this.dock ? true : false;   // True when dock is visible, false when not
		this.dockAutoHide  = false;  // True when dock autohide is set to on, false if set to off

		if ( this.dock ) { this.initializeDock(); }
		
		this.setDesktopSize();	
		this.newWindowsFromXHTML();		
		this.modalInitialize();		
		this.menuInitialize();
		
		// Resize desktop, page wrapper, modal overlay, and maximized windows when browser window is resized
		window.onresize = function(){ this.onBrowserResize(); }.bind(this);		
		
	},
	menuInitialize: function(){
		// Fix for dropdown menus in IE6
		if (Browser.Engine.trident4 && this.desktopNavBar){
			this.desktopNavBar.getElements('li').each(function(element) {
				element.addEvent('mouseenter', function(){
					this.addClass('ieHover');
				})
				element.addEvent('mouseleave', function(){
					this.removeClass('ieHover');
				})
			})
		};		
	},
	modalInitialize: function(){	
		var modalOverlay = new Element('div', {
			'id': 'mochaModalOverlay',
			'styles': {
				'height': document.getCoordinates().height
			}
		});		
		modalOverlay.injectInside(this.desktop ? this.desktop : document.body);
		
		modalOverlay.setStyle('opacity', .4);
		this.modalOpenMorph = new Fx.Morph($('mochaModalOverlay'), {
				'duration': 200
				});
		this.modalCloseMorph = new Fx.Morph($('mochaModalOverlay'), {
			'duration': 200,
			onComplete: function(){
				$('mochaModalOverlay').setStyle('display', 'none');
			}.bind(this)
		});
	},
	onBrowserResize: function(){
		this.setDesktopSize();
		this.setModalSize();
		// Resize maximized windows to fit new browser window size
		setTimeout( function(){								 
			$$('div.mocha').each(function(el){				
				if (el.isMaximized) {

					var iframe = this.getSubElement(el, 'iframe');						
					if ( iframe ) {
						iframe.setStyle('visibility', 'hidden');
					}
				
					var windowDimensions = document.getCoordinates();
					var contentWrapper = this.getSubElement(el, 'contentWrapper');
					contentWrapper.setStyles({
						'height': (windowDimensions.height - this.options.headerHeight - this.options.footerHeight),
						'width': windowDimensions.width
					});
					
					this.drawWindow(el);						
					if ( iframe ) {
						iframe.setStyles({
							'height': contentWrapper.getStyle('height')
						});
						iframe.setStyle('visibility', 'visible');
					}						
					
				}				
			}.bind(this));
		}.bind(this), 100);
	},
	newWindowsFromXHTML: function(properties, cascade){		
		$$('div.mocha').each(function(el, i) {
			// Get the window title and destroy that element, so it does not end up in window content
			if ( Browser.Engine.presto || Browser.Engine.trident5 )
				el.setStyle('display','block'); // Required by Opera, and probably IE7
			var title = el.getElement('h3.mochaTitle');
			var elDimensions = el.getStyles('height', 'width');
			var properties = {
				id: el.getProperty('id'),
				height: elDimensions.height.toInt(),
				width: elDimensions.width.toInt()
			}
			// If there is a title element, set title and destroy the element so it does not end up in window content
			if ( title ) {
				properties.title = title.innerHTML;
				title.destroy();
			}
			
			/*
			// Make sure there are no null values
			for(var key in properties) {
				if ( !properties[key] )
					delete properties[key];
			} */
			
			// Get content and destroy the element
			properties.content = el.innerHTML;
			el.destroy();
			
			// Create window
			this.newWindow(properties, true);
		}.bind(this));
		
		this.arrangeCascade();
	},
	/*
	
	Method: newWindowsFromJSON
	
	Description: Create one or more windows from JSON data. You can define all the same properties
	             as you can for newWindow. Undefined properties are set to their defaults.
	
	*/	
	newWindowsFromJSON: function(properties){
		properties.each(function(properties) {						 
				this.newWindow(properties);		
		}.bind(this));				
	},		
	/*
	
	Method: newWindow
	
	Arguments: 
		properties
		cascade - boolean - this is set to true for windows parsed from the original XHTML

	*/	
	newWindow: function(properties, cascade){
		

		
		var windowProperties = $extend({
			id:                null,
			title:            'New Window',
			loadMethod:       'html', 	             // html, xhr, or iframe
			content:           '',                   // used if loadMethod is set to 'html'
			contentURL:        'pages/lipsum.html',	 // used if loadMethod is set to 'xhr' or 'iframe'			
			modal:             false,
			width:             300,
			height:            125, 
			x:                 null,
			y:                 null,
			scrollbars:        true,
			draggable:         this.options.draggable,
			resizable:         this.options.resizable,			
			minimizable:       this.options.minimizable,
			maximizable:       this.options.maximizable,
			closable:          this.options.closable,			
			// Styling
			paddingVertical:   10,
			paddingHorizontal: 12,			
			bodyBgColor:       this.options.bodyBgColor,
			headerStartColor:  this.options.headerStartColor,  // Header gradient's top color
			headerStopColor:   this.options.headerStopColor,   // Header gradient's bottom color
			footerBgColor:     this.options.footerBgColor,	   // Background color of the main canvas shape
			minimizeColor:     this.options.minimizeColor,     // Minimize button color
			maximizeColor:     this.options.maximizeColor,     // Maximize button color
			closeColor:        this.options.closeColor,        // Close button color
			resizableColor:    this.options.resizableColor,    // Resizable icon color
			// Events
			onContentLoaded:   $empty,  // Event, fired when content is successfully loaded via XHR
			onFocus:           $empty,  // Event, fired when the window is focused
			onResize:          $empty,  // Event, fired when the window is resized
			onMinimize:        $empty,  // Event, fired when the window is minimized
			onMaximize:        $empty,  // Event, fired when the window is maximized
			onClose:           $empty,  // Event, fired just before the window is closed
			onCloseComplete:   $empty   // Event, fired after the window is closed
		}, properties || {});
		var windowEl = $(windowProperties.id);
		
		// Check if window already exists and is not in progress of closing down
		if ( windowEl && !windowEl.isClosing ) {
			if ( windowEl.isMinimized )	// If minimized -> restore
				this.restoreMinimized(windowEl);
			else // else focus
				setTimeout(function(){ this.focusWindow(windowEl); }.bind(this),10);			
			return;
		}
		
		if (windowProperties.id == null || windowProperties.id == ''){
			windowProperties.id = 'win' + (++this.windowIDCount)
		}		
		
		// Create window div
		var windowEl = new Element('div', {
			'class': 'mocha',			
			'id':    windowProperties.id ,
			'styles': {
				'width':   windowProperties.width,
				'height':  windowProperties.height,
				'display': 'block'
			}
		});
		
		// Part of fix for scrollbar issues in Mac FF2
		if (Browser.Platform.mac && Browser.Engine.gecko){
			windowEl.setStyle('position', 'fixed');	
		}
		
		if (windowProperties.loadMethod == 'iframe') {
			// Iframes have their own scrollbars and padding.
			windowProperties.scrollbars = false;
			windowProperties.paddingVertical = 0;
			windowProperties.paddingHorizontal = 0;
		}
		
		// Extend our window element
		windowEl = $extend(windowEl, {
			// Custom properties
			id:         windowProperties.id,
			oldTop:     0,
			oldLeft:    0,
			oldWidth:   0, // Using this?
			oldHeight:  0,
			iconAnimation: $empty,
			modal:      windowProperties.modal,
			scrollbars: windowProperties.scrollbars,
			contentBorder: null,
			// Always use close buttons for modal windows
			closable:   windowProperties.closable || windowProperties.modal,
			resizable:  windowProperties.resizable && !windowProperties.modal,
			draggable:  windowProperties.draggable && !windowProperties.modal,
			// Minimizable, dock is required and window cannot be modal
			minimizable: this.dock && windowProperties.minimizable && !windowProperties.modal,
			// Maximizable, desktop is required
			maximizable: this.desktop && windowProperties.maximizable && !windowProperties.modal,
			iframe: windowProperties.loadMethod == 'iframe' ? true : false,
			isMaximized: false,
			isMinimized: false,
			// Custom styling			
			headerStartColor:  windowProperties.headerStartColor,  // Header gradient's top color
			headerStopColor:   windowProperties.headerStopColor,   // Header gradient's bottom color
			footerBgColor:     windowProperties.footerBgColor,	   // Background color of the main canvas shape
			minimizeColor:     windowProperties.minimizeColor,     // Minimize button color
			maximizeColor:     windowProperties.maximizeColor,     // Maximize button color
			closeColor:        windowProperties.closeColor,        // Close button color
			resizableColor:    windowProperties.resizableColor,    // Resizable icon color				
			// Custom events
			onFocus:           windowProperties.onFocus,
			onResize:          windowProperties.onResize,
			onMinimize:        windowProperties.onMinimize,
			onMaximize:        windowProperties.onMaximize,
			onClose:           windowProperties.onClose,
			onCloseComplete:   windowProperties.onCloseComplete
		});

		// Insert sub elements inside windowEl and cache them locally while creating the new window 
		var subElements = this.insertWindowElements(windowEl, windowProperties.height, windowProperties.width);
		
		// Set title
		subElements.title.setHTML(windowProperties.title);

		// Add content to window		
		switch(windowProperties.loadMethod) {
			case 'xhr':
				new Request({
					url: windowProperties.contentURL,
					onRequest: function(){
						this.showLoadingIcon(subElements.canvasIcon);
					}.bind(this),
					onFailure: function(){						
						subElements.content.setHTML('<p><strong>Error Loading XMLHttpRequest</strong></p><p>Make sure all of your content is uploaded to your server, and that you are attempting to load a document from the same domain as this page. XMLHttpRequests will not work on your local machine.</p>');
						this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
					}.bind(this),
					onSuccess: function(response) {						
						subElements.content.setHTML(response);
						this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
						windowProperties.onContentLoaded();
					}.bind(this)
				}).get();
				break;
			case 'iframe':
				if ( windowProperties.contentURL == '') {					
					break;
				}				
				subElements.iframe = new Element('iframe', {
					'id': windowEl.id + '_iframe', 
					'class': 'mochaIframe',
					'src': windowProperties.contentURL,
					'marginwidth':  0,
					'marginheight': 0,
					'frameBorder':  0,
					'scrolling':    'auto'
				}).injectInside(subElements.content);
				// Add onload event to iframe so we can stop the loading icon and run onContentLoaded()
				subElements.iframe.addEvent('load', function(e) {
					this.hideLoadingIcon.delay(150, this, subElements.canvasIcon);
					windowProperties.onContentLoaded();
				}.bind(this));					
				this.showLoadingIcon(subElements.canvasIcon);				
				break;
			case 'html':
			default:
				subElements.content.setHTML(windowProperties.content);
				windowProperties.onContentLoaded();
				break;
		}

		// Set scrollbars, always use 'hidden' for iframe windows
		subElements.contentWrapper.setStyles({
			'overflow': windowProperties.scrollbars && !windowProperties.iframe ? 'auto' : 'hidden',
			'background': windowProperties.bodyBgColor
		});

		// Set content padding
		subElements.content.setStyles({
			'padding-top': windowProperties.paddingVertical,
			'padding-bottom': windowProperties.paddingVertical,
			'padding-left': windowProperties.paddingHorizontal,
			'padding-right': windowProperties.paddingHorizontal
		});

		// Attach events to the window
		this.attachResizable(windowEl, subElements);
		this.setupEvents(windowEl, subElements);
	
		// Move new window into position. If position not specified by user then center the window on the page		
		var dimensions = document.getCoordinates();
		
		if (!windowProperties.y) {
			var windowPosTop = (dimensions.height * .5) - ((windowProperties.height + this.HeaderFooterShadow) * .5);	
		}
		else {
			var windowPosTop = windowProperties.y		
		}
		
		if (!windowProperties.x) {
			var windowPosLeft =	(dimensions.width * .5) - (windowProperties.width * .5);
		}
		else {
			var windowPosLeft = windowProperties.x	
		}
				
		if (windowEl.modal) {
			$('mochaModalOverlay').setStyle('display', 'block');
			if (this.options.effects == false){
				$('mochaModalOverlay').setStyle('height', "100%");
				$('mochaModalOverlay').setStyle('opacity', .55);
			}
			else {
				$('mochaModalOverlay').setStyle('height', "100%");
				this.modalCloseMorph.cancel();
				this.modalOpenMorph.start({
					'opacity': .55
				});
			}
			windowEl.setStyles({
				'top': windowPosTop,
				'left': windowPosLeft,
				'zIndex': 11000
			});			
		}
		else if (cascade == true) {
			// do nothing		
		}
		else if (this.options.effects == false){	
			windowEl.setStyles({
				'top': windowPosTop,
				'left': windowPosLeft
			});
		}
		else {
			windowEl.positionMorph = new Fx.Morph(windowEl, {
				'duration': 300
			});
			windowEl.positionMorph.start({
				'top': windowPosTop,
				'left': windowPosLeft
			});
			setTimeout(function(){ this.focusWindow(windowEl); }.bind(this), 10);			
		}		

		// Inject window into DOM		
		
		windowEl.injectInside(this.desktop ? this.desktop : document.body);
		this.drawWindow(windowEl, subElements);
		
		// Drag.Move() does not work in IE until element has been injected, thus setting here
		this.attachDraggable(windowEl, subElements.titleBar);
		
	},
	/*
	
	Method: closeWindow
	
	Arguments: 
		el: the $(window) to be closed

	Returns:
		true: the window was closed
		false: the window was not closed

	*/
	closeWindow: function(windowEl) {
		// Does window exist and is not already in process of closing ?
		if ( !(windowEl = $(windowEl)) || windowEl.isClosing )
			return;
		
		windowEl.isClosing = true;
		windowEl.onClose();
		
		if (this.options.effects == false){
			if (windowEl.modal) {
				$('mochaModalOverlay').setStyle('opacity', 0);
			}
			windowEl.destroy();
			windowEl.onCloseComplete();			
		}
		else {
			// Redraws IE windows without shadows since IE messes up canvas alpha when you change element opacity
			if (Browser.Engine.trident) this.drawWindow(windowEl, null, false);
			if (windowEl.modal) {
				this.modalCloseMorph.start({
					'opacity': 0
				});
			}		
			var closeMorph = new Fx.Morph(windowEl, {
				duration: 250,
				onComplete: function(){
					windowEl.destroy();
					windowEl.onCloseComplete();
				}.bind(this)
			});
			closeMorph.start({
				'opacity': .4
			});
		}
		return true;
	},
	/*
	
	Method: closeAll
	
	Notes: This closes all the windows

	Returns:
		true: the windows were closed
		false: the windows were not closed

	*/	
	closeAll: function() {
		$$('div.mocha').each(function(el) {
			this.closeWindow(el);
			$$('button.mochaDockButton').destroy();
		}.bind(this));
		
		return true;		
	},
	/*
	
	Method: minimizeAll
	
	Notes: This minimizes all the windows

	Returns:
		true: the windows were minimized
		false: the windows were not minimized

	*/	
	minimizeAll: function() {
		$$('div.mocha').each(function(el) {
			this.minimizeWindow(el);
			$$('button.mochaDockButton').destroy();
		}.bind(this));
		
		return true;
	},
	focusWindow: function(windowEl){
		if ( !(windowEl = $(windowEl)) )
			return;
		// Only focus when needed
		if ( windowEl.getStyle('zIndex').toInt() == this.indexLevel )
			return;
		this.indexLevel++;
		windowEl.setStyle('zIndex', this.indexLevel);
		windowEl.onFocus();
	},
	maximizeWindow: function(windowEl) {
		// If window no longer exists or is maximized, stop
		if ( !(windowEl = $(windowEl)) || windowEl.isMaximized )
			return;
		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');
		windowEl.onMaximize();
		
		// Save original position, width and height
		windowEl.oldTop = windowEl.getStyle('top');
		windowEl.oldLeft = windowEl.getStyle('left');
		contentWrapper.oldWidth = contentWrapper.getStyle('width');
		contentWrapper.oldHeight = contentWrapper.getStyle('height');
		
		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
		}		

		var windowDimensions = document.getCoordinates();

		if (this.options.effects == false){	
			windowEl.setStyles({
				'top': -this.shadowWidth,
				'left': -this.shadowWidth
			});
			contentWrapper.setStyles({
				'height': windowDimensions.height - this.options.headerHeight - this.options.footerHeight,
				'width':  windowDimensions.width
			});			
			this.drawWindow(windowEl);
			// Show iframe
			if ( windowEl.iframe ) {
				this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
			}			
		}
		else {
			var maximizeMorph = new Fx.Morph(windowEl, { 
				'duration': 200,
				'onComplete': function(windowEl){					
					contentWrapper.setStyles({
						'height': (windowDimensions.height - this.options.headerHeight - this.options.footerHeight),
						'width':  windowDimensions.width
					});
					this.drawWindow(windowEl);
					// Show iframe
					if ( windowEl.iframe ) {
						this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
					}				
				}.bind(this)
			});
			maximizeMorph.start({
				'top':  -this.shadowWidth, // Takes shadow width into account
				'left': -this.shadowWidth // Takes shadow width into account
			});
		}		
		
		windowEl.isMaximized = true;
	},
	restoreWindow: function(windowEl) {
		// Window exists and is maximized ?
		if ( !(windowEl = $(windowEl)) || !windowEl.isMaximized )
			return;
			
		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden');
		}				
		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');
		contentWrapper.setStyles({
			'width':  contentWrapper.oldWidth,
			'height': contentWrapper.oldHeight
		});

		windowEl.isMaximized = false;
		this.drawWindow(windowEl);
		
		if (this.options.effects == false){	
			windowEl.setStyles({
				'top': windowEl.oldTop,
				'left': windowEl.oldLeft
			});		
		}
		else {
			var mochaMorph = new Fx.Morph(windowEl, { 
				'duration':   150,
				'onComplete': function(el){
					if ( windowEl.iframe ) {
						this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
					}
				}.bind(this)	
			});
			mochaMorph.start({
				'top': windowEl.oldTop,
				'left': windowEl.oldLeft
			});
		}
	},
	minimizeWindow: function(windowEl) {
		// What if there is no dock, react how ?? ignore request?
		if ( !(windowEl = $(windowEl)) || !this.dock)
			return;

		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');

		// Save original position, width and height
		windowEl.oldTop2 = windowEl.getStyle('top');
		windowEl.oldLeft2 = windowEl.getStyle('left');
		contentWrapper.oldWidth2 = contentWrapper.getStyle('width');
		contentWrapper.oldHeight2 = contentWrapper.getStyle('height');			

		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( windowEl.iframe ) {
			this.getSubElement(windowEl, 'iframe').setStyle('display', 'none');
		}
		
		this.windowEl = windowEl;		
		var windowDimensions = document.getCoordinates();
		
			var minimizeSizeMorph = new Fx.Elements([windowEl.getElement('.mochaContentWrapper'), windowEl], { 
				'duration': 400,
				'onStart': function(windowEl){
					this.minimizeAnimation = this.drawWindow.periodical(20, this, this.windowEl);
				}.bind(this),
				'onComplete': function(windowEl){
					this.windowEl.isMinimized = true;
					$clear(this.minimizeAnimation);	
					this.windowEl.setStyle('display', 'none');
					this.makeMinimizeButton(this.windowEl);
					// Fixes a scrollbar issue in Mac FF2.
					// Have to use timeout because window gets focused when you click on the minimize button 	
					setTimeout(function(){ this.windowEl.setStyle('zIndex', 1); }.bind(this),100);
					this.windowEl.onMinimize();
				}.bind(this)
			});
			
			var opacity = Browser.Engine.trident ? 1 : 0
			
			minimizeSizeMorph.start({
				'0': {	'height': this.options.minHeight,
						'width':  this.options.minWidth
				},
				'1': {	'top':  this.dock.getProperty('dockPosition') == 'Top' ? this.minimizeOffset : windowDimensions.height.toInt() - this.options.minHeight - this.minimizeOffset,
						'left': (windowDimensions.width.toInt() - this.options.minWidth) * .5,
						'opacity': opacity
				}
			});		

		 // Fixes a scrollbar issue in Mac FF2
		if (Browser.Platform.mac && Browser.Engine.gecko){
			this.getSubElement(windowEl, 'contentWrapper').setStyle('overflow', 'hidden');
		} 
	},
	makeMinimizeButton: function(windowEl) {
		var title = this.getSubElement(windowEl, 'title');		
		var titleText = title.innerHTML;	
		var dockButton = new Element('button', {
			'id': windowEl.id + '_dockButton',
			'class': 'mochaDockButton',
			'title': titleText
		}).setHTML(titleText.substring(0,13) + (titleText.length > 13 ? '...' : '')).injectInside($(this.dock));
		dockButton.addEvent('click', function(event) {
			this.restoreMinimized(windowEl);
		}.bind(this));		
		
	},
	restoreMinimized: function(windowEl) {
		
		 // Part of Mac FF2 scrollbar fix
		if (windowEl.scrollbars == true && windowEl.iframe == false){ 
			this.getSubElement(windowEl, 'contentWrapper').setStyle('overflow', 'auto');		
		}
		
		var contentWrapper = this.getSubElement(windowEl, 'contentWrapper');		
		this.windowEl = windowEl;		
		var windowDimensions = document.getCoordinates();		
		this.dock.getElementById(windowEl.id + '_dockButton').destroy();

		this.windowEl.setStyle('top', this.dock.getProperty('dockPosition') == 'Top' ? this.minimizeOffset : windowDimensions.height.toInt() - this.options.minHeight - this.minimizeOffset);	

		var restoreSizeMorph = new Fx.Elements([windowEl.getElement('.mochaContentWrapper'), windowEl], { 
			'duration': 300,
			'onStart': function(windowEl){							
				this.windowEl.setStyle('display', 'block');
				this.focusWindow(this.windowEl);
				this.restoreAnimation = this.drawWindow.periodical(20, this, this.windowEl);
			}.bind(this),
			'onComplete': function(windowEl){
				$clear(this.restoreAnimation);
				this.drawWindow(this.windowEl);
				// Show iframe
				if ( this.windowEl.iframe ) {
					this.getSubElement(this.windowEl, 'iframe').setStyle('display', 'block');
				}
				this.windowEl.isMinimized = false;									
			}.bind(this)
		});
			
		restoreSizeMorph.start({
			'0': {	'height': contentWrapper.oldHeight2,
					'width':  contentWrapper.oldWidth2
			},
			'1': {	'top':  windowEl.oldTop2,
					'left': windowEl.oldLeft2,
					'opacity': 1
			}
		});		

	},
		
	/* -- START Private Methods -- */
	
	/*
		Method: getSubElement()
		Description: 
			Get a single subElement within windowEl. Subelements have IDs that are made up of the windowEl ID plus
			an element key. e.g., myWindow_content or myWindow_iframe.
			Might rename these parentWindow and childElements in the future.
		Arguments: 
			windowEl, subElementKey
		Returns:
			subElement
	*/
		
	getSubElement: function(windowEl, subElementKey) {
		return windowEl.getElementById((windowEl.id + '_' + subElementKey));
	},
	/*
		Method: getSubElements()
		Description:
			Get subElements within windowEl referenced in array subElementsKeys 
		Arguments:
			windowEl, subElementKeys
		Returns:
			Object, where elements are object.key
	*/
	getSubElements: function(windowEl, subElementKeys) {
		var subElements = {};
		subElementKeys.each(function(key) {
			subElements[key] = this.getSubElement(windowEl, key);
		}.bind(this));
		return subElements;
	},
	/*
		Method: setupControlEvents()
		Usage: internal

		Arguments:
			windowEl
	*/
	setupEvents: function(windowEl, subElements) {
		/*if ( !subElements )
			subElements = this.getSubElements(windowEl, ['closeButton','minimizeButton','maximizeButton']);*/
		
		// Set events
		// Note: if a button does not exist, its due to properties passed to newWindow() stating otherwice
		if ( subElements.closeButton )
			subElements.closeButton.addEvent('click', function() { this.closeWindow(windowEl); }.bind(this));
		
		if ( !windowEl.modal )		
			windowEl.addEvent('click', function() { this.focusWindow(windowEl); }.bind(this));
		
		if ( subElements.minimizeButton )
			subElements.minimizeButton.addEvent('click', function() { this.minimizeWindow(windowEl); }.bind(this));
		
		if ( subElements.maximizeButton ) {
			subElements.maximizeButton.addEvent('click', function() { 
				if ( windowEl.isMaximized ) {
					this.restoreWindow(windowEl);
					subElements.maximizeButton.setProperty('title', 'Maximize');
				} else {
					this.maximizeWindow(windowEl); 
					subElements.maximizeButton.setProperty('title', 'Restore');
				}
			}.bind(this));
		}
	},
	/*
		Method: attachDraggable()
		Description: make window draggable
		Usage: internal
		
		Arguments:
			windowEl
	*/
	attachDraggable: function(windowEl, handleEl){
		if ( !windowEl.draggable )
			return;
		new Drag.Move(windowEl, {
			handle: handleEl,
			onStart: function() {
				this.focusWindow(windowEl);
				if ( windowEl.iframe ) { /* this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'hidden'); */ }
			}.bind(this),
			onComplete: function() {
				if ( windowEl.iframe )
					this.getSubElement(windowEl, 'iframe').setStyle('visibility', 'visible');
			}.bind(this)
		});
	},
	/*
		Method: attachResizable()
		Description: make window resizable
		Usage: internal
		
		Arguments:
			windowEl
	*/
	attachResizable: function(windowEl, subElements){
		if ( !windowEl.resizable )
			return;
		subElements.contentWrapper.makeResizable({
			handle: subElements.resizeHandle,
			modifiers: {
				x: 'width',
				y: 'height'
			},
			limit: {
				x: [this.options.minWidth, this.options.maxWidth],
				y: [this.options.minHeight, this.options.maxHeight]
			},
			onStart: function() {
				this.cacheSubElements = this.getSubElements(windowEl, ['title', 'content', 'canvas', 'contentWrapper', 'overlay', 'titleBar', 'iframe', 'zIndexFix']);
				if ( this.cacheSubElements.iframe )
					this.cacheSubElements.iframe.setStyle('visibility', 'hidden');
			}.bind(this),
			onDrag: function() {
				this.drawWindow(windowEl, this.cacheSubElements);
			}.bind(this),
			onComplete: function() {
				if ( this.cacheSubElements.iframe )
					this.cacheSubElements.iframe.setStyle('visibility', 'visible');
				delete this.cacheSubElements;
				this.cacheSubElements = null;
				windowEl.onResize();
			}.bind(this)
		});
	},
	setDesktopSize: function(){
		var windowDimensions = document.getCoordinates();
		
		if ( this.desktop ){
			this.desktop.setStyle('height', windowDimensions.height);
		}
		
		// Set pageWrapper height so the dock doesn't cover the pageWrapper scrollbars.

		if ( this.pageWrapper && this.desktopHeader) {
			var pageWrapperHeight = (windowDimensions.height - this.desktopHeader.offsetHeight - (this.dockVisible ? this.dock.offsetHeight : 0));	
			if ( pageWrapperHeight < 0 ) {
				pageWrapperHeight = 0;
			}
			this.pageWrapper.setStyle('height', pageWrapperHeight + 'px');
		}
	},	
	setModalSize: function(){
		$('mochaModalOverlay').setStyle('height', document.getCoordinates().height);
	},
	/*
		Method: insertWindowElements
		Arguments:
			windowEl
		Returns:
			object containing all elements created within [windowEl]
	*/
	insertWindowElements: function(windowEl, height, width){
		var subElements = {};
		
		if (Browser.Engine.trident4){
			subElements.zIndexFix = new Element('iframe', {
				'class': 'zIndexFix',
				'scrolling': 'no',
				'marginWidth': 0,
				'marginHeight': 0,
				'src': '',
				'id': windowEl.id + '_zIndexFix'
			}).injectInside(windowEl);
		}
			
		subElements.overlay = new Element('div', {
			'class': 'mochaOverlay',
			'id': windowEl.id + '_overlay'
		}).injectInside(windowEl);
		
		//Insert mochaTitlebar
		subElements.titleBar = new Element('div', {
			'class': 'mochaTitlebar',
			'id': windowEl.id + '_titleBar',
			'styles': {
				'cursor': windowEl.draggable ? 'move' : 'default'
			}
		}).injectTop(subElements.overlay);

		// Create window header
		subElements.title = new Element('h3', {
			'class': 'mochaTitle',
			'id': windowEl.id + '_title'
		}).injectInside(subElements.titleBar);
		
		windowEl.contentBorder = new Element('div', {
			'class': 'mochaContentBorder',
			'id': this.options.id + '_contentBorder'
		}).injectInside(subElements.overlay);			
		
		subElements.contentWrapper = new Element('div', {
			'class': 'mochaContentWrapper',
			'id': windowEl.id + '_contentWrapper',
			'styles': {
				'width': width + 'px',
				'height': height + 'px'
			}
		}).injectInside(windowEl.contentBorder);
		
		subElements.content = new Element('div', {
			'class': 'mochaContent',
			'id': windowEl.id + '_content'
		}).injectInside(subElements.contentWrapper);
		
		//Insert canvas
		subElements.canvas = new Element('canvas', {
			'class': 'mochaCanvas',
			'width': 1,
			'height': 1,
			'id': windowEl.id + '_canvas'
		}).injectInside(windowEl);
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if ( Browser.Engine.trident && this.ieSupport == 'excanvas'  ) {			
			G_vmlCanvasManager.initElement(subElements.canvas);
			// This is odd, .getContext() method does not exist before retrieving the
			// element via getElement
			subElements.canvas = windowEl.getElement('.mochaCanvas');			
		}		
		
		//Insert resize handles
		if (windowEl.resizable){
			subElements.resizeHandle = new Element('div', {
				'class': 'resizeHandle',
				'id': windowEl.id + '_resizeHandle'
			}).injectAfter(subElements.overlay);
			
			if ( Browser.Engine.trident )
				subElements.resizeHandle.setStyle('zIndex', 2);
		}
		
		//Insert mochaTitlebar controls
		subElements.controls = new Element('div', {
			'class': 'mochaControls',
			'id': windowEl.id + '_controls'
		}).injectAfter(subElements.overlay);
		
		//Insert close button
		if (windowEl.closable){
			subElements.closeButton = new Element('div', {
				'class': 'mochaClose',
				'title': 'Close Window',
				'id': windowEl.id + '_closeButton'
			}).injectInside(subElements.controls);
		}				

		//Insert maximize button
		if (windowEl.maximizable){
			subElements.maximizeButton = new Element('div', {
				'class': 'maximizeToggle',
				'title': 'Maximize',
				'id': windowEl.id + '_maximizeButton'
			}).injectInside(subElements.controls);
		}
		//Insert minimize button
		if (windowEl.minimizable){
			subElements.minimizeButton = new Element('div', {
				'class': 'minimizeToggle',
				'title': 'Minimize',
				'id': windowEl.id + '_minimizeButton'
			}).injectInside(subElements.controls);
		}
		
		//Insert canvas
		subElements.canvasIcon = new Element('canvas', {
			'class': 'mochaLoadingIcon',
			'width': 18,
			'height': 18,
			'id': windowEl.id + '_canvasIcon'
		}).injectBottom(windowEl);	
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if (Browser.Engine.trident && this.ieSupport == 'excanvas') {
			G_vmlCanvasManager.initElement(subElements.canvasIcon);
			// This is odd, .getContext() method does not exist before retrieving the
			// element via getElement
			subElements.canvasIcon = windowEl.getElement('.mochaLoadingIcon');			
		}		
		
		if ( Browser.Engine.trident ) {
			subElements.controls.setStyle('zIndex', 2)
			subElements.overlay.setStyle('zIndex', 2)
		}
		
		// For Mac Firefox 2 to help reduce scrollbar bugs in that browser
		if (Browser.Platform.mac && Browser.Engine.gecko)
			subElements.overlay.setStyle('overflow', 'auto');
		this.setMochaControlsWidth(windowEl, subElements);
		return subElements;
	},	
	/*
	
	Method: drawWindow
	
	Arguments: 
		windowEl: the $(window)
		subElements: children of $(window)
		shadows: (boolean) false will draw a window without shadows
		
	Notes: This is where we create the canvas GUI	

	*/	
	drawWindow: function(windowEl, subElements, shadows) {
		if ( !subElements ) {
			subElements = this.getSubElements(windowEl, ['title', 'content', 'canvas', 'contentWrapper', 'overlay', 'titleBar', 'iframe', 'zIndexFix']);
		}
		
		windowEl.contentBorder.setStyles({
			'width': subElements.contentWrapper.offsetWidth
		});			

		// Resize iframe when window is resized
		if ( windowEl.iframe ) {
			subElements.iframe.setStyles({
				'height': subElements.contentWrapper.offsetHeight
			});
		}
		
		var mochaHeight = subElements.contentWrapper.getStyle('height').toInt() + this.HeaderFooterShadow;		
		var mochaWidth = subElements.contentWrapper.getStyle('width').toInt() + this.shadowOffset;
			
		subElements.overlay.setStyle('height', mochaHeight);
		windowEl.setStyle('height', mochaHeight);
		
		// If opera height and width must be set like this, when resizing:
		subElements.canvas.height = Browser.Engine.webkit ? 4000 : mochaHeight;
		subElements.canvas.width = Browser.Engine.webkit ? 2000 : mochaWidth;
		
		// Part of the fix for IE6 select z-index bug and FF on Mac scrollbar z-index bug
		if ( Browser.Engine.trident4 ){
			subElements.zIndexFix.setStyles({
				'width': mochaWidth,
				'height': mochaHeight
			})
		}

		// Set width		
		windowEl.setStyle('width', mochaWidth);
		subElements.overlay.setStyle('width', mochaWidth); 
		subElements.titleBar.setStyles({
			'width': mochaWidth - this.shadowOffset,
			'height': this.options.headerHeight
		});	

		// Draw shapes
		var ctx = subElements.canvas.getContext('2d');
		var dimensions = document.getCoordinates();
		ctx.clearRect(0, 0, dimensions.width, dimensions.height);
		
		// This is the drop shadow. It is created onion style with three layers
		if ( shadows != false ) {
			this.roundedRect(ctx, 0, 0, mochaWidth, mochaHeight, this.options.cornerRadius, [0, 0, 0], 0.06); 
			this.roundedRect(ctx, 1, 1, mochaWidth - 2, mochaHeight - 2, this.options.cornerRadius, [0, 0, 0], 0.08);
			this.roundedRect(ctx, 2, 2, mochaWidth - 4, mochaHeight - 4, this.options.cornerRadius, [0, 0, 0], 0.3); 
		}
		
		// Mocha body
		this.bodyRoundedRect(
			ctx,							 // context		
			3,                               // x
			2,                               // y			
			mochaWidth - this.shadowOffset,  // width
			mochaHeight - this.shadowOffset, // height
			this.options.cornerRadius,       // corner radius
			windowEl.footerBgColor           // Footer color			
		);
		
		// Mocha header
		this.topRoundedRect(				
			ctx,							 // context
			3,                               // x
			2,                               // y
			mochaWidth - this.shadowOffset,  // width
			this.options.headerHeight,       // height
			this.options.cornerRadius,       // corner radius
			windowEl.headerStartColor,       // Header gradient's top color
			windowEl.headerStopColor         // Header gradient's bottom color
		);		

		// Calculate X position for controlbuttons
		this.closebuttonX = mochaWidth - (windowEl.closable ? 15 : -4);
		this.maximizebuttonX = this.closebuttonX - (windowEl.maximizable ? 19 : 0);
		this.minimizebuttonX = this.maximizebuttonX - (windowEl.minimizable ? 19 : 0);
		
		if ( windowEl.closable )
			this.closebutton(ctx, this.closebuttonX, 15, windowEl.closeColor, 1.0);
		if ( windowEl.maximizable )
			this.maximizebutton(ctx, this.maximizebuttonX, 15, windowEl.maximizeColor, 1.0);
		if ( windowEl.minimizable )
			this.minimizebutton(ctx, this.minimizebuttonX, 15, windowEl.minimizeColor, 1.0); // Minimize
		if ( windowEl.resizable ) 
			this.triangle(ctx, mochaWidth - 20, mochaHeight - 20, 12, 12, windowEl.resizableColor, 1.0); // Resize handle
		
		// Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7.
		this.triangle(ctx, 0, 0, 10, 10, windowEl.resizableColor, 0); 

	},
	// Window body
	bodyRoundedRect: function(ctx, x, y, width, height, radius, rgb){
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ', 100)';
		ctx.beginPath();
		ctx.moveTo(x, y + radius);
		ctx.lineTo(x, y + height - radius);
		ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
		ctx.lineTo(x + width - radius, y + height);
		ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},	
	roundedRect: function(ctx, x, y, width, height, radius, rgb, a){
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.beginPath();
		ctx.moveTo(x, y + radius);
		ctx.lineTo(x, y + height - radius);
		ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
		ctx.lineTo(x + width - radius, y + height);
		ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},	
	// Window header with gradient background
	topRoundedRect: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor){

		// Create gradient
		if (Browser.Engine.presto != null ){
			var lingrad = ctx.createLinearGradient(0, 0, 0, this.options.headerHeight + 2);
		}
		else {
			var lingrad = ctx.createLinearGradient(0, 0, 0, this.options.headerHeight);
		}

		lingrad.addColorStop(0, 'rgba(' + headerStartColor.join(',') + ', 100)');
		lingrad.addColorStop(1, 'rgba(' + headerStopColor.join(',') + ', 100)');
		ctx.fillStyle = lingrad;

		// Draw header
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.lineTo(x, y + height);
		ctx.lineTo(x + width, y + height);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},
	// Resize handle
	triangle: function(ctx, x, y, width, height, rgb, a){
		ctx.beginPath();
		ctx.moveTo(x + width, y);
		ctx.lineTo(x, y + height);
		ctx.lineTo(x + width, y + height);
		ctx.closePath();
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	drawCircle: function(ctx, x, y, diameter, rgb, a){
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, diameter, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	maximizebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, 7, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// X sign
		ctx.beginPath();
		ctx.moveTo(x, y - 4);
		ctx.lineTo(x, y + 4);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x - 4, y);
		ctx.lineTo(x + 4, y);
		ctx.stroke();
	},
	closebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, 7, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// Plus sign
		ctx.beginPath();
		ctx.moveTo(x - 3, y - 3);
		ctx.lineTo(x + 3, y + 3);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x + 3, y - 3);
		ctx.lineTo(x - 3, y + 3);
		ctx.stroke();
	},
	minimizebutton: function(ctx, x, y, rgb, a){ // This could reuse the drawCircle method above
		// Circle
		ctx.beginPath();
		ctx.moveTo(x,y);
		ctx.arc(x,y,7,0,Math.PI*2,true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
		// Minus sign
		ctx.beginPath();
		ctx.moveTo(x - 4, y);
		ctx.lineTo(x + 4, y);
		ctx.stroke();
	},
	hideLoadingIcon: function(canvas) {
		$(canvas).setStyle('display', 'none');		
		$clear(canvas.iconAnimation);
	},	
	/*
	
	Method: showLoadingIcon	

	*/	 
	showLoadingIcon: function(canvas) {
		$(canvas).setStyles({
			'display': 'block'
		});		
		var t = 1;	  	
		var iconAnimation = function(canvas){ 
			var ctx = $(canvas).getContext('2d');
			ctx.clearRect(0, 0, 18, 18); // Clear canvas
			ctx.save();
			ctx.translate(9, 9);
			ctx.rotate(t*(Math.PI / 8));	
			var color = 0;
			for (i=0; i < 8; i++){ // Draw individual dots
				color = Math.floor(255 / 8 * i);
				ctx.fillStyle = "rgb(" + color + "," + color + "," + color + ")";  	
				ctx.rotate(-Math.PI / 4);
				ctx.beginPath();
				ctx.arc(0, 7, 2, 0, Math.PI*2, true);
				ctx.fill();
			}
    		ctx.restore();			
			t++;			
		}.bind(this);
		canvas.iconAnimation = iconAnimation.periodical(125, this, canvas);
	},	
	setMochaControlsWidth: function(windowEl, subElements){
		var controlWidth = 14;
		var marginWidth = 5;
		this.mochaControlsWidth = 0;
		if ( windowEl.minimizable )
			this.mochaControlsWidth += (marginWidth + controlWidth);
		if ( windowEl.maximizable ) {
			this.mochaControlsWidth += (marginWidth + controlWidth);
			subElements.maximizeButton.setStyle('margin-left', marginWidth);
		}
		if ( windowEl.closable ) {
			this.mochaControlsWidth += (marginWidth + controlWidth);
			subElements.closeButton.setStyle('margin-left', marginWidth);
		}
		subElements.controls.setStyle('width', this.mochaControlsWidth);
	},
	toggleDock: function(){
			
				if ( !this.dockVisible ) {
					this.dock.setStyle('display', 'block'); 
					this.dockVisible = true;
					this.setDesktopSize();
				}
				else {
					this.dock.setStyle('display', 'none'); 
					this.dockVisible = false;
					this.setDesktopSize();
				}					
	},
	initializeDock: function (){
			this.dock.setStyles({
				'display':  'block',		   
				'position': 'absolute',
				'top':      null,
				'bottom':   0,
				'left':     0
			});
			

		
		this.dock.setStyle('display', 'none'); 
		this.dockVisible = false;
		this.setDesktopSize();		
			
		// Probably: this event should be added/removed when toggling AutoHide, since we dont need it when AutoHide is turned off
		// this.dockVisible tracks the status of the dock, so that showing/hiding is not done when not needed
		
		document.addEvent('mousemove', function(event) {
			if ( !this.dockAutoHide )
				return;
			var ev = new Event(event);
			if ( ev.client.y > (document.getCoordinates().height - 25) ) {
				if ( !this.dockVisible ) {
					this.dock.setStyle('display', 'block'); 
					this.dockVisible = true;
					this.setDesktopSize();
				}
			} else {
				if ( this.dockVisible ) {
					this.dock.setStyle('display', 'none'); 
					this.dockVisible = false;
					this.setDesktopSize();
				}
			}
		}.bind(this));
		

		// Insert canvas
		var canvas = new Element('canvas', {
			'class':  'mochaCanvas',
			'id':     'dockCanvas',
			'width':  '15',
			'height': '18'
		}).injectInside(this.dock).setStyles({
			position: 'absolute',
			top:      '4px',
			left:     '2px',
			zIndex:   2
		});
		
		// Dynamically initialize canvas using excanvas. This is only required by IE
		if (Browser.Engine.trident && this.ieSupport == 'excanvas') {
			G_vmlCanvasManager.initElement(canvas);
		}		

		// Position top or bottom selector
		$('mochaDockPlacement').setProperty('title','Position Dock Top');
			
		// Auto Hide toggle switch
		$('mochaDockAutoHide').setProperty('title','Turn Auto Hide On');
		
		// Attach event
		$('mochaDockPlacement').addEvent('click', function(event){
			var ctx = this.dock.getElement('.mochaCanvas').getContext('2d');
			
			// Move dock to top position
			if (this.dock.getStyle('position') != 'relative'){
				this.dock.setStyles({
					'position':      'relative',
					'bottom':         null,
					'border-top':    '1px solid #fff',
					'border-bottom': '1px solid #bbb'
				})
				this.setDesktopSize();
				this.dock.setProperty('dockPosition','Top');	
				this.drawCircle(ctx, 5, 4, 3, [0, 255, 0], 1.0); // green
				this.drawCircle(ctx, 5, 14, 3, [212, 208, 200], 1.0); // gray
				$('mochaDockPlacement').setProperty('title', 'Position Dock Bottom');				
				$('mochaDockAutoHide').setProperty('title', 'Auto Hide Disabled in Top Dock Position');
				this.dockAutoHide = false;
			}
			// Move dock to bottom position
			else {
				this.dock.setStyles({
					'position':      'absolute',
					'bottom':        0,
					'border-top':    '1px solid #bbb',
					'border-bottom': '1px solid #fff'
				})
				this.setDesktopSize();				
				this.dock.setProperty('dockPosition','Bottom');
				this.drawCircle(ctx, 5, 4, 3, [241, 102, 116], 1.0); // orange		
				this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange 
				$('mochaDockPlacement').setProperty('title', 'Position Dock Top');					
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide On');	 		
			}

		}.bind(this));

		// Attach event Auto Hide 
		$('mochaDockAutoHide').addEvent('click', function(event){
			if ( this.dock.getProperty('dockPosition') == 'Top' )
				return false;
			
			var ctx = this.dock.getElement('.mochaCanvas').getContext('2d');
			this.dockAutoHide = !this.dockAutoHide;	// Toggle
			if ( this.dockAutoHide ) {
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide Off');
				this.drawCircle(ctx, 5 , 14, 3, [0, 255, 0], 1.0); // green
			} else {
				$('mochaDockAutoHide').setProperty('title', 'Turn Auto Hide On');
				this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange
			}
		}.bind(this));
		
		this.drawDock(this.dock);		
	},
	drawDock: function (el){
		var ctx = el.getElement('.mochaCanvas').getContext('2d');
		this.drawCircle(ctx, 5 , 4, 3, [241, 102, 116], 1.0);  // orange
		this.drawCircle(ctx, 5 , 14, 3, [241, 102, 116], 1.0); // orange
	},
	dynamicResize: function (windowEl){				
			this.getSubElement(windowEl, 'contentWrapper').setStyle('height', this.getSubElement(windowEl, 'content').offsetHeight);
			this.drawWindow(windowEl);		
	},
	/*
	
	Method: arrangeCascade
	
	*/	
	arrangeCascade: function(){
		var x = this.options.desktopLeftOffset
		var y = this.options.desktopTopOffset;
		$$('div.mocha').each(function(windowEl){
			if (!windowEl.isMinimized && !windowEl.isMaximized){
				this.focusWindow(windowEl);
				x += this.options.mochaLeftOffset;
				y += this.options.mochaTopOffset;
				
				if (this.options.effects == false){	
					windowEl.setStyles({
						'top': y,
						'left': x
					});
				}				
				else {
					var cascadeMorph = new Fx.Morph(windowEl, {
						'duration': 550
					});
					cascadeMorph.start({
						'top': y,
						'left': x
					});
				}
			}
		}.bind(this));
	},
	/*
	
	Method: garbageCleanup
	
	Notes: Empties an all windows of their children, removes and garbages the windows.
	It is does not trigger onClose() or onCloseComplete().
	This is useful to clear memory before the pageUnload. 
	
	*/	
	garbageCleanUp: function() {
		$$('div.mocha').each(function(el) {
			el.destroy();
		}.bind(this));		
	}	
});
MochaUI.implement(new Options);

/* -----------------------------------------------------------------

	MOCHA SCREENS
	Notes: This class can be removed if you are not creating multiple screens/workspaces.

   ----------------------------------------------------------------- */

var MochaScreens = new Class({
	options: {
		defaultScreen: 0 // Default screen	
	},
	initialize: function(options){
		this.setOptions(options);
		this.setScreen(this.options.defaultScreen);
	},
	setScreen: function(index) {
		if ( !$('mochaScreens') )
			return;
		$$('#mochaScreens div.screen').each(function(el,i) {
			el.setStyle('display', i == index ? 'block' : 'none');
		});
	}
});
MochaScreens.implement(new Options);

/* -----------------------------------------------------------------

	MOCHA WINDOW FROM FORM
	Notes: This class can be removed if you are not creating new windows dynamically from a form.

   ----------------------------------------------------------------- */

var MochaWindowForm = new Class({
	options: {
		id: null,
		title: 'New Window',
		loadMethod: 'html', // html, xhr, or iframe
		content: '', // used if loadMethod is set to 'html'
		contentURL: 'pages/lipsum.html', // used if loadMethod is set to 'xhr' or 'iframe'
		modal: false,
		width: 300,
		height: 125,
		scrollbars: true, // true sets the overflow to auto and false sets it to hidden
		x: null, // if x or y is null or modal is false the new window is centered in the browser window
		y: null,
		paddingVertical: 10,
		paddingHorizontal: 12
	},
	initialize: function(options){
		this.setOptions(options);
		this.options.id = 'win' + (++document.mochaUI.windowIDCount);		
		this.options.title = $('mochaNewWindowHeaderTitle').value;
		if ($('htmlLoadMethod').checked){
			this.options.loadMethod = 'html';
		}
		if ($('xhrLoadMethod').checked){
			this.options.loadMethod = 'xhr';
		}
		if ($('iframeLoadMethod').checked){
			this.options.loadMethod = 'iframe';
		}
		this.options.content = $('mochaNewWindowContent').value;
		if ($('mochaNewWindowContentURL').value){
			this.options.contentURL = $('mochaNewWindowContentURL').value;
		}		
		if ($('mochaNewWindowModal').checked) {
			this.options.modal = true;
		}
		this.options.width = $('mochaNewWindowWidth').value.toInt();
		this.options.height = $('mochaNewWindowHeight').value.toInt();	
		this.options.x = $('mochaNewWindowX').value.toInt();
		this.options.y = $('mochaNewWindowY').value.toInt();
		this.options.paddingVertical = $('mochaNewWindowPaddingVertical').value.toInt();
		this.options.paddingHorizontal = $('mochaNewWindowPaddingHorizontal').value.toInt();
		document.mochaUI.newWindow(this.options);		
	}
});
MochaWindowForm.implement(new Options);


/* -----------------------------------------------------------------

	Corner Radius Slider
	Notes: Remove this function and it's reference in onload if you are not
	using the example corner radius slider

   ----------------------------------------------------------------- */

function addSlider(){
	if ($('sliderarea')) {
		mochaSlide = new Slider($('sliderarea'), $('sliderknob'), {
			steps: 20,
			offset: 5,
			onChange: function(pos){
				$('updatevalue').setHTML(pos);
				document.mochaUI.options.cornerRadius = pos;
				$$('div.mocha').each(function(windowEl, i) {
					document.mochaUI.drawWindow(windowEl);
				});
				document.mochaUI.indexLevel++; 
			}
		}).set(document.mochaUI.options.cornerRadius);
	}
}

/* -----------------------------------------------------------------

	Initialize Everything onLoad

   ----------------------------------------------------------------- */

window.addEvent('domready', function(){							 
		document.mochaScreens = new MochaScreens();
		document.mochaUI = new MochaUI();
		attachMochaLinkEvents(); // See mocha-events.js
		addSlider();             // remove this if you remove the example corner radius slider		
});

// This runs when a person leaves your page.
window.addEvent('unload', function(){
		if (document.mochaUI) document.mochaUI.garbageCleanUp();
});





if(!window.CanvasRenderingContext2D){(function(){var I=Math,i=I.round,L=I.sin,M=I.cos,m=10,A=m/2,Q={init:function(a){var b=a||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=this;b.attachEvent("onreadystatechange",function(){c.r(b)})}},r:function(a){if(a.readyState=="complete"){if(!a.namespaces["s"]){a.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var b=a.createStyleSheet();b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";
var c=a.getElementsByTagName("canvas");for(var d=0;d<c.length;d++){if(!c[d].getContext){this.initElement(c[d])}}}},q:function(a){var b=a.outerHTML,c=a.ownerDocument.createElement(b);if(b.slice(-2)!="/>"){var d="/"+a.tagName,e;while((e=a.nextSibling)&&e.tagName!=d){e.removeNode()}if(e){e.removeNode()}}a.parentNode.replaceChild(c,a);return c},initElement:function(a){a=this.q(a);a.getContext=function(){if(this.l){return this.l}return this.l=new K(this)};a.attachEvent("onpropertychange",V);a.attachEvent("onresize",
W);var b=a.attributes;if(b.width&&b.width.specified){a.style.width=b.width.nodeValue+"px"}else{a.width=a.clientWidth}if(b.height&&b.height.specified){a.style.height=b.height.nodeValue+"px"}else{a.height=a.clientHeight}return a}};function V(a){var b=a.srcElement;switch(a.propertyName){case "width":b.style.width=b.attributes.width.nodeValue+"px";b.getContext().clearRect();break;case "height":b.style.height=b.attributes.height.nodeValue+"px";b.getContext().clearRect();break}}function W(a){var b=a.srcElement;
if(b.firstChild){b.firstChild.style.width=b.clientWidth+"px";b.firstChild.style.height=b.clientHeight+"px"}}Q.init();var R=[];for(var E=0;E<16;E++){for(var F=0;F<16;F++){R[E*16+F]=E.toString(16)+F.toString(16)}}function J(){return[[1,0,0],[0,1,0],[0,0,1]]}function G(a,b){var c=J();for(var d=0;d<3;d++){for(var e=0;e<3;e++){var g=0;for(var h=0;h<3;h++){g+=a[d][h]*b[h][e]}c[d][e]=g}}return c}function N(a,b){b.fillStyle=a.fillStyle;b.lineCap=a.lineCap;b.lineJoin=a.lineJoin;b.lineWidth=a.lineWidth;b.miterLimit=
a.miterLimit;b.shadowBlur=a.shadowBlur;b.shadowColor=a.shadowColor;b.shadowOffsetX=a.shadowOffsetX;b.shadowOffsetY=a.shadowOffsetY;b.strokeStyle=a.strokeStyle;b.d=a.d;b.e=a.e}function O(a){var b,c=1;a=String(a);if(a.substring(0,3)=="rgb"){var d=a.indexOf("(",3),e=a.indexOf(")",d+1),g=a.substring(d+1,e).split(",");b="#";for(var h=0;h<3;h++){b+=R[Number(g[h])]}if(g.length==4&&a.substr(3,1)=="a"){c=g[3]}}else{b=a}return[b,c]}function S(a){switch(a){case "butt":return"flat";case "round":return"round";
case "square":default:return"square"}}function K(a){this.a=J();this.m=[];this.k=[];this.c=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=m*1;this.globalAlpha=1;this.canvas=a;var b=a.ownerDocument.createElement("div");b.style.width=a.clientWidth+"px";b.style.height=a.clientHeight+"px";b.style.overflow="hidden";b.style.position="absolute";a.appendChild(b);this.j=b;this.d=1;this.e=1}var j=K.prototype;j.clearRect=function(){this.j.innerHTML=
"";this.c=[]};j.beginPath=function(){this.c=[]};j.moveTo=function(a,b){this.c.push({type:"moveTo",x:a,y:b});this.f=a;this.g=b};j.lineTo=function(a,b){this.c.push({type:"lineTo",x:a,y:b});this.f=a;this.g=b};j.bezierCurveTo=function(a,b,c,d,e,g){this.c.push({type:"bezierCurveTo",cp1x:a,cp1y:b,cp2x:c,cp2y:d,x:e,y:g});this.f=e;this.g=g};j.quadraticCurveTo=function(a,b,c,d){var e=this.f+0.6666666666666666*(a-this.f),g=this.g+0.6666666666666666*(b-this.g),h=e+(c-this.f)/3,l=g+(d-this.g)/3;this.bezierCurveTo(e,
g,h,l,c,d)};j.arc=function(a,b,c,d,e,g){c*=m;var h=g?"at":"wa",l=a+M(d)*c-A,n=b+L(d)*c-A,o=a+M(e)*c-A,f=b+L(e)*c-A;if(l==o&&!g){l+=0.125}this.c.push({type:h,x:a,y:b,radius:c,xStart:l,yStart:n,xEnd:o,yEnd:f})};j.rect=function(a,b,c,d){this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath()};j.strokeRect=function(a,b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.stroke()};j.fillRect=function(a,
b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.fill()};j.createLinearGradient=function(a,b,c,d){var e=new H("gradient");return e};j.createRadialGradient=function(a,b,c,d,e,g){var h=new H("gradientradial");h.n=c;h.o=g;h.i.x=a;h.i.y=b;return h};j.drawImage=function(a,b){var c,d,e,g,h,l,n,o,f=a.runtimeStyle.width,k=a.runtimeStyle.height;a.runtimeStyle.width="auto";a.runtimeStyle.height="auto";var q=a.width,r=a.height;a.runtimeStyle.width=
f;a.runtimeStyle.height=k;if(arguments.length==3){c=arguments[1];d=arguments[2];h=(l=0);n=(e=q);o=(g=r)}else if(arguments.length==5){c=arguments[1];d=arguments[2];e=arguments[3];g=arguments[4];h=(l=0);n=q;o=r}else if(arguments.length==9){h=arguments[1];l=arguments[2];n=arguments[3];o=arguments[4];c=arguments[5];d=arguments[6];e=arguments[7];g=arguments[8]}else{throw"Invalid number of arguments";}var s=this.b(c,d),t=[],v=10,w=10;t.push(" <g_vml_:group",' coordsize="',m*v,",",m*w,'"',' coordorigin="0,0"',
' style="width:',v,";height:",w,";position:absolute;");if(this.a[0][0]!=1||this.a[0][1]){var x=[];x.push("M11='",this.a[0][0],"',","M12='",this.a[1][0],"',","M21='",this.a[0][1],"',","M22='",this.a[1][1],"',","Dx='",i(s.x/m),"',","Dy='",i(s.y/m),"'");var p=s,y=this.b(c+e,d),z=this.b(c,d+g),B=this.b(c+e,d+g);p.x=Math.max(p.x,y.x,z.x,B.x);p.y=Math.max(p.y,y.y,z.y,B.y);t.push("padding:0 ",i(p.x/m),"px ",i(p.y/m),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else{t.push("top:",
i(s.y/m),"px;left:",i(s.x/m),"px;")}t.push(' ">','<g_vml_:image src="',a.src,'"',' style="width:',m*e,";"," height:",m*g,';"',' cropleft="',h/q,'"',' croptop="',l/r,'"',' cropright="',(q-h-n)/q,'"',' cropbottom="',(r-l-o)/r,'"'," />","</g_vml_:group>");this.j.insertAdjacentHTML("BeforeEnd",t.join(""))};j.stroke=function(a){var b=[],c=O(a?this.fillStyle:this.strokeStyle),d=c[0],e=c[1]*this.globalAlpha,g=10,h=10;b.push("<g_vml_:shape",' fillcolor="',d,'"',' filled="',Boolean(a),'"',' style="position:absolute;width:',
g,";height:",h,';"',' coordorigin="0 0" coordsize="',m*g," ",m*h,'"',' stroked="',!a,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',d,'"',' path="');var l={x:null,y:null},n={x:null,y:null};for(var o=0;o<this.c.length;o++){var f=this.c[o];if(f.type=="moveTo"){b.push(" m ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="lineTo"){b.push(" l ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="close"){b.push(" x ")}else if(f.type=="bezierCurveTo"){b.push(" c ");
var k=this.b(f.x,f.y),q=this.b(f.cp1x,f.cp1y),r=this.b(f.cp2x,f.cp2y);b.push(i(q.x),",",i(q.y),",",i(r.x),",",i(r.y),",",i(k.x),",",i(k.y))}else if(f.type=="at"||f.type=="wa"){b.push(" ",f.type," ");var k=this.b(f.x,f.y),s=this.b(f.xStart,f.yStart),t=this.b(f.xEnd,f.yEnd);b.push(i(k.x-this.d*f.radius),",",i(k.y-this.e*f.radius)," ",i(k.x+this.d*f.radius),",",i(k.y+this.e*f.radius)," ",i(s.x),",",i(s.y)," ",i(t.x),",",i(t.y))}if(k){if(l.x==null||k.x<l.x){l.x=k.x}if(n.x==null||k.x>n.x){n.x=k.x}if(l.y==
null||k.y<l.y){l.y=k.y}if(n.y==null||k.y>n.y){n.y=k.y}}}b.push(' ">');if(typeof this.fillStyle=="object"){var v={x:"50%",y:"50%"},w=n.x-l.x,x=n.y-l.y,p=w>x?w:x;v.x=i(this.fillStyle.i.x/w*100+50)+"%";v.y=i(this.fillStyle.i.y/x*100+50)+"%";var y=[];if(this.fillStyle.p=="gradientradial"){var z=this.fillStyle.n/p*100,B=this.fillStyle.o/p*100-z}else{var z=0,B=100}var C={offset:null,color:null},D={offset:null,color:null};this.fillStyle.h.sort(function(T,U){return T.offset-U.offset});for(var o=0;o<this.fillStyle.h.length;o++){var u=
this.fillStyle.h[o];y.push(u.offset*B+z,"% ",u.color,",");if(u.offset>C.offset||C.offset==null){C.offset=u.offset;C.color=u.color}if(u.offset<D.offset||D.offset==null){D.offset=u.offset;D.color=u.color}}y.pop();b.push("<g_vml_:fill",' color="',D.color,'"',' color2="',C.color,'"',' type="',this.fillStyle.p,'"',' focusposition="',v.x,", ",v.y,'"',' colors="',y.join(""),'"',' opacity="',e,'" />')}else if(a){b.push('<g_vml_:fill color="',d,'" opacity="',e,'" />')}else{b.push("<g_vml_:stroke",' opacity="',
e,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',S(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',d,'" />')}b.push("</g_vml_:shape>");this.j.insertAdjacentHTML("beforeEnd",b.join(""));this.c=[]};j.fill=function(){this.stroke(true)};j.closePath=function(){this.c.push({type:"close"})};j.b=function(a,b){return{x:m*(a*this.a[0][0]+b*this.a[1][0]+this.a[2][0])-A,y:m*(a*this.a[0][1]+b*this.a[1][1]+this.a[2][1])-A}};j.save=function(){var a={};N(this,a);
this.k.push(a);this.m.push(this.a);this.a=G(J(),this.a)};j.restore=function(){N(this.k.pop(),this);this.a=this.m.pop()};j.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];this.a=G(c,this.a)};j.rotate=function(a){var b=M(a),c=L(a),d=[[b,c,0],[-c,b,0],[0,0,1]];this.a=G(d,this.a)};j.scale=function(a,b){this.d*=a;this.e*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];this.a=G(c,this.a)};j.clip=function(){};j.arcTo=function(){};j.createPattern=function(){return new P};function H(a){this.p=a;this.n=0;this.o=
0;this.h=[];this.i={x:0,y:0}}H.prototype.addColorStop=function(a,b){b=O(b);this.h.push({offset:1-a,color:b})};function P(){}G_vmlCanvasManager=Q;CanvasRenderingContext2D=K;CanvasGradient=H;CanvasPattern=P})()};



    // Copyright 2008 www.flexcapacitor.com, www.drumbeatinsight.com 
    // Version 4.0
    
    // global array of html elements
    var fcHTMLControls = new Array();
    var fcEventTimeoutInterval = 200;
    var fcExistingOnBeforeUnload;
    var fcRelativeMovie = false;
	
    // blur xinha editor
    function fcAddBlurHandler() {
		this._doc.xinhaEditor = this;
		Xinha._addEvent(this._doc, "blur", function() {
			var movie = fcGetMovieById(this.xinhaEditor.movieId);
			//movie.xinhaBlur();
			window.focus();
			movie.focus();
		});
    }
    
	// add HTML element to the page
    function fcAddChild(o) {
    	var movie = fcGetMovieById(o.movieId);
    	fcHTMLControls.movieId = o.movieId;
    	
    	if (String(o.chrome)=="true") {
    		fcAddChildPopUp(o);
    	}
    	else if (o.type=="division") {
    		fcAddChildDivision(o);
    	}
    	else if (o.type=="iframe") {
    		fcAddChildIFrame(o);
    	}
    	else if (o.type=="editor") {
    		fcAddChildEditor(o);
    	}
    }
    
    // add division to the page
    function fcAddChildDivision(o) {
		fcGetIncludes(o.includesBefore);
		var newElement = document.createElement("div");
		newElement.id = o.id;
		newElement.name = o.name;
		newElement.movieId = o.movieId;
		
		newElement.style.position = o.position;
		
		if (String(o.fitToContentHeight)=="true") {
			o.height = "";
		}
		fcSetSize(newElement,o.width,o.height);
		fcMoveElementTo(newElement,o.x,o.y);
		newElement.style.backgroundColor = "#" + o.backgroundColor;
		newElement.style.padding = o.padding;
		newElement.style.margin = "0px";
		// always 0px - do not add a border to the container div tag
		// add a border in mxml or add a child div tag in the htmlText property and add a border to that
		newElement.style.border = o.border;
		newElement.innerHTML = o.htmlText;
		
		document.body.appendChild(newElement);
		
		fcAddToGlobalArray(newElement, o);
		fcSetScrollPolicyById(o.id, o.htmlScrollPolicy);
		
		fcGetIncludes(o.includesAfter);
		
		if (String(o.visible)=="false") {
			fcHide(o.id,true,false);
		}
		
		fcDelayedDispatchEvent("htmlCreationComplete", o.movieId, o.id, fcEventTimeoutInterval);
    }
    
    // add an editor to the page
    function fcAddChildEditor(o) {
    	// Add new editors here
		// There are three places to add new editor support. 
		// here, getHTML, setHTML and if possible, call htmlCreationComplete when the editor has been created
		// see FCKeditor_OnComplete for an example
		
    	// if the editor is generated with the same id, same textarea should be used
		var el = document.getElementById(o.id);
		if (el!=null) return;
		
		// we add this control early on editors 
		fcHTMLControls[o.id] = new Object();
	
		fcGetIncludes(o.includesBefore);
		var editorName = o.name + "Editor";
		var newElement = document.createElement("div");
		newElement.id = o.id;
		newElement.name = o.name;
		newElement.movieId = o.movieId;
		
		newElement.style.position = o.position;
		fcSetSize(newElement,o.width,o.height);
		fcMoveElementTo(newElement,o.x,o.y);
		newElement.style.backgroundColor = "#" + o.backgroundColor;
		newElement.style.padding = o.padding;
		newElement.style.margin = "0px";
		newElement.style.border = o.border;
		
		var textareaElement = document.createElement("textarea");
		textareaElement.id = editorName;
		textareaElement.name = editorName;
		textareaElement.value = o.htmlText;
		fcSetSize(textareaElement,"100%","100%");
		newElement.appendChild(textareaElement);
		
		document.body.appendChild(newElement);
		fcSetScrollPolicyById(o.id, o.htmlScrollPolicy);
		
		// add additional editor support here
		if (o.editorType=="fckeditor") {
			// Create an instance of FCKeditor (using the target textarea as the name).
			var oFCKeditor = new FCKeditor( editorName ) ;
			oFCKeditor.BasePath = o.editorPath;
			if (o.configPath) {
				oFCKeditor.Config["CustomConfigurationsPath"] = o.configPath +"?" + ( new Date() * 1 ) ;
			}
			oFCKeditor.Width = '100%';
			oFCKeditor.Height = '100%';
			oFCKeditor.ReplaceTextarea();
			
			fcHTMLControls[o.id].editor = oFCKeditor;
		}
		else if (o.editorType=="tinymce") {
		    var elm = document.getElementById(o.id);
		    
			if (typeof o.editorOptions == "string") {
				// crashes firefox??? maybe set a timeout?
				//tinyMCE.init({mode:"exact",theme:"simple"});
			}
			else {
				tinyMCE.init(o.editorOptions);
			}
			
			if (tinyMCE.getInstanceById(editorName) == null) {
				// cannot find editor sometimes. causes crash. maybe set a timeout?
				//tinyMCE.execCommand('mceAddControl', false, editorName);
			}
			fcHTMLControls[o.id].editor = elm
			fcHTMLControls[o.id].loaded = true;
			// when editor is ready dispatch creation complete
			//fcDelayedDispatchEvent("htmlCreationComplete", o.movieId, o.id, fcEventTimeoutInterval);
		}
		else if (o.editorType=="xinha") {
			// if script not declared use only textarea
			if (typeof Xinha != "undefined") {
				var c = new Xinha.Config();
				c.showLoading = true;
				var ed = new Xinha(editorName, c);
				fcHTMLControls[o.id].editor = ed
				ed.movieId = o.movieId;
				ed.generate();
				ed._onGenerate = fcAddBlurHandler;
				ed.whenDocReady = function(e) {
					fcHTMLControls[o.id].loaded = true;
					fcDelayedDispatchEvent("htmlCreationComplete", o.movieId, o.id, fcEventTimeoutInterval);
				}
			} else {
				fcHTMLControls[o.id].editor = textareaElement;
			}
		}
		
		fcAddToGlobalArray(newElement, o);
		
		if (String(o.visible)=="false") {
			fcHide(o.id,true,false);
		}
		
    }
    
    // add iframe to the page
    function fcAddChildIFrame(o) {
		var newElement = document.createElement("iframe");
		newElement.id = o.id;
		newElement.name = o.name;
		newElement.movieId = o.movieId;
		newElement.width = o.width;
		newElement.height = o.height;
		newElement.frameBorder = o.frameborder;
		newElement.style.position = o.position;
		fcSetSize(newElement,o.width,o.height);
		fcMoveElementTo(newElement,o.x,o.y);
		//newElement.style.backgroundColor = "transparent";
		// always 0px - do not add a border to the iframe itself
		// add a child div and add a border to that or add border in mxml
		newElement.style.border = o.border;
		newElement.style.padding = o.padding;
		newElement.src = o.source;
		
		//  use innerHTML or DOM element creation methods to put content into body
		document.body.appendChild(newElement);
		
		newElement.onload = new function() {
			// set a flag so the application knows the page is loaded
			fcDelayedDispatchEvent("htmlCreationComplete", o.movieId, o.id, fcEventTimeoutInterval);
		}
		
		newElement.onunload = new function() {
			// set a flag so the application knows the page is unloading
			// can we purge this from memory here?
			fcDispatchEvent("htmlUnload", o.movieId, o.id);
		}
		
		fcAddToGlobalArray(newElement, o);
		
		if (String(o.visible)=="false") {
			fcHide(o.id,true,false);
		}
		
    }
    
    // add mocha ui pop up to the page
    function fcAddChildPopUp(o) {
		fcGetIncludes(o.includesBefore);
		var p = new Object();
		p.id = o.id;
		p.content = o.htmlText;
		p.x = o.x;
		p.y = o.y;
		if (String(o.centerPopUp)!="true") {
			p.x = o.x;
			p.y = o.y;
		}
		p.contentURL = String(o.source);
		p.bodyBgColor = "" + o.backgroundColor;
		p.title = o.title;
		p.modal = o.modal;
		p.width = o.width;
		p.height = o.height;
		p.minimizable = o.minimizable;
		p.maximizable = o.maximizable;
		//p.paddingVertical = parseInt(o.padding); 10
		//p.paddingHorizontal = parseInt(o.padding); 12
		
		p.onContentLoaded = function (e) {
			fcDelayedDispatchEvent("htmlPopUpContentLoaded", o.movieId, o.id, fcEventTimeoutInterval)
		}
		p.onFocus = function (e) {
			fcDispatchEvent("htmlPopUpFocus", o.movieId, o.id)
		}
		p.onResize = function (e) {
			fcDispatchEvent("htmlPopUpResize", o.movieId, o.id)
		}
		p.onMinimize = function (e) {
			fcDispatchEvent("htmlPopUpMinimize", o.movieId, o.id)
		}
		p.onMaximize = function (e) {
			fcDispatchEvent("htmlPopUpMaximize", o.movieId, o.id)
		}
		p.onClose = function (e) {
			// we need to listen to this event and handle it in flex html manager class for alerts
			fcDispatchEvent("htmlPopUpClose", o.movieId, o.id)
		}
		p.onCloseComplete = function (e) {
			fcDispatchEvent("htmlPopUpCloseComplete", o.movieId, o.id)
		}
		
		// html, xhr, or iframe
		if (o.type == "division") {
			p.loadMethod = "html";
		}
		else if (o.type == "iframe") {
			p.loadMethod = "iframe";
		}
		else if (o.type == "xhr") {
			p.loadMethod = "xhr";
		}
		
		if (String(o.chrome)=="true" && document.mochaUI) {
			document.mochaUI.newWindow(p, false);
		}
		
		fcAddToGlobalArray(fcGetElement(o.id), o);
		
		fcGetIncludes(o.includesAfter);
		
		if (String(o.visible)=="false") {
			//fcHide(o.id,true,false);
		}
		
		// dispatch when window is created
		fcDelayedDispatchEvent("htmlCreationComplete", o.movieId, o.id, fcEventTimeoutInterval);
		if (String(o.alert)=="true") {
			var newElement = document.createElement("div");
			newElement.id = o.id + "_alert_buttons";
			newElement.movieId = o.movieId;
			//newElement.style.position = "absolute";
			//newElement.style.bottom = "6px";
			//newElement.style.right = "6px";
			newElement.className = "mochaAlertButtons"; // set in css/mocha.css
			
			for (var i=0;i<o.alertButtons.length;i++) {
				var button = document.createElement("input");
				var value = o.alertButtons[i];
				button.type = "button";
				button.value = value;
				button.className = "mochaAlertButton"; // set in css/mocha.css
				
				button.onclick = function(e) {
					fcDispatchEvent2("htmlAlertHandler", o.movieId, o.id, this.value);
					var el = fcGetElement(o.id);
					if(document.mochaUI) {
						document.mochaUI.closeWindow(el);
					}
				}
				newElement.appendChild(button);
			}
			
			var el = fcGetElement(o.id);
			el.appendChild(newElement);
		}
    }
    
	//usage: var currentTarget = fcEventTrigger (e);
    function fcEventTrigger (e) {
    	if (!e) { e = event; }
    	return e.target || e.srcElement;
	}
    
	// add to associative array - do we need to make any changes for garbage collecting?
	function fcAddToGlobalArray(el, o) {
		var newElement = new Object();
		newElement.element = el; // could cause memory leak do we need it?
		newElement.id = o.id;
		newElement.loaded = false;
		newElement.type = o.type;
		newElement.popUp = o.chrome;
		newElement.alert = o.alert;
		newElement.movieId = o.movieId;
		if (o.type == "editor") {
			// set first in addChildEditor
			newElement.editor = fcHTMLControls[o.id].editor;
		}
		else {
			newElement.editor = "";
		}
		
		fcHTMLControls[o.id] = newElement;
	}
	
	// evaluates a script and returns the value - note use ExternalInterface to call functions
	function fcCallScript(str) {
		try {
			var something = eval(str);
			return something;
		}
		catch(e) {
			return false;
		}
	}
	
    // dispatch creation complete event 
	function fcDispatchEvent(eventName, movieId, id) {
		var movie = fcGetMovieById(movieId);
		movie[eventName](id);
	}
	
	// dispatch creation complete event 
	function fcDispatchEvent2(eventName, movieId, id, value) {
		var movie = fcGetMovieById(movieId);
		movie[eventName](id, value);
	}

	// call actionscript function after specified delay
    // we do this to give the browser and flash time to sync
	function fcDelayedDispatchEvent(eventName,movieId,id,delay) {
		setTimeout("fcDispatchEvent('"+eventName+"','"+movieId+"','"+id+"')",delay);
	}

	// handle when flash text field gets focus, text field in iframe is greedy
	function fcDefocus(movieId) {
		var movie = fcGetMovieById(movieId);
		window.focus();
		movie.focus();
	}
	
	// finds the absolute position of the swf movie
	function fcFindPosition(obj) {
		var left = obj.offsetLeft;
		var top = obj.offsetTop;
		if (obj.offsetParent) {
			var parentPos = this.fcFindPosition(obj.offsetParent);
			if (parentPos[0]) left += parentPos[0];
  			if (parentPos[1]) top += parentPos[1];
 		}
		return [left,top];
 	}
    
	// The FCKeditor_OnComplete function is a special function called everytime an
	// editor instance is completely loaded and available for API interactions.
	function FCKeditor_OnComplete(editorInstance) {
		var editor = fcGetElement(editorInstance.Name);
		if (editor) {
			fcHTMLControls[editor.parentNode.id].loaded = true;			
			fcDelayedDispatchEvent("htmlCreationComplete", editor.parentNode.movieId, editor.parentNode.id, fcEventTimeoutInterval);
		}
	}
	
	// gets the element by name
	function fcGetElement(id) {
		return document.getElementById(id);
	}
	
	// cannot get height of pages loaded from different domains
	// ie, page is hosted at www.yoursite.com and you load www.google.com will fail with return value of -1
	// works in ff and ie. not tested in mac browsers - 
	function fcGetElementHeight(id){
		var el = fcGetElement(id);
		moz = (document.getElementById && !document.all);
		
		if (el) {
		
			// check the height value
			try {
			
				/*** return div height ***/
				if (el.nodeName.toLowerCase()=="div") {
					var scrollHeight = el.scrollHeight;
					var divHeight = el.style.height;
					divHeight = (scrollHeight > parseInt(divHeight)) ? scrollHeight : divHeight;
					return divHeight;
				}
				
				/*** return iframe height ***/
				//moz
				if (moz) {
					return el.contentDocument.body.scrollHeight;
				}
				else if (el.Document) {
					return el.Document.body.scrollHeight;
				}
			}
			catch(e) {
				//An error is raised if the content in the iframe is not from the same domain as the swf
				//alert('Error: ' + e.number + '; ' + e.description+'\nPossibly - Cannot access height of iframe because the content is from another dudes domain');
				return -1;
			}
		}
	}

	// get property value
	function fcGetElementValue(id, elProperty){
		
		// if periods are in the name assume absolute path 
		// otherwise assume element id
		if (id.indexOf('.')!=-1) {
			var newArr = id.split('.');
			var elValue = "";
			
			try {
				el = window;
				for (var i=0;i < newArr.length;i++) {
					el = el[newArr[i]];
				}
				return el;
			}
			catch (e) {
				//alert("Whoooops!! Cant find " + id);
				// should return null or undefined here
				return -1;
			}
		}
		else {
			// try and get property value
			try {
				var el = fcGetElement(id);
				var elValue = el[elProperty];
				return elValue;
			}
			catch(e) {
				//alert("Error: Can't find " + id + "." + elProperty);
				// should return null or undefined here
				return -1;
			}
		}
	}
	
	// get HTML content
	function fcGetHTML(id, elementType, editorType, chrome) {
		var el = fcGetElement(id);
		if (el!=null) {
			
			if (elementType =="division" && String(chrome)=="true") {
				var elContent = fcGetElement(id + "_content");
				if (elContent != null) {
					return String(elContent.innerHTML);
				}
			}
			else if (elementType=="division") {
				return el.innerHTML;
			}
			else if (elementType == "editor") {
				var oEditor;
				
				// add additional editor support here
				if (editorType=="fckeditor") {
					if ( typeof( FCKeditorAPI ) != 'undefined' ) {
						oEditor = FCKeditorAPI.GetInstance( id + "Editor" );
						if ( oEditor )	{
							// Get the current text in the editor.
							return oEditor.GetXHTML();
						}
					}
				}
				else if (editorType=="tinymce") {
					return tinyMCE.getContent(id);
				}
				else if (editorType=="xinha") {
					//var ed = editors[id];
					var ed = fcHTMLControls[id].editor;
					if (typeof Xinha != "undefined") {
						return ed.getHTML();
					}
					return ed.value;
				}
				
			}
		}
		return "";
	}

	// get the scripts dynamically to include
	function fcGetIncludes(includes) {
		var len = includes.length;
		//var head = document.getElementsByTagName("head");
		// sometimes this doesn't work. possibly browser or sandbox issues. in those cases edit the html page and add scripts manually
		for (var i=0;i<len;i++) {
			var el = document.createElement("script");
			//el.onload = onload2;
			el.setAttribute("src",includes[i]);
			el.setAttribute("type","text/javascript");
			document.body.appendChild(el);
		}
	}

	// get reference to the flash movie	
	function fcGetMovieById(id) {
		if (navigator.appName.indexOf ("Microsoft") !=-1) {
			return window[id];
		} else {
			return window.document[id];
		}
	}
	
	// hide element by name
	// set height of content to 0px so the 
	// flash context menu appears in the right location
	// note: display none also fixes the issue but have not implemented yet
	function fcHide(id, hideOffscreen, offscreenOffset) {
		var el = fcGetElement(id);
		if (hideOffscreen) {
			//el.style.width = "0px";
			//el.style.height = "0px";
		}
		//el.style.visibility = "hidden";
		el.style.display = "none";
	}
	
	// move element to new location
	function fcMoveElementTo(el,x,y) {
		var movie = fcGetMovieById(el.movieId);
		if (fcRelativeMovie) {
			el.style.left = parseInt(x) + fcFindPosition(movie)[0] + "px";
			el.style.top = parseInt(y) + fcFindPosition(movie)[1] + "px";
		}
		else {
			el.style.left = parseInt(x) + "px";
			el.style.top = parseInt(y) + "px";
		}
	}
	
	// warn user if they or a link try to navigate them away from the page - used to prevent data loss / save changes
	function fcPromptOnUnload(prompt, message) {
		if (String(prompt) == "true") {
			// todo wrap existing function if it exists
			//fcExistingOnBeforeUnload = (window.onbeforeunload!=null) ? window.onbeforeunload : null;
			window.onbeforeunload = function (e) {
				//if (fcExistingOnBeforeUnload) {
				//	fcExistingOnBeforeUnload();
				//}
				//fcPurge(document.body);
				return message;
			};
		}
		else {
			window.onbeforeunload = function (e) {
				// see you later
				//if (fcExistingOnBeforeUnload) {
				//	fcExistingOnBeforeUnload();
				//}
			}
		}
	}
	
	// call before removing from DOM - necessary?
	// credit - http://javascript.crockford.com/memory/leak.html
	function fcPurge(d) {
		var a = d.attributes, i, l, n;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i += 1) {
				n = a[i].name;
				if (typeof d[n] === 'function') {
					d[n] = null;
				}
			}
		}
		a = d.childNodes;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i += 1) {
				fcPurge(d.childNodes[i]);
			}
		}
	}
	
	// forces redraw
	function fcRefresh(id) {
		var el = fcGetElement(id);
		el.style.cssText = el.style.cssText;
	}
	
	// remove and get memory back	
	function fcRemove(id) {
		//fcHide(id, true);
		var el = fcGetElement(id);
		var elParent = el.parentNode;
		fcPurge(el);
		fcHTMLControls[id] = null;
		elParent.removeChild(el);
	}
	
	// clips the html content
	function fcSetClip(id, top, right, bottom, left) {
		var el = fcGetElement(id);
		if (el!=null) {
			el.style.clip = "rect(" + top + " " + right + " " + bottom + " " + left  + ")";
		}
	}
    
	// set document title
    function fcSetDocumentTitle(title) {
        window.document.title = title;
    }
	
	// set HTML content
	function fcSetHTML(id, htmlText, elementType, editorType, chrome) {
		var el = fcGetElement(id);
		if (el!=null) {
		
			if (elementType =="division" && String(chrome)=="true") {
				var elContent = fcGetElement(id + "_content");
				elContent.innerHTML = htmlText;
			}
			else if (elementType =="division") {
				el.innerHTML = htmlText;
			}
			else if (elementType == "editor") {
				var oEditor;
				
				// add additional editor support here
				if (editorType == "fckeditor") {
					if ( typeof( FCKeditorAPI ) != 'undefined' ) {
						oEditor = FCKeditorAPI.GetInstance( id + "Editor" );
						if ( oEditor )	{
							// Set the text in the editor.
							oEditor.SetHTML( htmlText ) ;
						}
					}
				}
				else if (editorType=="tinymce") {
					var editor = tinyMCE.getInstanceById(id+"Editor");
					editor.setHTML(htmlText);
				}
				else if (editorType=="xinha") {
					//var ed = editors[id];
					var ed = fcHTMLControls[id].editor;
					if (typeof Xinha != "undefined") { 
						ed.setEditorContent(htmlText);
					}
					else {
						ed.value = htmlText;
					}
				}
			}
		}
	}
	
	// set position - should we use fcFindPosition here?
	function fcSetPosition(id,x,y) {
		var el = fcGetElement(id);
		var movie = fcGetMovieById(fcHTMLControls[id].movieId);
		if (fcHTMLControls[id].popUp == true ) { return }
		
		// LEFT
		if (x != undefined) {
			el.style.left = parseInt(x) + fcFindPosition(movie)[0] + "px";
		}
		// TOP
		if (y != undefined) {
			el.style.top = parseInt(y) + fcFindPosition(movie)[1] + "px";
		}
	}
	
	// set scroll policy of element
	function fcSetScrollPolicy(el, overflow) {
		if (overflow != "resize") {
			el.style.overflow = overflow;
		}
	}
	
	// save cpu when movie is at upper left corner of window
	function fcSetRelativeMovie(isRelative) {
		fcRelativeMovie = (String(isRelative)!="false") ? true : false;
	}
	
	// set scroll policy of element by id
	function fcSetScrollPolicyById(id, overflow) {
		var el = fcGetElement(id);
		
		// setting this to anything other than auto in ff fails it
		if (overflow != "resize") {
			el.style.overflow = overflow;
		}
	}
	
	// set size
	function fcSetSize(el,w,h) {
		
		if (String(w)!="undefined" && String(w)!="") {
			// if width is a percentage pass in the string as is
			if (String(w).indexOf("%")!=-1) {
				el.style.width = w;
			}
			else {
				el.style.width = parseInt(w) + "px";
			}
		}
		
		if (String(h)!="undefined" && String(h)!="") {
			if (String(h).indexOf("%")!=-1) {
				el.style.height = h;
			}
			else {
				el.style.height = parseInt(h) + "px"; 
			}
		}
	}
	
	// set size called by id
	function fcSetSizeByValue(id,w,h) {
		var el = fcGetElement(id);
		if (el.style.display=="none") { return; }
		if (fcHTMLControls[id].popUp == true ) { return }
		
		if (String(w)!="undefined" && String(w)!="") {
			// if width is a percentage pass in the string as is
			if (String(w).indexOf("%")!=-1) {
				el.style.width = w;
			}
			else {
				el.style.width = parseInt(w) + "px";
			}
		}
		
		if (String(h)!="undefined" && String(h)!="") {
			if (String(h).indexOf("%")!=-1) {
				el.style.height = h;
			}
			else {
				el.style.height = parseInt(h) + "px"; 
			}
		}
	}
	
	// set iframe location
	function fcSetSource(id,source) {
		var el = fcGetElement(id);
		el.src = source;
	}
	
	// show element by name
	// set display to block and we dont have to set size
	function fcShow(id, hideOffscreen, left, width, height) {
		var el = fcGetElement(id);
		//el.style.visibility = "visible";
		el.style.display = "block";
		if (hideOffscreen) {
			//el.style.width = parseInt(width) + "px";
			//el.style.height = parseInt(height) + "px";
		}
	}
	
	function fcFlexOnload(movieId) {
		// calling callback is unreliable - swf movie may not be loaded yet
		//movie.onLoadComplete();
		fcHTMLControls.pageLoaded = "true";
	}
	
	// end of line


BrowserHistoryUtils = {
    addEvent: function(elm, evType, fn, useCapture) {
        useCapture = useCapture || false;
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent) {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else {
            elm['on' + evType] = fn;
        }
    }
}

BrowserHistory = (function() {
    // type of browser
    var browser = {
        ie: false, 
        firefox: false, 
        safari: false, 
        opera: false, 
        version: -1
    };

    // if setDefaultURL has been called, our first clue
    // that the SWF is ready and listening
    //var swfReady = false;

    // the URL we'll send to the SWF once it is ready
    //var pendingURL = '';

    // Default app state URL to use when no fragment ID present
    var defaultHash = '';

    // Last-known app state URL
    var currentHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHash = document.location.hash;

    // History frame source URL prefix (used only by IE)
    var historyFrameSourcePrefix = 'history/historyFrame.html?';

    // History maintenance (used only by Safari)
    var currentHistoryLength = -1;

    var historyHash = [];

    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);

    var backStack = [];
    var forwardStack = [];

    var currentObjectId = null;

    //UserAgent detection
    var useragent = navigator.userAgent.toLowerCase();

    if (useragent.indexOf("opera") != -1) {
        browser.opera = true;
    } else if (useragent.indexOf("msie") != -1) {
        browser.ie = true;
        browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
    } else if (useragent.indexOf("safari") != -1) {
        browser.safari = true;
        browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
    } else if (useragent.indexOf("gecko") != -1) {
        browser.firefox = true;
    }

    if (browser.ie == true && browser.version == 7) {
        window["_ie_firstload"] = false;
    }

    // Accessor functions for obtaining specific elements of the page.
    function getHistoryFrame()
    {
        return document.getElementById('ie_historyFrame');
    }

    function getAnchorElement()
    {
        return document.getElementById('firefox_anchorDiv');
    }

    function getFormElement()
    {
        return document.getElementById('safari_formDiv');
    }

    function getRememberElement()
    {
        return document.getElementById("safari_remember_field");
    }

    /* Get the Flash player object for performing ExternalInterface callbacks. */
    function getPlayer(objectId) {
        var objectId = objectId || null;
        var player = null; /* AJH, needed?  = document.getElementById(getPlayerId()); */
        if (browser.ie && objectId != null) {
            player = document.getElementById(objectId);
        }
        if (player == null) {
            player = document.getElementsByTagName('object')[0];
        }
        
        if (player == null || player.object == null) {
            player = document.getElementsByTagName('embed')[0];
        }

        return player;
    }
    
    function getPlayers() {
        var players = [];
        if (players.length == 0) {
            var tmp = document.getElementsByTagName('object');
            players = tmp;
        }
        
        if (players.length == 0 || players[0].object == null) {
            var tmp = document.getElementsByTagName('embed');
            players = tmp;
        }
        return players;
    }

	function getIframeHash() {
		var doc = getHistoryFrame().contentWindow.document;
		var hash = String(doc.location.search);
		if (hash.length == 1 && hash.charAt(0) == "?") {
			hash = "";
		}
		else if (hash.length >= 2 && hash.charAt(0) == "?") {
			hash = hash.substring(1);
		}
		return hash;
	}

    /* Get the current location hash excluding the '#' symbol. */
    function getHash() {
       // It would be nice if we could use document.location.hash here,
       // but it's faulty sometimes.
       var idx = document.location.href.indexOf('#');
       return (idx >= 0) ? document.location.href.substr(idx+1) : '';
    }

    /* Get the current location hash excluding the '#' symbol. */
    function setHash(hash) {
       // It would be nice if we could use document.location.hash here,
       // but it's faulty sometimes.
       if (hash == '') hash = '#'
       document.location.hash = hash;
    }

    function createState(baseUrl, newUrl, flexAppUrl) {
        return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
    }

    /* Add a history entry to the browser.
     *   baseUrl: the portion of the location prior to the '#'
     *   newUrl: the entire new URL, including '#' and following fragment
     *   flexAppUrl: the portion of the location following the '#' only
     */
    function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {

        //delete all the history entries
        forwardStack = [];

        if (browser.ie) {
            //Check to see if we are being asked to do a navigate for the first
            //history entry, and if so ignore, because it's coming from the creation
            //of the history iframe
            if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
                currentHref = initialHref;
                return;
            }
            if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
                newUrl = baseUrl + '#' + defaultHash;
                flexAppUrl = defaultHash;
            } else {
                // for IE, tell the history frame to go somewhere without a '#'
                // in order to get this entry into the browser history.
                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
            }
            setHash(flexAppUrl);
        } else {

            //ADR
            if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
                initialState = createState(baseUrl, newUrl, flexAppUrl);
            } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
                backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
            }

            if (browser.safari) {
                // for Safari, submit a form whose action points to the desired URL
                if (browser.version <= 419.3) {
                    var file = window.location.pathname.toString();
                    file = file.substring(file.lastIndexOf("/")+1);
                    getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
                    //get the current elements and add them to the form
                    var qs = window.location.search.substring(1);
                    var qs_arr = qs.split("&");
                    for (var i = 0; i < qs_arr.length; i++) {
                        var tmp = qs_arr[i].split("=");
                        var elem = document.createElement("input");
                        elem.type = "hidden";
                        elem.name = tmp[0];
                        elem.value = tmp[1];
                        document.forms.historyForm.appendChild(elem);
                    }
                    document.forms.historyForm.submit();
                } else {
                    top.location.hash = flexAppUrl;
                }
                // We also have to maintain the history by hand for Safari
                historyHash[history.length] = flexAppUrl;
                _storeStates();
            } else {
                // Otherwise, write an anchor into the page and tell the browser to go there
                addAnchor(flexAppUrl);
                setHash(flexAppUrl);
            }
        }
        backStack.push(createState(baseUrl, newUrl, flexAppUrl));
    }

    function _storeStates() {
        if (browser.safari) {
            getRememberElement().value = historyHash.join(",");
        }
    }

    function handleBackButton() {
        //The "current" page is always at the top of the history stack.
        var current = backStack.pop();
        if (!current) { return; }
        var last = backStack[backStack.length - 1];
        if (!last && backStack.length == 0){
            last = initialState;
        }
        forwardStack.push(current);
    }

    function handleForwardButton() {
        //summary: private method. Do not call this directly.

        var last = forwardStack.pop();
        if (!last) { return; }
        backStack.push(last);
    }

    function handleArbitraryUrl() {
        //delete all the history entries
        forwardStack = [];
    }

    /* Called periodically to poll to see if we need to detect navigation that has occurred */
    function checkForUrlChange() {

        if (browser.ie) {
            if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
                //This occurs when the user has navigated to a specific URL
                //within the app, and didn't use browser back/forward
                //IE seems to have a bug where it stops updating the URL it
                //shows the end-user at this point, but programatically it
                //appears to be correct.  Do a full app reload to get around
                //this issue.
                if (browser.version < 7) {
                    currentHref = document.location.href;
                    document.location.reload();
                } else {
					if (getHash() != getIframeHash()) {
						// this.iframe.src = this.blankURL + hash;
						var sourceToSet = historyFrameSourcePrefix + getHash();
						getHistoryFrame().src = sourceToSet;
					}
                }
            }
        }

        if (browser.safari) {
            // For Safari, we have to check to see if history.length changed.
            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
                //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
                // If it did change, then we have to look the old state up
                // in our hand-maintained array since document.location.hash
                // won't have changed, then call back into BrowserManager.
                currentHistoryLength = history.length;
                var flexAppUrl = historyHash[currentHistoryLength];
                if (flexAppUrl == '') {
                    //flexAppUrl = defaultHash;
                }
                //ADR: to fix multiple
                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                    var pl = getPlayers();
                    for (var i = 0; i < pl.length; i++) {
                        pl[i].browserURLChange(flexAppUrl);
                    }
                } else {
                    getPlayer().browserURLChange(flexAppUrl);
                }
                _storeStates();
            }
        }
        if (browser.firefox) {
            if (currentHref != document.location.href) {
                var bsl = backStack.length;

                var urlActions = {
                    back: false, 
                    forward: false, 
                    set: false
                }

                if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
                    urlActions.back = true;
                    // FIXME: could this ever be a forward button?
                    // we can't clear it because we still need to check for forwards. Ugg.
                    // clearInterval(this.locationTimer);
                    handleBackButton();
                }
                
                // first check to see if we could have gone forward. We always halt on
                // a no-hash item.
                if (forwardStack.length > 0) {
                    if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
                        urlActions.forward = true;
                        handleForwardButton();
                    }
                }

                // ok, that didn't work, try someplace back in the history stack
                if ((bsl >= 2) && (backStack[bsl - 2])) {
                    if (backStack[bsl - 2].flexAppUrl == getHash()) {
                        urlActions.back = true;
                        handleBackButton();
                    }
                }
                
                if (!urlActions.back && !urlActions.forward) {
                    var foundInStacks = {
                        back: -1, 
                        forward: -1
                    }

                    for (var i = 0; i < backStack.length; i++) {
                        if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
                            arbitraryUrl = true;
                            foundInStacks.back = i;
                        }
                    }
                    for (var i = 0; i < forwardStack.length; i++) {
                        if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
                            arbitraryUrl = true;
                            foundInStacks.forward = i;
                        }
                    }
                    handleArbitraryUrl();
                }

                // Firefox changed; do a callback into BrowserManager to tell it.
                currentHref = document.location.href;
                var flexAppUrl = getHash();
                if (flexAppUrl == '') {
                    //flexAppUrl = defaultHash;
                }
                //ADR: to fix multiple
                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                    var pl = getPlayers();
                    for (var i = 0; i < pl.length; i++) {
                        pl[i].browserURLChange(flexAppUrl);
                    }
                } else {
                    getPlayer().browserURLChange(flexAppUrl);
                }
            }
        }
        //setTimeout(checkForUrlChange, 50);
    }

    /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
    function addAnchor(flexAppUrl)
    {
       if (document.getElementsByName(flexAppUrl).length == 0) {
           getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
       }
    }

    var _initialize = function () {
        if (browser.ie)
        {
            var scripts = document.getElementsByTagName('script');
            for (var i = 0, s; s = scripts[i]; i++) {
                if (s.src.indexOf("history.js") > -1) {
                    var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
                }
            }
            historyFrameSourcePrefix = iframe_location + "?";
            var src = historyFrameSourcePrefix;

            var iframe = document.createElement("iframe");
            iframe.id = 'ie_historyFrame';
            iframe.name = 'ie_historyFrame';
            //iframe.src = historyFrameSourcePrefix;
            try {
                document.body.appendChild(iframe);
            } catch(e) {
                setTimeout(function() {
                    document.body.appendChild(iframe);
                }, 0);
            }
        }

        if (browser.safari)
        {
            var rememberDiv = document.createElement("div");
            rememberDiv.id = 'safari_rememberDiv';
            document.body.appendChild(rememberDiv);
            rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';

            var formDiv = document.createElement("div");
            formDiv.id = 'safari_formDiv';
            document.body.appendChild(formDiv);

            var reloader_content = document.createElement('div');
            reloader_content.id = 'safarireloader';
            var scripts = document.getElementsByTagName('script');
            for (var i = 0, s; s = scripts[i]; i++) {
                if (s.src.indexOf("history.js") > -1) {
                    html = (new String(s.src)).replace(".js", ".html");
                }
            }
            reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
            document.body.appendChild(reloader_content);
            reloader_content.style.position = 'absolute';
            reloader_content.style.left = reloader_content.style.top = '-9999px';
            iframe = reloader_content.getElementsByTagName('iframe')[0];

            if (document.getElementById("safari_remember_field").value != "" ) {
                historyHash = document.getElementById("safari_remember_field").value.split(",");
            }

        }

        if (browser.firefox)
        {
            var anchorDiv = document.createElement("div");
            anchorDiv.id = 'firefox_anchorDiv';
            document.body.appendChild(anchorDiv);
        }
        
        //setTimeout(checkForUrlChange, 50);
    }

    return {
        historyHash: historyHash, 
        backStack: function() { return backStack; }, 
        forwardStack: function() { return forwardStack }, 
        getPlayer: getPlayer, 
        initialize: function(src) {
            _initialize(src);
        }, 
        setURL: function(url) {
            document.location.href = url;
        }, 
        getURL: function() {
            return document.location.href;
        }, 
        getTitle: function() {
            return document.title;
        }, 
        setTitle: function(title) {
            try {
                backStack[backStack.length - 1].title = title;
            } catch(e) { }
            //if on safari, set the title to be the empty string. 
            if (browser.safari) {
                if (title == "") {
                    try {
                    var tmp = window.location.href.toString();
                    title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
                    } catch(e) {
                        title = "";
                    }
                }
            }
            document.title = title;
        }, 
        setDefaultURL: function(def)
        {
            defaultHash = def;
            def = getHash();
            //trailing ? is important else an extra frame gets added to the history
            //when navigating back to the first page.  Alternatively could check
            //in history frame navigation to compare # and ?.
            if (browser.ie)
            {
                window['_ie_firstload'] = true;
                var sourceToSet = historyFrameSourcePrefix + def;
                var func = function() {
                    getHistoryFrame().src = sourceToSet;
                    window.location.replace("#" + def);
                    setInterval(checkForUrlChange, 50);
                }
                try {
                    func();
                } catch(e) {
                    window.setTimeout(function() { func(); }, 0);
                }
            }

            if (browser.safari)
            {
                currentHistoryLength = history.length;
                if (historyHash.length == 0) {
                    historyHash[currentHistoryLength] = def;
                    var newloc = "#" + def;
                    window.location.replace(newloc);
                } else {
                    //alert(historyHash[historyHash.length-1]);
                }
                //setHash(def);
                setInterval(checkForUrlChange, 50);
            }
            
            
            if (browser.firefox || browser.opera)
            {
                var reg = new RegExp("#" + def + "$");
                if (window.location.toString().match(reg)) {
                } else {
                    var newloc ="#" + def;
                    window.location.replace(newloc);
                }
                setInterval(checkForUrlChange, 50);
                //setHash(def);
            }

        }, 

        /* Set the current browser URL; called from inside BrowserManager to propagate
         * the application state out to the container.
         */
        setBrowserURL: function(flexAppUrl, objectId) {
            if (browser.ie && typeof objectId != "undefined") {
                currentObjectId = objectId;
            }
           //fromIframe = fromIframe || false;
           //fromFlex = fromFlex || false;
           //alert("setBrowserURL: " + flexAppUrl);
           //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;

           var pos = document.location.href.indexOf('#');
           var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
           var newUrl = baseUrl + '#' + flexAppUrl;

           if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
               currentHref = newUrl;
               addHistoryEntry(baseUrl, newUrl, flexAppUrl);
               currentHistoryLength = history.length;
           }

           return false;
        }, 

        browserURLChange: function(flexAppUrl) {
            var objectId = null;
            if (browser.ie && currentObjectId != null) {
                objectId = currentObjectId;
            }
            pendingURL = '';
            
            if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                var pl = getPlayers();
                for (var i = 0; i < pl.length; i++) {
                    try {
                        pl[i].browserURLChange(flexAppUrl);
                    } catch(e) { }
                }
            } else {
                try {
                    getPlayer(objectId).browserURLChange(flexAppUrl);
                } catch(e) { }
            }

            currentObjectId = null;
        }

    }

})();

// Initialization

// Automated unit testing and other diagnostics

function setURL(url)
{
    document.location.href = url;
}

function backButton()
{
    history.back();
}

function forwardButton()
{
    history.forward();
}

function goForwardOrBackInHistory(step)
{
    history.go(step);
}

//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
(function(i) {
    var u =navigator.userAgent;var e=/*@cc_on!@*/false; 
    var st = setTimeout;
    if(/webkit/i.test(u)){
        st(function(){
            var dr=document.readyState;
            if(dr=="loaded"||dr=="complete"){i()}
            else{st(arguments.callee,10);}},10);
    } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
        document.addEventListener("DOMContentLoaded",i,false);
    } else if(e){
    (function(){
        var t=document.createElement('doc:rdy');
        try{t.doScroll('left');
            i();t=null;
        }catch(e){st(arguments.callee,0);}})();
    } else{
        window.onload=i;
    }
})( function() {BrowserHistory.initialize();} );



