// Master Javascript round-up file 

/*
* Begin File: "admin/js/SpryData.js"
*/

// SpryData.js - version 0.45 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

var Spry; if (!Spry) Spry = {};

//////////////////////////////////////////////////////////////////////
//
// Spry.Utils
//
//////////////////////////////////////////////////////////////////////
if(!Spry.Utils)Spry.Utils={};Spry.Utils.msProgIDs=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0"];Spry.Utils.createXMLHttpRequest=function()
{var req=null;try
{if(window.ActiveXObject)
{while(!req&&Spry.Utils.msProgIDs.length)
{try{req=new ActiveXObject(Spry.Utils.msProgIDs[0]);}catch(e){req=null;}
if(!req)
Spry.Utils.msProgIDs.splice(0,1);}}
if(!req&&window.XMLHttpRequest)
req=new XMLHttpRequest();}
catch(e){req=null;}
if(!req)
Spry.Debug.reportError("Failed to create an XMLHttpRequest object!");return req;};Spry.Utils.loadURL=function(method,url,async,callback,opts)
{var req=new Spry.Utils.loadURL.Request();req.method=method;req.url=url;req.async=async;req.successCallback=callback;Spry.Utils.setOptions(req,opts);try
{req.xhRequest=Spry.Utils.createXMLHttpRequest();if(!req.xhRequest)
return null;if(req.async)
req.xhRequest.onreadystatechange=function(){Spry.Utils.loadURL.callback(req);};req.xhRequest.open(req.method,req.url,req.async,req.username,req.password);if(req.headers)
{for(var name in req.headers)
req.xhRequest.setRequestHeader(name,req.headers[name]);}
req.xhRequest.send(req.postData);if(!req.async)
Spry.Utils.loadURL.callback(req);}
catch(e)
{if(req.errorCallback)
req.errorCallback(req);else
Spry.Debug.reportError("Exception caught while loading "+url+": "+e);req=null;}
return req;};Spry.Utils.loadURL.callback=function(req)
{if(!req||req.xhRequest.readyState!=4)
return;if(req.successCallback&&(req.xhRequest.status==200||req.xhRequest.status==0))
req.successCallback(req);else if(req.errorCallback)
req.errorCallback(req);};Spry.Utils.loadURL.Request=function()
{var props=Spry.Utils.loadURL.Request.props;var numProps=props.length;for(var i=0;i<numProps;i++)
this[props[i]]=null;this.method="GET";this.async=true;this.headers={};};Spry.Utils.loadURL.Request.props=["method","url","async","username","password","postData","successCallback","errorCallback","headers","userData","xhRequest"];Spry.Utils.loadURL.Request.prototype.extractRequestOptions=function(opts,undefineRequestProps)
{if(!opts)
return;var props=Spry.Utils.loadURL.Request.props;var numProps=props.length;for(var i=0;i<numProps;i++)
{var prop=props[i];if(opts[prop]!=undefined)
{this[prop]=opts[prop];if(undefineRequestProps)
opts[prop]=undefined;}}};Spry.Utils.loadURL.Request.prototype.clone=function()
{var props=Spry.Utils.loadURL.Request.props;var numProps=props.length;var req=new Spry.Utils.loadURL.Request;for(var i=0;i<numProps;i++)
req[props[i]]=this[props[i]];if(this.headers)
{req.headers={};Spry.Utils.setOptions(req.headers,this.headers);}
return req;};Spry.Utils.setInnerHTML=function(ele,str,preventScripts)
{if(!ele)
return;ele=Spry.$(ele);var scriptExpr="<script[^>]*>(.|\s|\n|\r)*?</script>";ele.innerHTML=str.replace(new RegExp(scriptExpr,"img"),"");if(preventScripts)
return;var matches=str.match(new RegExp(scriptExpr,"img"));if(matches)
{var numMatches=matches.length;for(var i=0;i<numMatches;i++)
{var s=matches[i].replace(/<script[^>]*>[\s\r\n]*(<\!--)?|(-->)?[\s\r\n]*<\/script>/img,"");Spry.Utils.eval(s);}}};Spry.Utils.updateContent=function(ele,url,finishFunc,opts)
{Spry.Utils.loadURL("GET",url,true,function(req)
{Spry.Utils.setInnerHTML(ele,req.xhRequest.responseText);if(finishFunc)
finishFunc(ele,url);},opts);};if(!Spry.$$)
{Spry.Utils.addEventListener=function(element,eventType,handler,capture)
{try
{element=Spry.$(element);if(element.addEventListener)
element.addEventListener(eventType,handler,capture);else if(element.attachEvent)
element.attachEvent("on"+eventType,handler);}
catch(e){}};Spry.Utils.removeEventListener=function(element,eventType,handler,capture)
{try
{element=Spry.$(element);if(element.removeEventListener)
element.removeEventListener(eventType,handler,capture);else if(element.detachEvent)
element.detachEvent("on"+eventType,handler);}
catch(e){}};Spry.Utils.addLoadListener=function(handler)
{if(typeof window.addEventListener!='undefined')
window.addEventListener('load',handler,false);else if(typeof document.addEventListener!='undefined')
document.addEventListener('load',handler,false);else if(typeof window.attachEvent!='undefined')
window.attachEvent('onload',handler);};Spry.Utils.addClassName=function(ele,className)
{ele=Spry.$(ele);if(!ele||!className||(ele.className&&ele.className.search(new RegExp("\\b"+className+"\\b"))!=-1))
return;ele.className+=(ele.className?" ":"")+className;};Spry.Utils.removeClassName=function(ele,className)
{ele=Spry.$(ele);if(!ele||!className||(ele.className&&ele.className.search(new RegExp("\\b"+className+"\\b"))==-1))
return;ele.className=ele.className.replace(new RegExp("\\s*\\b"+className+"\\b","g"),"");};Spry.Utils.getObjectByName=function(name)
{var result=null;if(name)
{var lu=window;var objPath=name.split(".");for(var i=0;lu&&i<objPath.length;i++)
{result=lu[objPath[i]];lu=result;}}
return result;};Spry.$=function(element)
{if(arguments.length>1)
{for(var i=0,elements=[],length=arguments.length;i<length;i++)
elements.push(Spry.$(arguments[i]));return elements;}
if(typeof element=='string')
element=document.getElementById(element);return element;};}
Spry.Utils.eval=function(str)
{return eval(str);};Spry.Utils.escapeQuotesAndLineBreaks=function(str)
{if(str)
{str=str.replace(/\\/g,"\\\\");str=str.replace(/["']/g,"\\$&");str=str.replace(/\n/g,"\\n");str=str.replace(/\r/g,"\\r");}
return str;};Spry.Utils.encodeEntities=function(str)
{if(str&&str.search(/[&<>"]/)!=-1)
{str=str.replace(/&/g,"&amp;");str=str.replace(/</g,"&lt;");str=str.replace(/>/g,"&gt;");str=str.replace(/"/g,"&quot;");}
return str};Spry.Utils.decodeEntities=function(str)
{var d=Spry.Utils.decodeEntities.div;if(!d)
{d=document.createElement('div');Spry.Utils.decodeEntities.div=d;if(!d)return str;}
d.innerHTML=str;if(d.childNodes.length==1&&d.firstChild.nodeType==3&&d.firstChild.nextSibling==null)
str=d.firstChild.data;else
{str=str.replace(/&lt;/gi,"<");str=str.replace(/&gt;/gi,">");str=str.replace(/&quot;/gi,"\"");str=str.replace(/&amp;/gi,"&");}
return str;};Spry.Utils.fixupIETagAttributes=function(inStr)
{var outStr="";var tagStart=inStr.match(/^<[^\s>]+\s*/)[0];var tagEnd=inStr.match(/\s*\/?>$/)[0];var tagAttrs=inStr.replace(/^<[^\s>]+\s*|\s*\/?>/g,"");outStr+=tagStart;if(tagAttrs)
{var startIndex=0;var endIndex=0;while(startIndex<tagAttrs.length)
{while(tagAttrs.charAt(endIndex)!='='&&endIndex<tagAttrs.length)
++endIndex;if(endIndex>=tagAttrs.length)
{outStr+=tagAttrs.substring(startIndex,endIndex);break;}
++endIndex;outStr+=tagAttrs.substring(startIndex,endIndex);startIndex=endIndex;if(tagAttrs.charAt(endIndex)=='"'||tagAttrs.charAt(endIndex)=="'")
{var savedIndex=endIndex++;while(endIndex<tagAttrs.length)
{if(tagAttrs.charAt(endIndex)==tagAttrs.charAt(savedIndex))
{endIndex++;break;}
else if(tagAttrs.charAt(endIndex)=="\\")
endIndex++;endIndex++;}
outStr+=tagAttrs.substring(startIndex,endIndex);startIndex=endIndex;}
else
{outStr+="\"";var sIndex=tagAttrs.slice(endIndex).search(/\s/);endIndex=(sIndex!=-1)?(endIndex+sIndex):tagAttrs.length;outStr+=tagAttrs.slice(startIndex,endIndex);outStr+="\"";startIndex=endIndex;}}}
outStr+=tagEnd;return outStr;};Spry.Utils.fixUpIEInnerHTML=function(inStr)
{var outStr="";var regexp=new RegExp("<\\!--|<\\!\\[CDATA\\[|<\\w+[^<>]*>|-->|\\]\\](>|\&gt;)","g");var searchStartIndex=0;var skipFixUp=0;while(inStr.length)
{var results=regexp.exec(inStr);if(!results||!results[0])
{outStr+=inStr.substr(searchStartIndex,inStr.length-searchStartIndex);break;}
if(results.index!=searchStartIndex)
{outStr+=inStr.substr(searchStartIndex,results.index-searchStartIndex);}
if(results[0]=="<!--"||results[0]=="<![CDATA[")
{++skipFixUp;outStr+=results[0];}
else if(results[0]=="-->"||results[0]=="]]>"||(skipFixUp&&results[0]=="]]&gt;"))
{--skipFixUp;outStr+=results[0];}
else if(!skipFixUp&&results[0].charAt(0)=='<')
outStr+=Spry.Utils.fixupIETagAttributes(results[0]);else
outStr+=results[0];searchStartIndex=regexp.lastIndex;}
return outStr;};Spry.Utils.stringToXMLDoc=function(str)
{var xmlDoc=null;try
{var xmlDOMObj=new ActiveXObject("Microsoft.XMLDOM");xmlDOMObj.async=false;xmlDOMObj.loadXML(str);xmlDoc=xmlDOMObj;}
catch(e)
{try
{var domParser=new DOMParser;xmlDoc=domParser.parseFromString(str,'text/xml');}
catch(e)
{Spry.Debug.reportError("Caught exception in Spry.Utils.stringToXMLDoc(): "+e+"\n");xmlDoc=null;}}
return xmlDoc;};Spry.Utils.serializeObject=function(obj)
{var str="";var firstItem=true;if(obj==null||obj==undefined)
return str+obj;var objType=typeof obj;if(objType=="number"||objType=="boolean")
str+=obj;else if(objType=="string")
str+="\""+Spry.Utils.escapeQuotesAndLineBreaks(obj)+"\"";else if(obj.constructor==Array)
{str+="[";for(var i=0;i<obj.length;i++)
{if(!firstItem)
str+=", ";str+=Spry.Utils.serializeObject(obj[i]);firstItem=false;}
str+="]";}
else if(objType=="object")
{str+="{";for(var p in obj)
{if(!firstItem)
str+=", ";str+="\""+p+"\": "+Spry.Utils.serializeObject(obj[p]);firstItem=false;}
str+="}";}
return str;};Spry.Utils.getNodesByFunc=function(root,func)
{var nodeStack=new Array;var resultArr=new Array;var node=root;while(node)
{if(func(node))
resultArr.push(node);if(node.hasChildNodes())
{nodeStack.push(node);node=node.firstChild;}
else
{if(node==root)
node=null;else
try{node=node.nextSibling;}catch(e){node=null;};}
while(!node&&nodeStack.length>0)
{node=nodeStack.pop();if(node==root)
node=null;else
try{node=node.nextSibling;}catch(e){node=null;}}}
if(nodeStack&&nodeStack.length>0)
Spry.Debug.trace("-- WARNING: Spry.Utils.getNodesByFunc() failed to traverse all nodes!\n");return resultArr;};Spry.Utils.getFirstChildWithNodeName=function(node,nodeName)
{var child=node.firstChild;while(child)
{if(child.nodeName==nodeName)
return child;child=child.nextSibling;}
return null;};Spry.Utils.setOptions=function(obj,optionsObj,ignoreUndefinedProps)
{if(!optionsObj)
return;for(var optionName in optionsObj)
{if(ignoreUndefinedProps&&optionsObj[optionName]==undefined)
continue;obj[optionName]=optionsObj[optionName];}};Spry.Utils.SelectionManager={};Spry.Utils.SelectionManager.selectionGroups=new Object;Spry.Utils.SelectionManager.SelectionGroup=function()
{this.selectedElements=new Array;};Spry.Utils.SelectionManager.SelectionGroup.prototype.select=function(element,className,multiSelect)
{var selObj=null;if(!multiSelect)
{this.clearSelection();}
else
{for(var i=0;i<this.selectedElements.length;i++)
{selObj=this.selectedElements[i].element;if(selObj.element==element)
{if(selObj.className!=className)
{Spry.Utils.removeClassName(element,selObj.className);Spry.Utils.addClassName(element,className);}
return;}}}
selObj=new Object;selObj.element=element;selObj.className=className;this.selectedElements.push(selObj);Spry.Utils.addClassName(element,className);};Spry.Utils.SelectionManager.SelectionGroup.prototype.unSelect=function(element)
{for(var i=0;i<this.selectedElements.length;i++)
{var selObj=this.selectedElements[i].element;if(selObj.element==element)
{Spry.Utils.removeClassName(selObj.element,selObj.className);return;}}};Spry.Utils.SelectionManager.SelectionGroup.prototype.clearSelection=function()
{var selObj=null;do
{selObj=this.selectedElements.shift();if(selObj)
Spry.Utils.removeClassName(selObj.element,selObj.className);}
while(selObj);};Spry.Utils.SelectionManager.getSelectionGroup=function(selectionGroupName)
{if(!selectionGroupName)
return null;var groupObj=Spry.Utils.SelectionManager.selectionGroups[selectionGroupName];if(!groupObj)
{groupObj=new Spry.Utils.SelectionManager.SelectionGroup();Spry.Utils.SelectionManager.selectionGroups[selectionGroupName]=groupObj;}
return groupObj;};Spry.Utils.SelectionManager.select=function(selectionGroupName,element,className,multiSelect)
{var groupObj=Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName);if(!groupObj)
return;groupObj.select(element,className,multiSelect);};Spry.Utils.SelectionManager.unSelect=function(selectionGroupName,element)
{var groupObj=Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName);if(!groupObj)
return;groupObj.unSelect(element,className);};Spry.Utils.SelectionManager.clearSelection=function(selectionGroupName)
{var groupObj=Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName);if(!groupObj)
return;groupObj.clearSelection();};Spry.Utils.Notifier=function()
{this.observers=[];this.suppressNotifications=0;};Spry.Utils.Notifier.prototype.addObserver=function(observer)
{if(!observer)
return;var len=this.observers.length;for(var i=0;i<len;i++)
{if(this.observers[i]==observer)
return;}
this.observers[len]=observer;};Spry.Utils.Notifier.prototype.removeObserver=function(observer)
{if(!observer)
return;for(var i=0;i<this.observers.length;i++)
{if(this.observers[i]==observer)
{this.observers.splice(i,1);break;}}};Spry.Utils.Notifier.prototype.notifyObservers=function(methodName,data)
{if(!methodName)
return;if(!this.suppressNotifications)
{var len=this.observers.length;for(var i=0;i<len;i++)
{var obs=this.observers[i];if(obs)
{if(typeof obs=="function")
obs(methodName,this,data);else if(obs[methodName])
obs[methodName](this,data);}}}};Spry.Utils.Notifier.prototype.enableNotifications=function()
{if(--this.suppressNotifications<0)
{this.suppressNotifications=0;Spry.Debug.reportError("Unbalanced enableNotifications() call!\n");}};Spry.Utils.Notifier.prototype.disableNotifications=function()
{++this.suppressNotifications;};Spry.Debug={};Spry.Debug.enableTrace=true;Spry.Debug.debugWindow=null;Spry.Debug.onloadDidFire=false;Spry.Utils.addLoadListener(function(){Spry.Debug.onloadDidFire=true;Spry.Debug.flushQueuedMessages();});Spry.Debug.flushQueuedMessages=function()
{if(Spry.Debug.flushQueuedMessages.msgs)
{var msgs=Spry.Debug.flushQueuedMessages.msgs;for(var i=0;i<msgs.length;i++)
Spry.Debug.debugOut(msgs[i].msg,msgs[i].color);Spry.Debug.flushQueuedMessages.msgs=null;}};Spry.Debug.createDebugWindow=function()
{if(!Spry.Debug.enableTrace||Spry.Debug.debugWindow||!Spry.Debug.onloadDidFire)
return;try
{Spry.Debug.debugWindow=document.createElement("div");var div=Spry.Debug.debugWindow;div.style.fontSize="12px";div.style.fontFamily="console";div.style.position="absolute";div.style.width="400px";div.style.height="300px";div.style.overflow="auto";div.style.border="solid 1px black";div.style.backgroundColor="white";div.style.color="black";div.style.bottom="0px";div.style.right="0px";div.setAttribute("id","SpryDebugWindow");document.body.appendChild(Spry.Debug.debugWindow);}
catch(e){}};Spry.Debug.debugOut=function(str,bgColor)
{if(!Spry.Debug.debugWindow)
{Spry.Debug.createDebugWindow();if(!Spry.Debug.debugWindow)
{if(!Spry.Debug.flushQueuedMessages.msgs)
Spry.Debug.flushQueuedMessages.msgs=new Array;Spry.Debug.flushQueuedMessages.msgs.push({msg:str,color:bgColor});return;}}
var d=document.createElement("div");if(bgColor)
d.style.backgroundColor=bgColor;d.innerHTML=str;Spry.Debug.debugWindow.appendChild(d);};Spry.Debug.trace=function(str)
{Spry.Debug.debugOut(str);};Spry.Debug.reportError=function(str)
{Spry.Debug.debugOut(str,"red");};Spry.Data={};Spry.Data.regionsArray={};Spry.Data.initRegionsOnLoad=true;Spry.Data.initRegions=function(rootNode)
{rootNode=rootNode?Spry.$(rootNode):document.body;var lastRegionFound=null;var regions=Spry.Utils.getNodesByFunc(rootNode,function(node)
{try
{if(node.nodeType!=1)
return false;var attrName="spry:region";var attr=node.attributes.getNamedItem(attrName);if(!attr)
{attrName="spry:detailregion";attr=node.attributes.getNamedItem(attrName);}
if(attr)
{if(lastRegionFound)
{var parent=node.parentNode;while(parent)
{if(parent==lastRegionFound)
{Spry.Debug.reportError("Found a nested "+attrName+" in the following markup. Nested regions are currently not supported.<br/><pre>"+Spry.Utils.encodeEntities(parent.innerHTML)+"</pre>");return false;}
parent=parent.parentNode;}}
if(attr.value)
{attr=node.attributes.getNamedItem("id");if(!attr||!attr.value)
{node.setAttribute("id","spryregion"+(++Spry.Data.initRegions.nextUniqueRegionID));}
lastRegionFound=node;return true;}
else
Spry.Debug.reportError(attrName+" attributes require one or more data set names as values!");}}
catch(e){}
return false;});var name,dataSets,i;var newRegions=[];for(i=0;i<regions.length;i++)
{var rgn=regions[i];var isDetailRegion=false;name=rgn.attributes.getNamedItem("id").value;attr=rgn.attributes.getNamedItem("spry:region");if(!attr)
{attr=rgn.attributes.getNamedItem("spry:detailregion");isDetailRegion=true;}
if(!attr.value)
{Spry.Debug.reportError("spry:region and spry:detailregion attributes require one or more data set names as values!");continue;}
rgn.attributes.removeNamedItem(attr.nodeName);Spry.Utils.removeClassName(rgn,Spry.Data.Region.hiddenRegionClassName);dataSets=Spry.Data.Region.strToDataSetsArray(attr.value);if(!dataSets.length)
{Spry.Debug.reportError("spry:region or spry:detailregion attribute has no data set!");continue;}
var hasBehaviorAttributes=false;var hasSpryContent=false;var dataStr="";var parent=null;var regionStates={};var regionStateMap={};attr=rgn.attributes.getNamedItem("spry:readystate");if(attr&&attr.value)
regionStateMap["ready"]=attr.value;attr=rgn.attributes.getNamedItem("spry:errorstate");if(attr&&attr.value)
regionStateMap["error"]=attr.value;attr=rgn.attributes.getNamedItem("spry:loadingstate");if(attr&&attr.value)
regionStateMap["loading"]=attr.value;attr=rgn.attributes.getNamedItem("spry:expiredstate");if(attr&&attr.value)
regionStateMap["expired"]=attr.value;var piRegions=Spry.Utils.getNodesByFunc(rgn,function(node)
{try
{if(node.nodeType==1)
{var attributes=node.attributes;var numPI=Spry.Data.Region.PI.orderedInstructions.length;var lastStartComment=null;var lastEndComment=null;for(var i=0;i<numPI;i++)
{var piName=Spry.Data.Region.PI.orderedInstructions[i];var attr=attributes.getNamedItem(piName);if(!attr)
continue;var piDesc=Spry.Data.Region.PI.instructions[piName];var childrenOnly=(node==rgn)?true:piDesc.childrenOnly;var openTag=piDesc.getOpenTag(node,piName);var closeTag=piDesc.getCloseTag(node,piName);if(childrenOnly)
{var oComment=document.createComment(openTag);var cComment=document.createComment(closeTag);if(!lastStartComment)
node.insertBefore(oComment,node.firstChild);else
node.insertBefore(oComment,lastStartComment.nextSibling);lastStartComment=oComment;if(!lastEndComment)
node.appendChild(cComment);else
node.insertBefore(cComment,lastEndComment);lastEndComment=cComment;}
else
{var parent=node.parentNode;parent.insertBefore(document.createComment(openTag),node);parent.insertBefore(document.createComment(closeTag),node.nextSibling);}
if(piName=="spry:state")
regionStates[attr.value]=true;node.removeAttribute(piName);}
if(Spry.Data.Region.enableBehaviorAttributes)
{var bAttrs=Spry.Data.Region.behaviorAttrs;for(var behaviorAttrName in bAttrs)
{var bAttr=attributes.getNamedItem(behaviorAttrName);if(bAttr)
{hasBehaviorAttributes=true;if(bAttrs[behaviorAttrName].setup)
bAttrs[behaviorAttrName].setup(node,bAttr.value);}}}}}
catch(e){}
return false;});dataStr=rgn.innerHTML;if(window.ActiveXObject&&!Spry.Data.Region.disableIEInnerHTMLFixUp&&dataStr.search(/=\{/)!=-1)
{if(Spry.Data.Region.debug)
Spry.Debug.trace("<hr />Performing IE innerHTML fix up of Region: "+name+"<br /><br />"+Spry.Utils.encodeEntities(dataStr));dataStr=Spry.Utils.fixUpIEInnerHTML(dataStr);}
if(Spry.Data.Region.debug)
Spry.Debug.trace("<hr />Region template markup for '"+name+"':<br /><br />"+Spry.Utils.encodeEntities(dataStr));if(!hasSpryContent)
{rgn.innerHTML="";}
var region=new Spry.Data.Region(rgn,name,isDetailRegion,dataStr,dataSets,regionStates,regionStateMap,hasBehaviorAttributes);Spry.Data.regionsArray[region.name]=region;newRegions.push(region);}
for(var i=0;i<newRegions.length;i++)
newRegions[i].updateContent();};Spry.Data.initRegions.nextUniqueRegionID=0;Spry.Data.updateRegion=function(regionName)
{if(!regionName||!Spry.Data.regionsArray||!Spry.Data.regionsArray[regionName])
return;try{Spry.Data.regionsArray[regionName].updateContent();}
catch(e){Spry.Debug.reportError("Spry.Data.updateRegion("+regionName+") caught an exception: "+e+"\n");}};Spry.Data.getRegion=function(regionName)
{return Spry.Data.regionsArray[regionName];};Spry.Data.updateAllRegions=function()
{if(!Spry.Data.regionsArray)
return;for(var regionName in Spry.Data.regionsArray)
Spry.Data.updateRegion(regionName);};Spry.Data.getDataSetByName=function(dataSetName)
{var ds=window[dataSetName];if(typeof ds!="object"||!ds.getData||!ds.filter)
return null;return ds;};Spry.Data.DataSet=function(options)
{Spry.Utils.Notifier.call(this);this.name="";this.internalID=Spry.Data.DataSet.nextDataSetID++;this.curRowID=0;this.data=[];this.unfilteredData=null;this.dataHash={};this.columnTypes={};this.filterFunc=null;this.filterDataFunc=null;this.distinctOnLoad=false;this.distinctFieldsOnLoad=null;this.sortOnLoad=null;this.sortOrderOnLoad="ascending";this.keepSorted=false;this.dataWasLoaded=false;this.pendingRequest=null;this.lastSortColumns=[];this.lastSortOrder="";this.loadIntervalID=0;Spry.Utils.setOptions(this,options);};Spry.Data.DataSet.prototype=new Spry.Utils.Notifier();Spry.Data.DataSet.prototype.constructor=Spry.Data.DataSet;Spry.Data.DataSet.prototype.getData=function(unfiltered)
{return(unfiltered&&this.unfilteredData)?this.unfilteredData:this.data;};Spry.Data.DataSet.prototype.getUnfilteredData=function()
{return this.getData(true);};Spry.Data.DataSet.prototype.getLoadDataRequestIsPending=function()
{return this.pendingRequest!=null;};Spry.Data.DataSet.prototype.getDataWasLoaded=function()
{return this.dataWasLoaded;};Spry.Data.DataSet.prototype.getValue=function(valueName,rowContext)
{var result=undefined;if(!rowContext)
rowContext=this.getCurrentRow();switch(valueName)
{case"ds_RowNumber":result=this.getRowNumber(rowContext);break;case"ds_RowNumberPlus1":result=this.getRowNumber(rowContext)+1;break;case"ds_RowCount":result=this.getRowCount();break;case"ds_UnfilteredRowCount":result=this.getRowCount(true);break;case"ds_CurrentRowNumber":result=this.getCurrentRowNumber();break;case"ds_CurrentRowID":result=this.getCurrentRowID();break;case"ds_EvenOddRow":result=(this.getRowNumber(rowContext)%2)?Spry.Data.Region.evenRowClassName:Spry.Data.Region.oddRowClassName;break;case"ds_SortOrder":result=this.getSortOrder();break;case"ds_SortColumn":result=this.getSortColumn();break;default:if(rowContext)
result=rowContext[valueName];break;}
return result;};Spry.Data.DataSet.prototype.setDataFromArray=function(arr,fireSyncLoad)
{this.notifyObservers("onPreLoad");this.unfilteredData=null;this.filteredData=null;this.data=[];this.dataHash={};var arrLen=arr.length;for(var i=0;i<arrLen;i++)
{var row=arr[i];if(row.ds_RowID==undefined)
row.ds_RowID=i;this.dataHash[row.ds_RowID]=row;this.data.push(row);}
this.loadData(fireSyncLoad);};Spry.Data.DataSet.prototype.loadData=function(syncLoad)
{var self=this;this.pendingRequest=new Object;this.dataWasLoaded=false;var loadCallbackFunc=function()
{self.pendingRequest=null;self.dataWasLoaded=true;self.applyColumnTypes();self.disableNotifications();self.filterAndSortData();self.enableNotifications();self.notifyObservers("onPostLoad");self.notifyObservers("onDataChanged");};if(syncLoad)
loadCallbackFunc();else
this.pendingRequest.timer=setTimeout(loadCallbackFunc,0);};Spry.Data.DataSet.prototype.filterAndSortData=function()
{if(this.filterDataFunc)
this.filterData(this.filterDataFunc,true);if(this.distinctOnLoad)
this.distinct(this.distinctFieldsOnLoad);if(this.keepSorted&&this.getSortColumn())
this.sort(this.lastSortColumns,this.lastSortOrder);else if(this.sortOnLoad)
this.sort(this.sortOnLoad,this.sortOrderOnLoad);if(this.filterFunc)
this.filter(this.filterFunc,true);if(this.data&&this.data.length>0)
this.curRowID=this.data[0]['ds_RowID'];else
this.curRowID=0;};Spry.Data.DataSet.prototype.cancelLoadData=function()
{if(this.pendingRequest&&this.pendingRequest.timer)
clearTimeout(this.pendingRequest.timer);this.pendingRequest=null;};Spry.Data.DataSet.prototype.getRowCount=function(unfiltered)
{var rows=this.getData(unfiltered);return rows?rows.length:0;};Spry.Data.DataSet.prototype.getRowByID=function(rowID)
{if(!this.data)
return null;return this.dataHash[rowID];};Spry.Data.DataSet.prototype.getRowByRowNumber=function(rowNumber,unfiltered)
{var rows=this.getData(unfiltered);if(rows&&rowNumber>=0&&rowNumber<rows.length)
return rows[rowNumber];return null;};Spry.Data.DataSet.prototype.getCurrentRow=function()
{return this.getRowByID(this.curRowID);};Spry.Data.DataSet.prototype.setCurrentRow=function(rowID)
{if(this.curRowID==rowID)
return;var nData={oldRowID:this.curRowID,newRowID:rowID};this.curRowID=rowID;this.notifyObservers("onCurrentRowChanged",nData);};Spry.Data.DataSet.prototype.getRowNumber=function(row,unfiltered)
{if(row)
{var rows=this.getData(unfiltered);if(rows&&rows.length)
{var numRows=rows.length;for(var i=0;i<numRows;i++)
{if(rows[i]==row)
return i;}}}
return-1;};Spry.Data.DataSet.prototype.getCurrentRowNumber=function()
{return this.getRowNumber(this.getCurrentRow());};Spry.Data.DataSet.prototype.getCurrentRowID=function()
{return this.curRowID;};Spry.Data.DataSet.prototype.setCurrentRowNumber=function(rowNumber)
{if(!this.data||rowNumber>=this.data.length)
{Spry.Debug.trace("Invalid row number: "+rowNumber+"\n");return;}
var rowID=this.data[rowNumber]["ds_RowID"];if(rowID==undefined||this.curRowID==rowID)
return;this.setCurrentRow(rowID);};Spry.Data.DataSet.prototype.findRowsWithColumnValues=function(valueObj,firstMatchOnly,unfiltered)
{var results=[];var rows=this.getData(unfiltered);if(rows)
{var numRows=rows.length;for(var i=0;i<numRows;i++)
{var row=rows[i];var matched=true;for(var colName in valueObj)
{if(valueObj[colName]!=row[colName])
{matched=false;break;}}
if(matched)
{if(firstMatchOnly)
return row;results.push(row);}}}
return firstMatchOnly?null:results;};Spry.Data.DataSet.prototype.setColumnType=function(columnNames,columnType)
{if(columnNames)
{if(typeof columnNames=="string")
columnNames=[columnNames];for(var i=0;i<columnNames.length;i++)
this.columnTypes[columnNames[i]]=columnType;}};Spry.Data.DataSet.prototype.getColumnType=function(columnName)
{if(this.columnTypes[columnName])
return this.columnTypes[columnName];return"string";};Spry.Data.DataSet.prototype.applyColumnTypes=function()
{var rows=this.getData(true);var numRows=rows.length;var colNames=[];if(numRows<1)
return;for(var cname in this.columnTypes)
{var ctype=this.columnTypes[cname];if(ctype!="string")
{for(var i=0;i<numRows;i++)
{var row=rows[i];var val=row[cname];if(val!=undefined)
{if(ctype=="number")
row[cname]=new Number(val);else if(ctype=="html")
row[cname]=Spry.Utils.decodeEntities(val);}}}}};Spry.Data.DataSet.prototype.distinct=function(columnNames)
{if(this.data)
{var oldData=this.data;this.data=[];this.dataHash={};var dataChanged=false;var alreadySeenHash={};var i=0;var keys=[];if(typeof columnNames=="string")
keys=[columnNames];else if(columnNames)
keys=columnNames;else
for(var recField in oldData[0])
keys[i++]=recField;for(var i=0;i<oldData.length;i++)
{var rec=oldData[i];var hashStr="";for(var j=0;j<keys.length;j++)
{recField=keys[j];if(recField!="ds_RowID")
{if(hashStr)
hashStr+=",";hashStr+=recField+":"+"\""+rec[recField]+"\"";}}
if(!alreadySeenHash[hashStr])
{this.data.push(rec);this.dataHash[rec['ds_RowID']]=rec;alreadySeenHash[hashStr]=true;}
else
dataChanged=true;}
if(dataChanged)
this.notifyObservers('onDataChanged');}};Spry.Data.DataSet.prototype.getSortColumn=function(){return(this.lastSortColumns&&this.lastSortColumns.length>0)?this.lastSortColumns[0]:"";};Spry.Data.DataSet.prototype.getSortOrder=function(){return this.lastSortOrder?this.lastSortOrder:"";};Spry.Data.DataSet.prototype.sort=function(columnNames,sortOrder)
{if(!columnNames)
return;if(typeof columnNames=="string")
columnNames=[columnNames,"ds_RowID"];else if(columnNames.length<2&&columnNames[0]!="ds_RowID")
columnNames.push("ds_RowID");if(!sortOrder)
sortOrder="toggle";if(sortOrder=="toggle")
{if(this.lastSortColumns.length>0&&this.lastSortColumns[0]==columnNames[0]&&this.lastSortOrder=="ascending")
sortOrder="descending";else
sortOrder="ascending";}
if(sortOrder!="ascending"&&sortOrder!="descending")
{Spry.Debug.reportError("Invalid sort order type specified: "+sortOrder+"\n");return;}
var nData={oldSortColumns:this.lastSortColumns,oldSortOrder:this.lastSortOrder,newSortColumns:columnNames,newSortOrder:sortOrder};this.notifyObservers("onPreSort",nData);var cname=columnNames[columnNames.length-1];var sortfunc=Spry.Data.DataSet.prototype.sort.getSortFunc(cname,this.getColumnType(cname),sortOrder);for(var i=columnNames.length-2;i>=0;i--)
{cname=columnNames[i];sortfunc=Spry.Data.DataSet.prototype.sort.buildSecondarySortFunc(Spry.Data.DataSet.prototype.sort.getSortFunc(cname,this.getColumnType(cname),sortOrder),sortfunc);}
if(this.unfilteredData)
{this.unfilteredData.sort(sortfunc);if(this.filterFunc)
this.filter(this.filterFunc,true);}
else
this.data.sort(sortfunc);this.lastSortColumns=columnNames.slice(0);this.lastSortOrder=sortOrder;this.notifyObservers("onPostSort",nData);};Spry.Data.DataSet.prototype.sort.getSortFunc=function(prop,type,order)
{var sortfunc=null;if(type=="number")
{if(order=="ascending")
sortfunc=function(a,b)
{a=a[prop];b=b[prop];if(a==undefined||b==undefined)
return(a==b)?0:(a?1:-1);return a-b;};else
sortfunc=function(a,b)
{a=a[prop];b=b[prop];if(a==undefined||b==undefined)
return(a==b)?0:(a?-1:1);return b-a;};}
else if(type=="date")
{if(order=="ascending")
sortfunc=function(a,b)
{var dA=a[prop];var dB=b[prop];dA=dA?(new Date(dA)):0;dB=dB?(new Date(dB)):0;return dA-dB;};else
sortfunc=function(a,b)
{var dA=a[prop];var dB=b[prop];dA=dA?(new Date(dA)):0;dB=dB?(new Date(dB)):0;return dB-dA;};}
else
{if(order=="ascending")
sortfunc=function(a,b){a=a[prop];b=b[prop];if(a==undefined||b==undefined)
return(a==b)?0:(a?1:-1);var tA=a.toString();var tB=b.toString();var tA_l=tA.toLowerCase();var tB_l=tB.toLowerCase();var min_len=tA.length>tB.length?tB.length:tA.length;for(var i=0;i<min_len;i++)
{var a_l_c=tA_l.charAt(i);var b_l_c=tB_l.charAt(i);var a_c=tA.charAt(i);var b_c=tB.charAt(i);if(a_l_c>b_l_c)
return 1;else if(a_l_c<b_l_c)
return-1;else if(a_c>b_c)
return 1;else if(a_c<b_c)
return-1;}
if(tA.length==tB.length)
return 0;else if(tA.length>tB.length)
return 1;return-1;};else
sortfunc=function(a,b){a=a[prop];b=b[prop];if(a==undefined||b==undefined)
return(a==b)?0:(a?-1:1);var tA=a.toString();var tB=b.toString();var tA_l=tA.toLowerCase();var tB_l=tB.toLowerCase();var min_len=tA.length>tB.length?tB.length:tA.length;for(var i=0;i<min_len;i++)
{var a_l_c=tA_l.charAt(i);var b_l_c=tB_l.charAt(i);var a_c=tA.charAt(i);var b_c=tB.charAt(i);if(a_l_c>b_l_c)
return-1;else if(a_l_c<b_l_c)
return 1;else if(a_c>b_c)
return-1;else if(a_c<b_c)
return 1;}
if(tA.length==tB.length)
return 0;else if(tA.length>tB.length)
return-1;return 1;};}
return sortfunc;};Spry.Data.DataSet.prototype.sort.buildSecondarySortFunc=function(funcA,funcB)
{return function(a,b)
{var ret=funcA(a,b);if(ret==0)
ret=funcB(a,b);return ret;};};Spry.Data.DataSet.prototype.filterData=function(filterFunc,filterOnly)
{var dataChanged=false;if(!filterFunc)
{this.filterDataFunc=null;dataChanged=true;}
else
{this.filterDataFunc=filterFunc;if(this.dataWasLoaded&&((this.unfilteredData&&this.unfilteredData.length)||(this.data&&this.data.length)))
{if(this.unfilteredData)
{this.data=this.unfilteredData;this.unfilteredData=null;}
var oldData=this.data;this.data=[];this.dataHash={};for(var i=0;i<oldData.length;i++)
{var newRow=filterFunc(this,oldData[i],i);if(newRow)
{this.data.push(newRow);this.dataHash[newRow["ds_RowID"]]=newRow;}}
dataChanged=true;}}
if(dataChanged)
{if(!filterOnly)
{this.disableNotifications();if(this.filterFunc)
this.filter(this.filterFunc,true);this.enableNotifications();}
this.notifyObservers("onDataChanged");}};Spry.Data.DataSet.prototype.filter=function(filterFunc,filterOnly)
{var dataChanged=false;if(!filterFunc)
{if(this.filterFunc&&this.unfilteredData)
{this.data=this.unfilteredData;this.unfilteredData=null;this.filterFunc=null;dataChanged=true;}}
else
{this.filterFunc=filterFunc;if(this.dataWasLoaded&&(this.unfilteredData||(this.data&&this.data.length)))
{if(!this.unfilteredData)
this.unfilteredData=this.data;var udata=this.unfilteredData;this.data=[];for(var i=0;i<udata.length;i++)
{var newRow=filterFunc(this,udata[i],i);if(newRow)
this.data.push(newRow);}
dataChanged=true;}}
if(dataChanged)
this.notifyObservers("onDataChanged");};Spry.Data.DataSet.prototype.startLoadInterval=function(interval)
{this.stopLoadInterval();if(interval>0)
{var self=this;this.loadInterval=interval;this.loadIntervalID=setInterval(function(){self.loadData();},interval);}};Spry.Data.DataSet.prototype.stopLoadInterval=function()
{if(this.loadIntervalID)
clearInterval(this.loadIntervalID);this.loadInterval=0;this.loadIntervalID=null;};Spry.Data.DataSet.nextDataSetID=0;Spry.Data.HTTPSourceDataSet=function(dataSetURL,dataSetOptions)
{Spry.Data.DataSet.call(this);this.url=dataSetURL;this.dataSetsForDataRefStrings=new Array;this.hasDataRefStrings=false;this.useCache=true;this.setRequestInfo(dataSetOptions,true);Spry.Utils.setOptions(this,dataSetOptions,true);this.recalculateDataSetDependencies();if(this.loadInterval>0)
this.startLoadInterval(this.loadInterval);};Spry.Data.HTTPSourceDataSet.prototype=new Spry.Data.DataSet();Spry.Data.HTTPSourceDataSet.prototype.constructor=Spry.Data.HTTPSourceDataSet;Spry.Data.HTTPSourceDataSet.prototype.setRequestInfo=function(requestInfo,undefineRequestProps)
{this.requestInfo=new Spry.Utils.loadURL.Request();this.requestInfo.extractRequestOptions(requestInfo,undefineRequestProps);if(this.requestInfo.method=="POST")
{if(!this.requestInfo.headers)
this.requestInfo.headers={};if(!this.requestInfo.headers['Content-Type'])
this.requestInfo.headers['Content-Type']="application/x-www-form-urlencoded; charset=UTF-8";}};Spry.Data.HTTPSourceDataSet.prototype.recalculateDataSetDependencies=function()
{this.hasDataRefStrings=false;var i=0;for(i=0;i<this.dataSetsForDataRefStrings.length;i++)
{var ds=this.dataSetsForDataRefStrings[i];if(ds)
ds.removeObserver(this);}
this.dataSetsForDataRefStrings=new Array();var regionStrs=this.getDataRefStrings();var dsCount=0;for(var n=0;n<regionStrs.length;n++)
{var tokens=Spry.Data.Region.getTokensFromStr(regionStrs[n]);for(i=0;tokens&&i<tokens.length;i++)
{if(tokens[i].search(/{[^}:]+::[^}]+}/)!=-1)
{var dsName=tokens[i].replace(/^\{|::.*\}/g,"");var ds=null;if(!this.dataSetsForDataRefStrings[dsName])
{ds=Spry.Data.getDataSetByName(dsName);if(dsName&&ds)
{this.dataSetsForDataRefStrings[dsName]=ds;this.dataSetsForDataRefStrings[dsCount++]=ds;this.hasDataRefStrings=true;}}}}}
for(i=0;i<this.dataSetsForDataRefStrings.length;i++)
{var ds=this.dataSetsForDataRefStrings[i];ds.addObserver(this);}};Spry.Data.HTTPSourceDataSet.prototype.getDataRefStrings=function()
{var strArr=[];if(this.url)strArr.push(this.url);if(this.requestInfo&&this.requestInfo.postData)strArr.push(this.requestInfo.postData);return strArr;};Spry.Data.HTTPSourceDataSet.prototype.attemptLoadData=function()
{for(var i=0;i<this.dataSetsForDataRefStrings.length;i++)
{var ds=this.dataSetsForDataRefStrings[i];if(ds.getLoadDataRequestIsPending()||!ds.getDataWasLoaded())
return;}
this.loadData();};Spry.Data.HTTPSourceDataSet.prototype.onCurrentRowChanged=function(ds,data)
{this.attemptLoadData();};Spry.Data.HTTPSourceDataSet.prototype.onPostSort=function(ds,data)
{this.attemptLoadData();};Spry.Data.HTTPSourceDataSet.prototype.onDataChanged=function(ds,data)
{this.attemptLoadData();};Spry.Data.HTTPSourceDataSet.prototype.loadData=function()
{if(!this.url)
return;this.cancelLoadData();var url=this.url;var postData=this.requestInfo.postData;if(this.hasDataRefStrings)
{var allDataSetsReady=true;for(var i=0;i<this.dataSetsForDataRefStrings.length;i++)
{var ds=this.dataSetsForDataRefStrings[i];if(ds.getLoadDataRequestIsPending())
allDataSetsReady=false;else if(!ds.getDataWasLoaded())
{ds.loadData();allDataSetsReady=false;}}
if(!allDataSetsReady)
return;url=Spry.Data.Region.processDataRefString(null,this.url,this.dataSetsForDataRefStrings);if(!url)
return;if(postData&&(typeof postData)=="string")
postData=Spry.Data.Region.processDataRefString(null,postData,this.dataSetsForDataRefStrings);}
this.notifyObservers("onPreLoad");this.data=null;this.dataWasLoaded=false;this.unfilteredData=null;this.dataHash=null;this.curRowID=0;var req=this.requestInfo.clone();req.url=url;req.postData=postData;this.pendingRequest=new Object;this.pendingRequest.data=Spry.Data.HTTPSourceDataSet.LoadManager.loadData(req,this,this.useCache);};Spry.Data.HTTPSourceDataSet.prototype.cancelLoadData=function()
{if(this.pendingRequest)
{Spry.Data.HTTPSourceDataSet.LoadManager.cancelLoadData(this.pendingRequest.data,this);this.pendingRequest=null;}};Spry.Data.HTTPSourceDataSet.prototype.getURL=function(){return this.url;};Spry.Data.HTTPSourceDataSet.prototype.setURL=function(url,requestOptions)
{if(this.url==url)
{if(!requestOptions||(this.requestInfo.method==requestOptions.method&&(requestOptions.method!="POST"||this.requestInfo.postData==requestOptions.postData)))
return;}
this.url=url;this.setRequestInfo(requestOptions);this.cancelLoadData();this.recalculateDataSetDependencies();this.dataWasLoaded=false;};Spry.Data.HTTPSourceDataSet.prototype.setDataFromDoc=function(rawDataDoc)
{this.pendingRequest=null;this.loadDataIntoDataSet(rawDataDoc);this.applyColumnTypes();this.disableNotifications();this.filterAndSortData();this.enableNotifications();this.notifyObservers("onPostLoad");this.notifyObservers("onDataChanged");};Spry.Data.HTTPSourceDataSet.prototype.loadDataIntoDataSet=function(rawDataDoc)
{this.dataHash=new Object;this.data=new Array;this.dataWasLoaded=true;};Spry.Data.HTTPSourceDataSet.prototype.xhRequestProcessor=function(xhRequest)
{var resp=xhRequest.responseText;if(xhRequest.status==200||xhRequest.status==0)
return resp;return null;};Spry.Data.HTTPSourceDataSet.prototype.sessionExpiredChecker=function(req)
{if(req.xhRequest.responseText=='session expired')
return true;return false;};Spry.Data.HTTPSourceDataSet.prototype.setSessionExpiredChecker=function(checker)
{this.sessionExpiredChecker=checker;};Spry.Data.HTTPSourceDataSet.prototype.onRequestResponse=function(cachedRequest,req)
{this.setDataFromDoc(cachedRequest.rawData);};Spry.Data.HTTPSourceDataSet.prototype.onRequestError=function(cachedRequest,req)
{this.notifyObservers("onLoadError",req);};Spry.Data.HTTPSourceDataSet.prototype.onRequestSessionExpired=function(cachedRequest,req)
{this.notifyObservers("onSessionExpired",req);};Spry.Data.HTTPSourceDataSet.LoadManager={};Spry.Data.HTTPSourceDataSet.LoadManager.cache=[];Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest=function(reqInfo,xhRequestProcessor,sessionExpiredChecker)
{Spry.Utils.Notifier.call(this);this.reqInfo=reqInfo;this.rawData=null;this.timer=null;this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED;this.xhRequestProcessor=xhRequestProcessor;this.sessionExpiredChecker=sessionExpiredChecker;};Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype=new Spry.Utils.Notifier();Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.constructor=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest;Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED=1;Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED=2;Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED=3;Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL=4;Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.loadDataCallback=function(req)
{if(req.xhRequest.readyState!=4)
return;var rawData=null;if(this.xhRequestProcessor)rawData=this.xhRequestProcessor(req.xhRequest);if(this.sessionExpiredChecker)
{Spry.Utils.setOptions(req,{'rawData':rawData},false);if(this.sessionExpiredChecker(req))
{this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED;this.notifyObservers("onRequestSessionExpired",req);this.observers.length=0;return;}}
if(!rawData)
{this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED;this.notifyObservers("onRequestError",req);this.observers.length=0;return;}
this.rawData=rawData;this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL;this.notifyObservers("onRequestResponse",req);this.observers.length=0;};Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.loadData=function()
{var self=this;this.cancelLoadData();this.rawData=null;this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED;var reqInfo=this.reqInfo.clone();reqInfo.successCallback=function(req){self.loadDataCallback(req);};reqInfo.errorCallback=reqInfo.successCallback;this.timer=setTimeout(function()
{self.timer=null;Spry.Utils.loadURL(reqInfo.method,reqInfo.url,reqInfo.async,reqInfo.successCallback,reqInfo);},0);};Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.cancelLoadData=function()
{if(this.state==Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED)
{if(this.timer)
{this.timer.clearTimeout();this.timer=null;}
this.rawData=null;this.state=Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED;}};Spry.Data.HTTPSourceDataSet.LoadManager.getCacheKey=function(reqInfo)
{return reqInfo.method+"::"+reqInfo.url+"::"+reqInfo.postData+"::"+reqInfo.username;};Spry.Data.HTTPSourceDataSet.LoadManager.loadData=function(reqInfo,ds,useCache)
{if(!reqInfo)
return null;var cacheObj=null;var cacheKey=null;if(useCache)
{cacheKey=Spry.Data.HTTPSourceDataSet.LoadManager.getCacheKey(reqInfo);cacheObj=Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey];}
if(cacheObj)
{if(cacheObj.state==Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED)
{if(ds)
cacheObj.addObserver(ds);return cacheObj;}
else if(cacheObj.state==Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL)
{if(ds)
setTimeout(function(){ds.setDataFromDoc(cacheObj.rawData);},0);return cacheObj;}}
if(!cacheObj)
{cacheObj=new Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest(reqInfo,(ds?ds.xhRequestProcessor:null),(ds?ds.sessionExpiredChecker:null));if(useCache)
{Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey]=cacheObj;cacheObj.addObserver({onRequestError:function(){Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey]=undefined;}});}}
if(ds)
cacheObj.addObserver(ds);cacheObj.loadData();return cacheObj;};Spry.Data.HTTPSourceDataSet.LoadManager.cancelLoadData=function(cacheObj,ds)
{if(cacheObj)
{if(ds)
cacheObj.removeObserver(ds);else
cacheObj.cancelLoadData();}};Spry.Data.XMLDataSet=function(dataSetURL,dataSetPath,dataSetOptions)
{this.xpath=dataSetPath;this.doc=null;this.subPaths=[];this.entityEncodeStrings=true;Spry.Data.HTTPSourceDataSet.call(this,dataSetURL,dataSetOptions);var jwType=typeof this.subPaths;if(jwType=="string"||(jwType=="object"&&this.subPaths.constructor!=Array))
this.subPaths=[this.subPaths];};Spry.Data.XMLDataSet.prototype=new Spry.Data.HTTPSourceDataSet();Spry.Data.XMLDataSet.prototype.constructor=Spry.Data.XMLDataSet;Spry.Data.XMLDataSet.prototype.getDataRefStrings=function()
{var strArr=[];if(this.url)strArr.push(this.url);if(this.xpath)strArr.push(this.xpath);if(this.requestInfo&&this.requestInfo.postData)strArr.push(this.requestInfo.postData);return strArr;};Spry.Data.XMLDataSet.prototype.getDocument=function(){return this.doc;};Spry.Data.XMLDataSet.prototype.getXPath=function(){return this.xpath;};Spry.Data.XMLDataSet.prototype.setXPath=function(path)
{if(this.xpath!=path)
{this.xpath=path;if(this.dataWasLoaded&&this.doc)
{this.notifyObservers("onPreLoad");this.setDataFromDoc(this.doc);}}};Spry.Data.XMLDataSet.nodeContainsElementNode=function(node)
{if(node)
{node=node.firstChild;while(node)
{if(node.nodeType==1)
return true;node=node.nextSibling;}}
return false;};Spry.Data.XMLDataSet.getNodeText=function(node,encodeText,encodeCData)
{var txt="";if(!node)
return;try
{var child=node.firstChild;while(child)
{try
{if(child.nodeType==3)
txt+=encodeText?Spry.Utils.encodeEntities(child.data):child.data;else if(child.nodeType==4)
txt+=encodeCData?Spry.Utils.encodeEntities(child.data):child.data;}catch(e){Spry.Debug.reportError("Spry.Data.XMLDataSet.getNodeText() exception caught: "+e+"\n");}
child=child.nextSibling;}}
catch(e){Spry.Debug.reportError("Spry.Data.XMLDataSet.getNodeText() exception caught: "+e+"\n");}
return txt;};Spry.Data.XMLDataSet.createObjectForNode=function(node,encodeText,encodeCData)
{if(!node)
return null;var obj=new Object();var i=0;var attr=null;try
{for(i=0;i<node.attributes.length;i++)
{attr=node.attributes[i];if(attr&&attr.nodeType==2)
obj["@"+attr.name]=attr.value;}}
catch(e)
{Spry.Debug.reportError("Spry.Data.XMLDataSet.createObjectForNode() caught exception while accessing attributes: "+e+"\n");}
var child=node.firstChild;if(child&&!child.nextSibling&&child.nodeType!=1)
{obj[node.nodeName]=Spry.Data.XMLDataSet.getNodeText(node,encodeText,encodeCData);}
while(child)
{if(child.nodeType==1)
{if(!Spry.Data.XMLDataSet.nodeContainsElementNode(child))
{obj[child.nodeName]=Spry.Data.XMLDataSet.getNodeText(child,encodeText,encodeCData);try
{var namePrefix=child.nodeName+"/@";for(i=0;i<child.attributes.length;i++)
{attr=child.attributes[i];if(attr&&attr.nodeType==2)
obj[namePrefix+attr.name]=attr.value;}}
catch(e)
{Spry.Debug.reportError("Spry.Data.XMLDataSet.createObjectForNode() caught exception while accessing attributes: "+e+"\n");}}}
child=child.nextSibling;}
return obj;};Spry.Data.XMLDataSet.getRecordSetFromXMLDoc=function(xmlDoc,path,suppressColumns,entityEncodeStrings)
{if(!xmlDoc||!path)
return null;var recordSet=new Object();recordSet.xmlDoc=xmlDoc;recordSet.xmlPath=path;recordSet.dataHash=new Object;recordSet.data=new Array;recordSet.getData=function(){return this.data;};var ctx=new ExprContext(xmlDoc);var pathExpr=xpathParse(path);var e=pathExpr.evaluate(ctx);var nodeArray=e.nodeSetValue();var isDOMNodeArray=true;if(nodeArray&&nodeArray.length>0)
isDOMNodeArray=nodeArray[0].nodeType!=2;var nextID=0;var encodeText=true;var encodeCData=false;if(typeof entityEncodeStrings=="boolean")
encodeText=encodeCData=entityEncodeStrings;for(var i=0;i<nodeArray.length;i++)
{var rowObj=null;if(suppressColumns)
rowObj=new Object;else
{if(isDOMNodeArray)
rowObj=Spry.Data.XMLDataSet.createObjectForNode(nodeArray[i],encodeText,encodeCData);else
{rowObj=new Object;rowObj["@"+nodeArray[i].name]=nodeArray[i].value;}}
if(rowObj)
{rowObj['ds_RowID']=nextID++;rowObj['ds_XMLNode']=nodeArray[i];recordSet.dataHash[rowObj['ds_RowID']]=rowObj;recordSet.data.push(rowObj);}}
return recordSet;};Spry.Data.XMLDataSet.PathNode=function(path)
{this.path=path;this.subPaths=[];this.xpath="";};Spry.Data.XMLDataSet.PathNode.prototype.addSubPath=function(path)
{var node=this.findSubPath(path);if(!node)
{node=new Spry.Data.XMLDataSet.PathNode(path);this.subPaths.push(node);}
return node;};Spry.Data.XMLDataSet.PathNode.prototype.findSubPath=function(path)
{var numSubPaths=this.subPaths.length;for(var i=0;i<numSubPaths;i++)
{var subPath=this.subPaths[i];if(path==subPath.path)
return subPath;}
return null;};Spry.Data.XMLDataSet.PathNode.prototype.consolidate=function()
{var numSubPaths=this.subPaths.length;if(!this.xpath&&numSubPaths==1)
{var subPath=this.subPaths[0];this.path+=((subPath[0]!="/")?"/":"")+subPath.path;this.xpath=subPath.xpath;this.subPaths=subPath.subPaths;this.consolidate();return;}
for(var i=0;i<numSubPaths;i++)
this.subPaths[i].consolidate();};Spry.Data.XMLDataSet.prototype.convertXPathsToPathTree=function(xpathArray)
{var xpaLen=xpathArray.length;var root=new Spry.Data.XMLDataSet.PathNode("");for(var i=0;i<xpaLen;i++)
{var xpath=xpathArray[i];var cleanXPath=xpath.replace(/\/\//g,"/__SPRYDS__");cleanXPath=cleanXPath.replace(/^\//,"");var pathItems=cleanXPath.split(/\//);var pathItemsLen=pathItems.length;var node=root;for(var j=0;j<pathItemsLen;j++)
{var path=pathItems[j].replace(/__SPRYDS__/,"//");node=node.addSubPath(path);}
node.xpath=xpath;}
root.consolidate();return root;};Spry.Data.XMLDataSet.prototype.flattenSubPaths=function(rs,subPaths)
{if(!rs||!subPaths)
return;var numSubPaths=subPaths.length;if(numSubPaths<1)
return;var data=rs.data;var dataHash={};var xpathArray=[];var cleanedXPathArray=[];for(var i=0;i<numSubPaths;i++)
{var subPath=subPaths[i];if(typeof subPath=="object")
subPath=subPath.path;if(!subPath)
subPath="";xpathArray[i]=Spry.Data.Region.processDataRefString(null,subPath,this.dataSetsForDataRefStrings);cleanedXPathArray[i]=xpathArray[i].replace(/\[.*\]/g,"");}
var row;var numRows=data.length;var newData=[];for(var i=0;i<numRows;i++)
{row=data[i];var newRows=[row];for(var j=0;j<numSubPaths;j++)
{var newRS=Spry.Data.XMLDataSet.getRecordSetFromXMLDoc(row.ds_XMLNode,xpathArray[j],(subPaths[j].xpath?false:true),this.entityEncodeStrings);if(newRS&&newRS.data&&newRS.data.length)
{if(typeof subPaths[j]=="object"&&subPaths[j].subPaths)
{var sp=subPaths[j].subPaths;spType=typeof sp;if(spType=="string")
sp=[sp];else if(spType=="object"&&spType.constructor==Object)
sp=[sp];this.flattenSubPaths(newRS,sp);}
var newRSData=newRS.data;var numRSRows=newRSData.length;var cleanedXPath=cleanedXPathArray[j]+"/";var numNewRows=newRows.length;var joinedRows=[];for(var k=0;k<numNewRows;k++)
{var newRow=newRows[k];for(var l=0;l<numRSRows;l++)
{var newRowObj=new Object;var newRSRow=newRSData[l];for(prop in newRow)
newRowObj[prop]=newRow[prop];for(var prop in newRSRow)
{var newPropName=cleanedXPath+prop;if(cleanedXPath==(prop+"/")||cleanedXPath.search(new RegExp("\\/"+prop+"\\/$"))!=-1)
newPropName=cleanedXPathArray[j];newRowObj[newPropName]=newRSRow[prop];}
joinedRows.push(newRowObj);}}
newRows=joinedRows;}}
newData=newData.concat(newRows);}
data=newData;numRows=data.length;for(i=0;i<numRows;i++)
{row=data[i];row.ds_RowID=i;dataHash[row.ds_RowID]=row;}
rs.data=data;rs.dataHash=dataHash;};Spry.Data.XMLDataSet.prototype.loadDataIntoDataSet=function(rawDataDoc)
{var rs=null;var mainXPath=Spry.Data.Region.processDataRefString(null,this.xpath,this.dataSetsForDataRefStrings);var subPaths=this.subPaths;var suppressColumns=false;if(this.subPaths&&this.subPaths.length>0)
{var processedSubPaths=[];var numSubPaths=subPaths.length;for(var i=0;i<numSubPaths;i++)
{var subPathStr=Spry.Data.Region.processDataRefString(null,subPaths[i],this.dataSetsForDataRefStrings);if(subPathStr.charAt(0)!='/')
subPathStr=mainXPath+"/"+subPathStr;processedSubPaths.push(subPathStr);}
processedSubPaths.unshift(mainXPath);var commonParent=this.convertXPathsToPathTree(processedSubPaths);mainXPath=commonParent.path;subPaths=commonParent.subPaths;suppressColumns=commonParent.xpath?false:true;}
rs=Spry.Data.XMLDataSet.getRecordSetFromXMLDoc(rawDataDoc,mainXPath,suppressColumns,this.entityEncodeStrings);if(!rs)
{Spry.Debug.reportError("Spry.Data.XMLDataSet.loadDataIntoDataSet() failed to create dataSet '"+this.name+"'for '"+this.xpath+"' - "+this.url+"\n");return;}
this.flattenSubPaths(rs,subPaths);this.doc=rs.xmlDoc;this.data=rs.data;this.dataHash=rs.dataHash;this.dataWasLoaded=(this.doc!=null);};Spry.Data.XMLDataSet.prototype.xhRequestProcessor=function(xhRequest)
{var resp=xhRequest.responseXML;var manualParseRequired=false;if(xhRequest.status!=200)
{if(xhRequest.status==0)
{if(xhRequest.responseText&&(!resp||!resp.firstChild))
manualParseRequired=true;}}
else if(!resp)
{manualParseRequired=true;}
if(manualParseRequired)
resp=Spry.Utils.stringToXMLDoc(xhRequest.responseText);if(!resp||!resp.firstChild||resp.firstChild.nodeName=="parsererror")
return null;return resp;};Spry.Data.XMLDataSet.prototype.sessionExpiredChecker=function(req)
{if(req.xhRequest.responseText=='session expired')
return true;else
{if(req.rawData)
{var firstChild=req.rawData.documentElement.firstChild;if(firstChild&&firstChild.nodeValue=="session expired")
return true;}}
return false;};Spry.Data.Region=function(regionNode,name,isDetailRegion,data,dataSets,regionStates,regionStateMap,hasBehaviorAttributes)
{this.regionNode=regionNode;this.name=name;this.isDetailRegion=isDetailRegion;this.data=data;this.dataSets=dataSets;this.hasBehaviorAttributes=hasBehaviorAttributes;this.tokens=null;this.currentState=null;this.states={ready:true};this.stateMap={};Spry.Utils.setOptions(this.states,regionStates);Spry.Utils.setOptions(this.stateMap,regionStateMap);for(var i=0;i<this.dataSets.length;i++)
{var ds=this.dataSets[i];try
{if(ds)
ds.addObserver(this);}
catch(e){Spry.Debug.reportError("Failed to add '"+this.name+"' as a dataSet observer!\n");}}};Spry.Data.Region.hiddenRegionClassName="SpryHiddenRegion";Spry.Data.Region.evenRowClassName="even";Spry.Data.Region.oddRowClassName="odd";Spry.Data.Region.notifiers={};Spry.Data.Region.evalScripts=true;Spry.Data.Region.addObserver=function(regionID,observer)
{var n=Spry.Data.Region.notifiers[regionID];if(!n)
{n=new Spry.Utils.Notifier();Spry.Data.Region.notifiers[regionID]=n;}
n.addObserver(observer);};Spry.Data.Region.removeObserver=function(regionID,observer)
{var n=Spry.Data.Region.notifiers[regionID];if(n)
n.removeObserver(observer);};Spry.Data.Region.notifyObservers=function(methodName,region,data)
{var n=Spry.Data.Region.notifiers[region.name];if(n)
{var dataObj={};if(data&&typeof data=="object")
dataObj=data;else
dataObj.data=data;dataObj.region=region;dataObj.regionID=region.name;dataObj.regionNode=region.regionNode;n.notifyObservers(methodName,dataObj);}};Spry.Data.Region.RS_Error=0x01;Spry.Data.Region.RS_LoadingData=0x02;Spry.Data.Region.RS_PreUpdate=0x04;Spry.Data.Region.RS_PostUpdate=0x08;Spry.Data.Region.prototype.getState=function()
{return this.currentState;};Spry.Data.Region.prototype.mapState=function(stateName,newStateName)
{this.stateMap[stateName]=newStateName;};Spry.Data.Region.prototype.getMappedState=function(stateName)
{var mappedState=this.stateMap[stateName];return mappedState?mappedState:stateName;};Spry.Data.Region.prototype.setState=function(stateName,suppressNotfications)
{var stateObj={state:stateName,mappedState:this.getMappedState(stateName)};if(!suppressNotfications)
Spry.Data.Region.notifyObservers("onPreStateChange",this,stateObj);this.currentState=stateObj.mappedState?stateObj.mappedState:stateName;if(this.states[stateName])
{var notificationData={state:this.currentState};if(!suppressNotfications)
Spry.Data.Region.notifyObservers("onPreUpdate",this,notificationData);var str=this.transform();if(Spry.Data.Region.debug)
Spry.Debug.trace("<hr />Generated region markup for '"+this.name+"':<br /><br />"+Spry.Utils.encodeEntities(str));Spry.Utils.setInnerHTML(this.regionNode,str,!Spry.Data.Region.evalScripts);if(this.hasBehaviorAttributes)
this.attachBehaviors();if(!suppressNotfications)
Spry.Data.Region.notifyObservers("onPostUpdate",this,notificationData);}
if(!suppressNotfications)
Spry.Data.Region.notifyObservers("onPostStateChange",this,stateObj);};Spry.Data.Region.prototype.getDataSets=function()
{return this.dataSets;};Spry.Data.Region.prototype.addDataSet=function(aDataSet)
{if(!aDataSet)
return;if(!this.dataSets)
this.dataSets=new Array;for(var i=0;i<this.dataSets.length;i++)
{if(this.dataSets[i]==aDataSet)
return;}
this.dataSets.push(aDataSet);aDataSet.addObserver(this);};Spry.Data.Region.prototype.removeDataSet=function(aDataSet)
{if(!aDataSet||this.dataSets)
return;for(var i=0;i<this.dataSets.length;i++)
{if(this.dataSets[i]==aDataSet)
{this.dataSets.splice(i,1);aDataSet.removeObserver(this);return;}}};Spry.Data.Region.prototype.onPreLoad=function(dataSet)
{if(this.currentState!="loading")
this.setState("loading");};Spry.Data.Region.prototype.onLoadError=function(dataSet)
{if(this.currentState!="error")
this.setState("error");Spry.Data.Region.notifyObservers("onError",this);};Spry.Data.Region.prototype.onSessionExpired=function(dataSet)
{if(this.currentState!="expired")
this.setState("expired");Spry.Data.Region.notifyObservers("onExpired",this);};Spry.Data.Region.prototype.onCurrentRowChanged=function(dataSet,data)
{if(this.isDetailRegion)
this.updateContent();};Spry.Data.Region.prototype.onPostSort=function(dataSet,data)
{this.updateContent();};Spry.Data.Region.prototype.onDataChanged=function(dataSet,data)
{this.updateContent();};Spry.Data.Region.enableBehaviorAttributes=true;Spry.Data.Region.behaviorAttrs={};Spry.Data.Region.behaviorAttrs["spry:select"]={attach:function(rgn,node,value)
{var selectGroupName=null;try{selectGroupName=node.attributes.getNamedItem("spry:selectgroup").value;}catch(e){}
if(!selectGroupName)
selectGroupName="default";Spry.Utils.addEventListener(node,"click",function(event){Spry.Utils.SelectionManager.select(selectGroupName,node,value);},false);if(node.attributes.getNamedItem("spry:selected"))
Spry.Utils.SelectionManager.select(selectGroupName,node,value);}};Spry.Data.Region.behaviorAttrs["spry:hover"]={attach:function(rgn,node,value)
{Spry.Utils.addEventListener(node,"mouseover",function(event){Spry.Utils.addClassName(node,value);},false);Spry.Utils.addEventListener(node,"mouseout",function(event){Spry.Utils.removeClassName(node,value);},false);}};Spry.Data.Region.setUpRowNumberForEvenOddAttr=function(node,attr,value,rowNumAttrName)
{if(!value)
{Spry.Debug.showError("The "+attr+" attribute requires a CSS class name as its value!");node.attributes.removeNamedItem(attr);return;}
var dsName="";var valArr=value.split(/\s/);if(valArr.length>1)
{dsName=valArr[0];node.setAttribute(attr,valArr[1]);}
node.setAttribute(rowNumAttrName,"{"+(dsName?(dsName+"::"):"")+"ds_RowNumber}");};Spry.Data.Region.behaviorAttrs["spry:even"]={setup:function(node,value)
{Spry.Data.Region.setUpRowNumberForEvenOddAttr(node,"spry:even",value,"spryevenrownumber");},attach:function(rgn,node,value)
{if(value)
{rowNumAttr=node.attributes.getNamedItem("spryevenrownumber");if(rowNumAttr&&rowNumAttr.value)
{var rowNum=parseInt(rowNumAttr.value);if(rowNum%2)
Spry.Utils.addClassName(node,value);}}
node.removeAttribute("spry:even");node.removeAttribute("spryevenrownumber");}};Spry.Data.Region.behaviorAttrs["spry:odd"]={setup:function(node,value)
{Spry.Data.Region.setUpRowNumberForEvenOddAttr(node,"spry:odd",value,"spryoddrownumber");},attach:function(rgn,node,value)
{if(value)
{rowNumAttr=node.attributes.getNamedItem("spryoddrownumber");if(rowNumAttr&&rowNumAttr.value)
{var rowNum=parseInt(rowNumAttr.value);if(rowNum%2==0)
Spry.Utils.addClassName(node,value);}}
node.removeAttribute("spry:odd");node.removeAttribute("spryoddrownumber");}};Spry.Data.Region.setRowAttrClickHandler=function(node,dsName,rowAttr,funcName)
{if(dsName)
{var ds=Spry.Data.getDataSetByName(dsName);if(ds)
{rowIDAttr=node.attributes.getNamedItem(rowAttr);if(rowIDAttr)
{var rowAttrVal=rowIDAttr.value;if(rowAttrVal)
Spry.Utils.addEventListener(node,"click",function(event){ds[funcName](rowAttrVal);},false);}}}};Spry.Data.Region.behaviorAttrs["spry:setrow"]={setup:function(node,value)
{if(!value)
{Spry.Debug.reportError("The spry:setrow attribute requires a data set name as its value!");node.removeAttribute("spry:setrow");return;}
node.setAttribute("spryrowid","{"+value+"::ds_RowID}");},attach:function(rgn,node,value)
{Spry.Data.Region.setRowAttrClickHandler(node,value,"spryrowid","setCurrentRow");node.removeAttribute("spry:setrow");node.removeAttribute("spryrowid");}};Spry.Data.Region.behaviorAttrs["spry:setrownumber"]={setup:function(node,value)
{if(!value)
{Spry.Debug.reportError("The spry:setrownumber attribute requires a data set name as its value!");node.removeAttribute("spry:setrownumber");return;}
node.setAttribute("spryrownumber","{"+value+"::ds_RowID}");},attach:function(rgn,node,value)
{Spry.Data.Region.setRowAttrClickHandler(node,value,"spryrownumber","setCurrentRowNumber");node.removeAttribute("spry:setrownumber");node.removeAttribute("spryrownumber");}};Spry.Data.Region.behaviorAttrs["spry:sort"]={attach:function(rgn,node,value)
{if(!value)
return;var ds=rgn.getDataSets()[0];var sortOrder="toggle";var colArray=value.split(/\s/);if(colArray.length>1)
{var specifiedDS=Spry.Data.getDataSetByName(colArray[0]);if(specifiedDS)
{ds=specifiedDS;colArray.shift();}
if(colArray.length>1)
{var str=colArray[colArray.length-1];if(str=="ascending"||str=="descending"||str=="toggle")
{sortOrder=str;colArray.pop();}}}
if(ds&&colArray.length>0)
Spry.Utils.addEventListener(node,"click",function(event){ds.sort(colArray,sortOrder);},false);node.removeAttribute("spry:sort");}};Spry.Data.Region.prototype.attachBehaviors=function()
{var rgn=this;Spry.Utils.getNodesByFunc(this.regionNode,function(node)
{if(!node||node.nodeType!=1)
return false;try
{var bAttrs=Spry.Data.Region.behaviorAttrs;for(var bAttrName in bAttrs)
{var attr=node.attributes.getNamedItem(bAttrName);if(attr)
{var behavior=bAttrs[bAttrName];if(behavior&&behavior.attach)
behavior.attach(rgn,node,attr.value);}}}catch(e){}
return false;});};Spry.Data.Region.prototype.updateContent=function()
{var allDataSetsReady=true;var dsArray=this.getDataSets();if(!dsArray||dsArray.length<1)
{Spry.Debug.reportError("updateContent(): Region '"+this.name+"' has no data set!\n");return;}
for(var i=0;i<dsArray.length;i++)
{var ds=dsArray[i];if(ds)
{if(ds.getLoadDataRequestIsPending())
allDataSetsReady=false;else if(!ds.getDataWasLoaded())
{ds.loadData();allDataSetsReady=false;}}}
if(!allDataSetsReady)
{Spry.Data.Region.notifyObservers("onLoadingData",this);return;}
this.setState("ready");};Spry.Data.Region.prototype.clearContent=function()
{this.regionNode.innerHTML="";};Spry.Data.Region.processContentPI=function(inStr)
{var outStr="";var regexp=/<!--\s*<\/?spry:content\s*[^>]*>\s*-->/mg;var searchStartIndex=0;var processingContentTag=0;while(inStr.length)
{var results=regexp.exec(inStr);if(!results||!results[0])
{outStr+=inStr.substr(searchStartIndex,inStr.length-searchStartIndex);break;}
if(!processingContentTag&&results.index!=searchStartIndex)
{outStr+=inStr.substr(searchStartIndex,results.index-searchStartIndex);}
if(results[0].search(/<\//)!=-1)
{--processingContentTag;if(processingContentTag)
Spry.Debug.reportError("Nested spry:content regions are not allowed!\n");}
else
{++processingContentTag;var dataRefStr=results[0].replace(/.*\bdataref="/,"");outStr+=dataRefStr.replace(/".*$/,"");}
searchStartIndex=regexp.lastIndex;}
return outStr;};Spry.Data.Region.prototype.tokenizeData=function(dataStr)
{if(!dataStr)
return null;var rootToken=new Spry.Data.Region.Token(Spry.Data.Region.Token.LIST_TOKEN,null,null,null);var tokenStack=new Array;var parseStr=Spry.Data.Region.processContentPI(dataStr);tokenStack.push(rootToken);var regexp=/((<!--\s*){0,1}<\/{0,1}spry:[^>]+>(\s*-->){0,1})|((\{|%7[bB])[^\}\s%]+(\}|%7[dD]))/mg;var searchStartIndex=0;while(parseStr.length)
{var results=regexp.exec(parseStr);var token=null;if(!results||!results[0])
{var str=parseStr.substr(searchStartIndex,parseStr.length-searchStartIndex);token=new Spry.Data.Region.Token(Spry.Data.Region.Token.STRING_TOKEN,null,str,str);tokenStack[tokenStack.length-1].addChild(token);break;}
if(results.index!=searchStartIndex)
{var str=parseStr.substr(searchStartIndex,results.index-searchStartIndex);token=new Spry.Data.Region.Token(Spry.Data.Region.Token.STRING_TOKEN,null,str,str);tokenStack[tokenStack.length-1].addChild(token);}
if(results[0].search(/^({|%7[bB])/)!=-1)
{var valueName=results[0];var regionStr=results[0];valueName=valueName.replace(/^({|%7[bB])/,"");valueName=valueName.replace(/(}|%7[dD])$/,"");var dataSetName=null;var splitArray=valueName.split(/::/);if(splitArray.length>1)
{dataSetName=splitArray[0];valueName=splitArray[1];}
regionStr=regionStr.replace(/^%7[bB]/,"{");regionStr=regionStr.replace(/%7[dD]$/,"}");token=new Spry.Data.Region.Token(Spry.Data.Region.Token.VALUE_TOKEN,dataSetName,valueName,new String(regionStr));tokenStack[tokenStack.length-1].addChild(token);}
else if(results[0].charAt(0)=='<')
{var piName=results[0].replace(/^(<!--\s*){0,1}<\/?/,"");piName=piName.replace(/>(\s*-->){0,1}|\s.*$/,"");if(results[0].search(/<\//)!=-1)
{if(tokenStack[tokenStack.length-1].tokenType!=Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN)
{Spry.Debug.reportError("Invalid processing instruction close tag: "+piName+" -- "+results[0]+"\n");return null;}
tokenStack.pop();}
else
{var piDesc=Spry.Data.Region.PI.instructions[piName];if(piDesc)
{var dataSet=null;var selectedDataSetName="";if(results[0].search(/^.*\bselect=\"/)!=-1)
{selectedDataSetName=results[0].replace(/^.*\bselect=\"/,"");selectedDataSetName=selectedDataSetName.replace(/".*$/,"");if(selectedDataSetName)
{dataSet=Spry.Data.getDataSetByName(selectedDataSetName);if(!dataSet)
{Spry.Debug.reportError("Failed to retrieve data set ("+selectedDataSetName+") for "+piName+"\n");selectedDataSetName="";}}}
var jsExpr=null;if(results[0].search(/^.*\btest=\"/)!=-1)
{jsExpr=results[0].replace(/^.*\btest=\"/,"");jsExpr=jsExpr.replace(/".*$/,"");jsExpr=Spry.Utils.decodeEntities(jsExpr);}
var regionState=null;if(results[0].search(/^.*\bname=\"/)!=-1)
{regionState=results[0].replace(/^.*\bname=\"/,"");regionState=regionState.replace(/".*$/,"");regionState=Spry.Utils.decodeEntities(regionState);}
var piData=new Spry.Data.Region.Token.PIData(piName,selectedDataSetName,jsExpr,regionState);token=new Spry.Data.Region.Token(Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN,dataSet,piData,new String(results[0]));tokenStack[tokenStack.length-1].addChild(token);tokenStack.push(token);}
else
{Spry.Debug.reportError("Unsupported region processing instruction: "+results[0]+"\n");return null;}}}
else
{Spry.Debug.reportError("Invalid region token: "+results[0]+"\n");return null;}
searchStartIndex=regexp.lastIndex;}
return rootToken;};Spry.Data.Region.prototype.callScriptFunction=function(funcName,processContext)
{var result=undefined;funcName=funcName.replace(/^\s*\{?\s*function::\s*|\s*\}?\s*$/g,"");var func=Spry.Utils.getObjectByName(funcName);if(func)
result=func(this.name,function(){return processContext.getValueFromDataSet.apply(processContext,arguments);});return result;};Spry.Data.Region.prototype.evaluateExpression=function(exprStr,processContext)
{var result=undefined;try
{if(exprStr.search(/^\s*function::/)!=-1)
result=this.callScriptFunction(exprStr,processContext);else
result=Spry.Utils.eval(Spry.Data.Region.processDataRefString(processContext,exprStr,null,true));}
catch(e)
{Spry.Debug.trace("Caught exception in Spry.Data.Region.prototype.evaluateExpression() while evaluating: "+Spry.Utils.encodeEntities(exprStr)+"\n    Exception:"+e+"\n");}
return result;};Spry.Data.Region.prototype.processTokenChildren=function(outputArr,token,processContext)
{var children=token.children;var len=children.length;for(var i=0;i<len;i++)
this.processTokens(outputArr,children[i],processContext);};Spry.Data.Region.prototype.processTokens=function(outputArr,token,processContext)
{var i=0;switch(token.tokenType)
{case Spry.Data.Region.Token.LIST_TOKEN:this.processTokenChildren(outputArr,token,processContext);break;case Spry.Data.Region.Token.STRING_TOKEN:outputArr.push(token.data);break;case Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN:if(token.data.name=="spry:repeat")
{var dataSet=null;if(token.dataSet)
dataSet=token.dataSet;else
dataSet=this.dataSets[0];if(dataSet)
{var dsContext=processContext.getDataSetContext(dataSet);if(!dsContext)
{Spry.Debug.reportError("processTokens() failed to get a data set context!\n");break;}
dsContext.pushState();var dataSetRows=dsContext.getData();var numRows=dataSetRows.length;for(i=0;i<numRows;i++)
{dsContext.setRowIndex(i);var testVal=true;if(token.data.jsExpr)
testVal=this.evaluateExpression(token.data.jsExpr,processContext);if(testVal)
this.processTokenChildren(outputArr,token,processContext);}
dsContext.popState();}}
else if(token.data.name=="spry:if")
{var testVal=true;if(token.data.jsExpr)
testVal=this.evaluateExpression(token.data.jsExpr,processContext);if(testVal)
this.processTokenChildren(outputArr,token,processContext);}
else if(token.data.name=="spry:choose")
{var defaultChild=null;var childToProcess=null;var testVal=false;var j=0;for(j=0;j<token.children.length;j++)
{var child=token.children[j];if(child.tokenType==Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN)
{if(child.data.name=="spry:when")
{if(child.data.jsExpr)
{testVal=this.evaluateExpression(child.data.jsExpr,processContext);if(testVal)
{childToProcess=child;break;}}}
else if(child.data.name=="spry:default")
defaultChild=child;}}
if(!childToProcess&&defaultChild)
childToProcess=defaultChild;if(childToProcess)
this.processTokenChildren(outputArr,childToProcess,processContext);}
else if(token.data.name=="spry:state")
{var testVal=true;if(!token.data.regionState||token.data.regionState==this.currentState)
this.processTokenChildren(outputArr,token,processContext);}
else
{Spry.Debug.reportError("processTokens(): Unknown processing instruction: "+token.data.name+"\n");return"";}
break;case Spry.Data.Region.Token.VALUE_TOKEN:var dataSet=token.dataSet;var val=undefined;if(dataSet&&dataSet=="function")
{val=this.callScriptFunction(token.data,processContext);}
else
{if(!dataSet&&this.dataSets&&this.dataSets.length>0&&this.dataSets[0])
{dataSet=this.dataSets[0];}
if(!dataSet)
{Spry.Debug.reportError("processTokens(): Value reference has no data set specified: "+token.regionStr+"\n");return"";}
val=processContext.getValueFromDataSet(dataSet,token.data);}
if(typeof val!="undefined")
outputArr.push(val+"");break;default:Spry.Debug.reportError("processTokens(): Invalid token type: "+token.regionStr+"\n");break;}};Spry.Data.Region.prototype.transform=function()
{if(this.data&&!this.tokens)
this.tokens=this.tokenizeData(this.data);if(!this.tokens)
return"";processContext=new Spry.Data.Region.ProcessingContext(this);if(!processContext)
return"";var outputArr=[""];this.processTokens(outputArr,this.tokens,processContext);return outputArr.join("");};Spry.Data.Region.PI={};Spry.Data.Region.PI.instructions={};Spry.Data.Region.PI.buildOpenTagForValueAttr=function(ele,piName,attrName)
{if(!ele||!piName)
return"";var jsExpr="";try
{var testAttr=ele.attributes.getNamedItem(piName);if(testAttr&&testAttr.value)
jsExpr=Spry.Utils.encodeEntities(testAttr.value);}
catch(e){jsExpr="";}
if(!jsExpr)
{Spry.Debug.reportError(piName+" attribute requires a JavaScript expression that returns true or false!\n");return"";}
return"<"+Spry.Data.Region.PI.instructions[piName].tagName+" "+attrName+"=\""+jsExpr+"\">";};Spry.Data.Region.PI.buildOpenTagForTest=function(ele,piName)
{return Spry.Data.Region.PI.buildOpenTagForValueAttr(ele,piName,"test");};Spry.Data.Region.PI.buildOpenTagForState=function(ele,piName)
{return Spry.Data.Region.PI.buildOpenTagForValueAttr(ele,piName,"name");};Spry.Data.Region.PI.buildOpenTagForRepeat=function(ele,piName)
{if(!ele||!piName)
return"";var selectAttrStr="";try
{var selectAttr=ele.attributes.getNamedItem(piName);if(selectAttr&&selectAttr.value)
{selectAttrStr=selectAttr.value;selectAttrStr=selectAttrStr.replace(/\s/g,"");}}
catch(e){selectAttrStr="";}
if(!selectAttrStr)
{Spry.Debug.reportError(piName+" attribute requires a data set name!\n");return"";}
var testAttrStr="";try
{var testAttr=ele.attributes.getNamedItem("spry:test");if(testAttr)
{if(testAttr.value)
testAttrStr=" test=\""+Spry.Utils.encodeEntities(testAttr.value)+"\"";ele.attributes.removeNamedItem(testAttr.nodeName);}}
catch(e){testAttrStr="";}
return"<"+Spry.Data.Region.PI.instructions[piName].tagName+" select=\""+selectAttrStr+"\""+testAttrStr+">";};Spry.Data.Region.PI.buildOpenTagForContent=function(ele,piName)
{if(!ele||!piName)
return"";var dataRefStr="";try
{var contentAttr=ele.attributes.getNamedItem(piName);if(contentAttr&&contentAttr.value)
dataRefStr=Spry.Utils.encodeEntities(contentAttr.value);}
catch(e){dataRefStr="";}
if(!dataRefStr)
{Spry.Debug.reportError(piName+" attribute requires a data reference!\n");return"";}
return"<"+Spry.Data.Region.PI.instructions[piName].tagName+" dataref=\""+dataRefStr+"\">";};Spry.Data.Region.PI.buildOpenTag=function(ele,piName)
{return"<"+Spry.Data.Region.PI.instructions[piName].tagName+">";};Spry.Data.Region.PI.buildCloseTag=function(ele,piName)
{return"</"+Spry.Data.Region.PI.instructions[piName].tagName+">";};Spry.Data.Region.PI.instructions["spry:state"]={tagName:"spry:state",childrenOnly:false,getOpenTag:Spry.Data.Region.PI.buildOpenTagForState,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:if"]={tagName:"spry:if",childrenOnly:false,getOpenTag:Spry.Data.Region.PI.buildOpenTagForTest,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:repeat"]={tagName:"spry:repeat",childrenOnly:false,getOpenTag:Spry.Data.Region.PI.buildOpenTagForRepeat,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:repeatchildren"]={tagName:"spry:repeat",childrenOnly:true,getOpenTag:Spry.Data.Region.PI.buildOpenTagForRepeat,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:choose"]={tagName:"spry:choose",childrenOnly:true,getOpenTag:Spry.Data.Region.PI.buildOpenTag,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:when"]={tagName:"spry:when",childrenOnly:false,getOpenTag:Spry.Data.Region.PI.buildOpenTagForTest,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:default"]={tagName:"spry:default",childrenOnly:false,getOpenTag:Spry.Data.Region.PI.buildOpenTag,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.instructions["spry:content"]={tagName:"spry:content",childrenOnly:true,getOpenTag:Spry.Data.Region.PI.buildOpenTagForContent,getCloseTag:Spry.Data.Region.PI.buildCloseTag};Spry.Data.Region.PI.orderedInstructions=["spry:state","spry:if","spry:repeat","spry:repeatchildren","spry:choose","spry:when","spry:default","spry:content"];Spry.Data.Region.getTokensFromStr=function(str)
{if(!str)
return null;return str.match(/{[^}]+}/g);};Spry.Data.Region.processDataRefString=function(processingContext,regionStr,dataSetsToUse,isJSExpr)
{if(!regionStr)
return"";if(!processingContext&&!dataSetsToUse)
return regionStr;var resultStr="";var re=new RegExp("\\{([^\\}:]+::)?[^\\}]+\\}","g");var startSearchIndex=0;while(startSearchIndex<regionStr.length)
{var reArray=re.exec(regionStr);if(!reArray||!reArray[0])
{resultStr+=regionStr.substr(startSearchIndex,regionStr.length-startSearchIndex);return resultStr;}
if(reArray.index!=startSearchIndex)
resultStr+=regionStr.substr(startSearchIndex,reArray.index-startSearchIndex);var dsName="";if(reArray[0].search(/^\{[^}:]+::/)!=-1)
dsName=reArray[0].replace(/^\{|::.*/g,"");var fieldName=reArray[0].replace(/^\{|.*::|\}/g,"");var row=null;var val="";if(processingContext)
val=processingContext.getValueFromDataSet(dsName,fieldName);else
{var ds=dsName?dataSetsToUse[dsName]:dataSetsToUse[0];if(ds)
val=ds.getValue(fieldName);}
if(typeof val!="undefined")
{val+="";resultStr+=isJSExpr?Spry.Utils.escapeQuotesAndLineBreaks(val):val;}
if(startSearchIndex==re.lastIndex)
{var leftOverIndex=reArray.index+reArray[0].length;if(leftOverIndex<regionStr.length)
resultStr+=regionStr.substr(leftOverIndex);break;}
startSearchIndex=re.lastIndex;}
return resultStr;};Spry.Data.Region.strToDataSetsArray=function(str,returnRegionNames)
{var dataSetsArr=new Array;var foundHash={};if(!str)
return dataSetsArr;str=str.replace(/\s+/g," ");str=str.replace(/^\s|\s$/g,"");var arr=str.split(/ /);for(var i=0;i<arr.length;i++)
{if(arr[i]&&!Spry.Data.Region.PI.instructions[arr[i]])
{try{var dataSet=Spry.Data.getDataSetByName(arr[i]);if(!foundHash[arr[i]])
{if(returnRegionNames)
dataSetsArr.push(arr[i]);else
dataSetsArr.push(dataSet);foundHash[arr[i]]=true;}}
catch(e){}}}
return dataSetsArr;};Spry.Data.Region.DSContext=function(dataSet,processingContext)
{var m_dataSet=dataSet;var m_processingContext=processingContext;var m_curRowIndexArray=[{rowIndex:-1}];var m_parent=null;var m_children=[];var getInternalRowIndex=function(){return m_curRowIndexArray[m_curRowIndexArray.length-1].rowIndex;};this.resetAll=function(){m_curRowIndexArray=[{rowIndex:m_dataSet.getCurrentRow()}]};this.getDataSet=function(){return m_dataSet;};this.getNumRows=function(unfiltered)
{var data=this.getCurrentState().data;return data?data.length:m_dataSet.getRowCount(unfiltered);};this.getData=function()
{var data=this.getCurrentState().data;return data?data:m_dataSet.getData();};this.setData=function(data)
{this.getCurrentState().data=data;};this.getValue=function(valueName,rowContext)
{var result="";var curState=this.getCurrentState();var ds=curState.nestedDS?curState.nestedDS:this.getDataSet();if(ds)
result=ds.getValue(valueName,rowContext);return result;};this.getCurrentRow=function()
{if(m_curRowIndexArray.length<2||getInternalRowIndex()<0)
return m_dataSet.getCurrentRow();var data=this.getData();var curRowIndex=getInternalRowIndex();if(curRowIndex<0||curRowIndex>data.length)
{Spry.Debug.reportError("Invalid index used in Spry.Data.Region.DSContext.getCurrentRow()!\n");return null;}
return data[curRowIndex];};this.getRowIndex=function()
{var curRowIndex=getInternalRowIndex();if(curRowIndex>=0)
return curRowIndex;return m_dataSet.getRowNumber(m_dataSet.getCurrentRow());};this.setRowIndex=function(rowIndex)
{this.getCurrentState().rowIndex=rowIndex;var data=this.getData();var numChildren=m_children.length;for(var i=0;i<numChildren;i++)
m_children[i].syncDataWithParentRow(this,rowIndex,data);};this.syncDataWithParentRow=function(parentDSContext,rowIndex,parentData)
{var row=parentData[rowIndex];if(row)
{nestedDS=m_dataSet.getNestedDataSetForParentRow(row);if(nestedDS)
{var currentState=this.getCurrentState();currentState.nestedDS=nestedDS;currentState.data=nestedDS.getData();currentState.rowIndex=nestedDS.getCurrentRowNumber();currentState.rowIndex=currentState.rowIndex<0?0:currentState.rowIndex;var numChildren=m_children.length;for(var i=0;i<numChildren;i++)
m_children[i].syncDataWithParentRow(this,currentState.rowIndex,currentState.data);}}};this.pushState=function()
{var curState=this.getCurrentState();var newState=new Object;newState.rowIndex=curState.rowIndex;newState.data=curState.data;newState.nestedDS=curState.nestedDS;m_curRowIndexArray.push(newState);var numChildren=m_children.length;for(var i=0;i<numChildren;i++)
m_children[i].pushState();};this.popState=function()
{if(m_curRowIndexArray.length<2)
{Spry.Debug.reportError("Stack underflow in Spry.Data.Region.DSContext.popState()!\n");return;}
var numChildren=m_children.length;for(var i=0;i<numChildren;i++)
m_children[i].popState();m_curRowIndexArray.pop();};this.getCurrentState=function()
{return m_curRowIndexArray[m_curRowIndexArray.length-1];};this.addChild=function(childDSContext)
{var numChildren=m_children.length;for(var i=0;i<numChildren;i++)
{if(m_children[i]==childDSContext)
return;}
m_children.push(childDSContext);};};Spry.Data.Region.ProcessingContext=function(region)
{this.region=region;this.dataSetContexts=[];if(region&&region.dataSets)
{var dsArray=region.dataSets.slice(0);var dsArrayLen=dsArray.length;for(var i=0;i<dsArrayLen;i++)
{var ds=region.dataSets[i];while(ds&&ds.getParentDataSet)
{var doesExist=false;ds=ds.getParentDataSet();if(ds&&this.indexOf(dsArray,ds)==-1)
dsArray.push(ds);}}
for(i=0;i<dsArray.length;i++)
this.dataSetContexts.push(new Spry.Data.Region.DSContext(dsArray[i],this));var dsContexts=this.dataSetContexts;var numDSContexts=dsContexts.length;for(i=0;i<numDSContexts;i++)
{var dsc=dsContexts[i];var ds=dsc.getDataSet();if(ds.getParentDataSet)
{var parentDS=ds.getParentDataSet();if(parentDS)
{var pdsc=this.getDataSetContext(parentDS);if(pdsc)pdsc.addChild(dsc);}}}}};Spry.Data.Region.ProcessingContext.prototype.indexOf=function(arr,item)
{if(arr)
{var arrLen=arr.length;for(var i=0;i<arrLen;i++)
if(arr[i]==item)
return i;}
return-1;};Spry.Data.Region.ProcessingContext.prototype.getDataSetContext=function(dataSet)
{if(!dataSet)
{if(this.dataSetContexts.length>0)
return this.dataSetContexts[0];return null;}
if(typeof dataSet=='string')
{dataSet=Spry.Data.getDataSetByName(dataSet);if(!dataSet)
return null;}
for(var i=0;i<this.dataSetContexts.length;i++)
{var dsc=this.dataSetContexts[i];if(dsc.getDataSet()==dataSet)
return dsc;}
return null;};Spry.Data.Region.ProcessingContext.prototype.getValueFromDataSet=function()
{var dsName="";var columnName="";if(arguments.length>1)
{dsName=arguments[0];columnName=arguments[1];}
else
{var dataRef=arguments[0].replace(/\s*{\s*|\s*}\s*/g,"");if(dataRef.search("::")!=-1)
{dsName=dataRef.replace(/::.*/,"");columnName=dataRef.replace(/.*::/,"");}
else
columnName=dataRef;}
var result="";var dsContext=this.getDataSetContext(dsName);if(dsContext)
result=dsContext.getValue(columnName,dsContext.getCurrentRow());else
Spry.Debug.reportError("getValueFromDataSet: Failed to get "+dsName+" context for the "+this.region.regionNode.id+" region.\n");return result;};Spry.Data.Region.ProcessingContext.prototype.$v=Spry.Data.Region.ProcessingContext.prototype.getValueFromDataSet;Spry.Data.Region.ProcessingContext.prototype.getCurrentRowForDataSet=function(dataSet)
{var dsc=this.getDataSetContext(dataSet);if(dsc)
return dsc.getCurrentRow();return null;};Spry.Data.Region.Token=function(tokenType,dataSet,data,regionStr)
{var self=this;this.tokenType=tokenType;this.dataSet=dataSet;this.data=data;this.regionStr=regionStr;this.parent=null;this.children=null;};Spry.Data.Region.Token.prototype.addChild=function(child)
{if(!child)
return;if(!this.children)
this.children=new Array;this.children.push(child);child.parent=this;};Spry.Data.Region.Token.LIST_TOKEN=0;Spry.Data.Region.Token.STRING_TOKEN=1;Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN=2;Spry.Data.Region.Token.VALUE_TOKEN=3;Spry.Data.Region.Token.PIData=function(piName,data,jsExpr,regionState)
{var self=this;this.name=piName;this.data=data;this.jsExpr=jsExpr;this.regionState=regionState;};Spry.Utils.addLoadListener(function(){setTimeout(function(){if(Spry.Data.initRegionsOnLoad)Spry.Data.initRegions();},0);});



/*
* Begin File: "admin/js/SpryUtils.js"
*/

// SpryUtils.js - version 0.3 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2007. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

var Spry; if (!Spry) Spry = {}; if (!Spry.Utils) Spry.Utils = {};


Spry.Utils.submitForm = function(form, callback, opts)
{
	if (!form)
		return true;

	if ( typeof form == 'string' )
		form = Spry.$(form) || document.forms[form];

	var frmOpts = {};
	frmOpts.method = form.getAttribute('method');
	frmOpts.url = form.getAttribute('action') || document.location.href;
	frmOpts.enctype = form.getAttribute('enctype');

	Spry.Utils.setOptions(frmOpts, opts);

	var submitData = Spry.Utils.extractParamsFromForm(form, frmOpts.elements);
	if (frmOpts.additionalData)
		submitData += "&" + frmOpts.additionalData;

	if (!frmOpts.enctype || frmOpts.enctype.toLowerCase() != 'multipart/form-data')
	{
		// Ajax submission of a form doesn't work for multipart/form-data!
		frmOpts.method = (frmOpts.method && frmOpts.method.toLowerCase() == "post") ? 'POST' : 'GET';
		if (frmOpts.method == "GET")
		{
			// Data will be submitted in the url.
			if (frmOpts.url.indexOf('?') == -1)
				frmOpts.url += '?';
			else
				frmOpts.url += '&';
			frmOpts.url += submitData;
		}
		else
		{
			// Send Content-Type header.
			if (!frmOpts.headers) frmOpts.headers = {};
			if (!frmOpts.headers['Content-Type'] || frmOpts.headers['Content-Type'].indexOf("application/x-www-form-urlencoded") ==-1 )
				frmOpts.headers['Content-Type'] = 'application/x-www-form-urlencoded';

			// Set the postData
			frmOpts.postData = submitData;
		}

		Spry.Utils.loadURL(frmOpts.method, frmOpts.url, true, callback, frmOpts);
		return false;
	}

	// Native submission when 'multipart/form-data' is used.
	return true;
};


Spry.Utils.extractParamsFromForm = function (form, elements)
{
	if (!form)
		return '';

	if ( typeof form == 'string' )
		form = document.getElementById(form) || document.forms[form];

	var formElements;
	if (elements)
		formElements = ',' + elements.join(',') + ',';

	var compStack = new Array(); // key=value pairs

	var el;
	for (var i = 0; i < form.elements.length; i++ )
	{
		el = form.elements[i];
		if (el.disabled || !el.name)
		{
			// Don't submit disabled elements.
			// Don't submit elements without name.
			continue;
		}

		if (!el.type)
		{
			// It seems that this element doesn't have a type set,
			// so skip it.
			continue;
		}

		if (formElements && formElements.indexOf(',' + el.name + ',')==-1)
			continue;

		switch(el.type.toLowerCase())
		{
			case 'text':
			case 'password':
			case 'textarea':
			case 'hidden':
			case 'submit':
				compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
				break;
			case 'select-one':
				var value = '';
				var opt;
				if (el.selectedIndex >= 0) {
					opt = el.options[el.selectedIndex];
					value = opt.value || opt.text;
				}
				compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(value));
				break;
			case 'select-multiple':
				for (var j = 0; j < el.length; j++)
				{
					if (el.options[j].selected)
					{
						value = el.options[j].value || el.options[j].text;
						compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(value));
					}
				}
				break;
			case 'checkbox':
			case 'radio':
				if (el.checked)
					compStack.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
				break;
			default:
			// file, button, reset
			break;
			}
		}
	return compStack.join('&');
};




/*
* Begin File: "SpryAssets/SpryCollapsiblePanel.js"
*/

// SpryCollapsiblePanel.js - version 0.7 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};

Spry.Widget.CollapsiblePanel = function(element, opts)
{
	this.element = this.getElement(element);
	this.focusElement = null;
	this.hoverClass = "CollapsiblePanelTabHover";
	this.openClass = "CollapsiblePanelOpen";
	this.closedClass = "CollapsiblePanelClosed";
	this.focusedClass = "CollapsiblePanelFocused";
	this.enableAnimation = true;
	this.enableKeyboardNavigation = true;
	this.animator = null;
	this.hasFocus = false;
	this.contentIsOpen = true;

	this.openPanelKeyCode = Spry.Widget.CollapsiblePanel.KEY_DOWN;
	this.closePanelKeyCode = Spry.Widget.CollapsiblePanel.KEY_UP;

	Spry.Widget.CollapsiblePanel.setOptions(this, opts);

	this.attachBehaviors();
};

Spry.Widget.CollapsiblePanel.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.CollapsiblePanel.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.CollapsiblePanel.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.CollapsiblePanel.prototype.hasClassName = function(ele, className)
{
	if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
		return false;
	return true;
};

Spry.Widget.CollapsiblePanel.prototype.setDisplay = function(ele, display)
{
	if( ele )
		ele.style.display = display;
};

Spry.Widget.CollapsiblePanel.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
	if (!optionsObj)
		return;
	for (var optionName in optionsObj)
	{
		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
			continue;
		obj[optionName] = optionsObj[optionName];
	}
};

Spry.Widget.CollapsiblePanel.prototype.onTabMouseOver = function(e)
{
	this.addClassName(this.getTab(), this.hoverClass);
	return false;
};

Spry.Widget.CollapsiblePanel.prototype.onTabMouseOut = function(e)
{
	this.removeClassName(this.getTab(), this.hoverClass);
	return false;
};

Spry.Widget.CollapsiblePanel.prototype.open = function()
{
	this.contentIsOpen = true;
	if (this.enableAnimation)
	{
		if (this.animator)
			this.animator.stop();
		this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, true, { duration: this.duration, fps: this.fps, transition: this.transition });
		this.animator.start();
	}
	else
		this.setDisplay(this.getContent(), "block");

	this.removeClassName(this.element, this.closedClass);
	this.addClassName(this.element, this.openClass);
};

Spry.Widget.CollapsiblePanel.prototype.close = function()
{
	this.contentIsOpen = false;
	if (this.enableAnimation)
	{
		if (this.animator)
			this.animator.stop();
		this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, false, { duration: this.duration, fps: this.fps, transition: this.transition });
		this.animator.start();
	}
	else
		this.setDisplay(this.getContent(), "none");

	this.removeClassName(this.element, this.openClass);
	this.addClassName(this.element, this.closedClass);
};

Spry.Widget.CollapsiblePanel.prototype.onTabClick = function(e)
{
	if (this.isOpen())
		this.close();
	else
		this.open();

	this.focus();

	return this.stopPropagation(e);
};

Spry.Widget.CollapsiblePanel.prototype.onFocus = function(e)
{
	this.hasFocus = true;
	this.addClassName(this.element, this.focusedClass);
	return false;
};

Spry.Widget.CollapsiblePanel.prototype.onBlur = function(e)
{
	this.hasFocus = false;
	this.removeClassName(this.element, this.focusedClass);
	return false;
};

Spry.Widget.CollapsiblePanel.KEY_UP = 38;
Spry.Widget.CollapsiblePanel.KEY_DOWN = 40;

Spry.Widget.CollapsiblePanel.prototype.onKeyDown = function(e)
{
	var key = e.keyCode;
	if (!this.hasFocus || (key != this.openPanelKeyCode && key != this.closePanelKeyCode))
		return true;

	if (this.isOpen() && key == this.closePanelKeyCode)
		this.close();
	else if ( key == this.openPanelKeyCode)
		this.open();
	
	return this.stopPropagation(e);
};

Spry.Widget.CollapsiblePanel.prototype.stopPropagation = function(e)
{
	if (e.preventDefault) e.preventDefault();
	else e.returnValue = false;
	if (e.stopPropagation) e.stopPropagation();
	else e.cancelBubble = true;
	return false;
};

Spry.Widget.CollapsiblePanel.prototype.attachPanelHandlers = function()
{
	var tab = this.getTab();
	if (!tab)
		return;

	var self = this;
	Spry.Widget.CollapsiblePanel.addEventListener(tab, "click", function(e) { return self.onTabClick(e); }, false);
	Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e); }, false);
	Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e); }, false);

	if (this.enableKeyboardNavigation)
	{
		// XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
		// rely on adding the tabindex attribute if it is missing to enable keyboard navigation
		// by default.

		// Find the first element within the tab container that has a tabindex or the first
		// anchor tag.
		
		var tabIndexEle = null;
		var tabAnchorEle = null;

		this.preorderTraversal(tab, function(node) {
			if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
			{
				var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
				if (tabIndexAttr)
				{
					tabIndexEle = node;
					return true;
				}
				if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
					tabAnchorEle = node;
			}
			return false;
		});

		if (tabIndexEle)
			this.focusElement = tabIndexEle;
		else if (tabAnchorEle)
			this.focusElement = tabAnchorEle;

		if (this.focusElement)
		{
			Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "focus", function(e) { return self.onFocus(e); }, false);
			Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "blur", function(e) { return self.onBlur(e); }, false);
			Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "keydown", function(e) { return self.onKeyDown(e); }, false);
		}
	}
};

Spry.Widget.CollapsiblePanel.addEventListener = function(element, eventType, handler, capture)
{
	try
	{
		if (element.addEventListener)
			element.addEventListener(eventType, handler, capture);
		else if (element.attachEvent)
			element.attachEvent("on" + eventType, handler);
	}
	catch (e) {}
};

Spry.Widget.CollapsiblePanel.prototype.preorderTraversal = function(root, func)
{
	var stopTraversal = false;
	if (root)
	{
		stopTraversal = func(root);
		if (root.hasChildNodes())
		{
			var child = root.firstChild;
			while (!stopTraversal && child)
			{
				stopTraversal = this.preorderTraversal(child, func);
				try { child = child.nextSibling; } catch (e) { child = null; }
			}
		}
	}
	return stopTraversal;
};

Spry.Widget.CollapsiblePanel.prototype.attachBehaviors = function()
{
	var panel = this.element;
	var tab = this.getTab();
	var content = this.getContent();

	if (this.contentIsOpen || this.hasClassName(panel, this.openClass))
	{
		this.addClassName(panel, this.openClass);
		this.removeClassName(panel, this.closedClass);
		this.setDisplay(content, "block");
		this.contentIsOpen = true;
	}
	else
	{
		this.removeClassName(panel, this.openClass);
		this.addClassName(panel, this.closedClass);
		this.setDisplay(content, "none");
		this.contentIsOpen = false;
	}

	this.attachPanelHandlers();
};

Spry.Widget.CollapsiblePanel.prototype.getTab = function()
{
	return this.getElementChildren(this.element)[0];
};

Spry.Widget.CollapsiblePanel.prototype.getContent = function()
{
	return this.getElementChildren(this.element)[1];
};

Spry.Widget.CollapsiblePanel.prototype.isOpen = function()
{
	return this.contentIsOpen;
};

Spry.Widget.CollapsiblePanel.prototype.getElementChildren = function(element)
{
	var children = [];
	var child = element.firstChild;
	while (child)
	{
		if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
			children.push(child);
		child = child.nextSibling;
	}
	return children;
};

Spry.Widget.CollapsiblePanel.prototype.focus = function()
{
	if (this.focusElement && this.focusElement.focus)
		this.focusElement.focus();
};

/////////////////////////////////////////////////////

Spry.Widget.CollapsiblePanel.PanelAnimator = function(panel, doOpen, opts)
{
	this.timer = null;
	this.interval = 0;

	this.fps = 60;
	this.duration = 500;
	this.startTime = 0;

	this.transition = Spry.Widget.CollapsiblePanel.PanelAnimator.defaultTransition;

	this.onComplete = null;

	this.panel = panel;
	this.content = panel.getContent();
	this.doOpen = doOpen;

	Spry.Widget.CollapsiblePanel.setOptions(this, opts, true);

	this.interval = Math.floor(1000 / this.fps);

	var c = this.content;

	var curHeight = c.offsetHeight ? c.offsetHeight : 0;
	this.fromHeight = (doOpen && c.style.display == "none") ? 0 : curHeight;

	if (!doOpen)
		this.toHeight = 0;
	else
	{
		if (c.style.display == "none")
		{
			// The content area is not displayed so in order to calculate the extent
			// of the content inside it, we have to set its display to block.

			c.style.visibility = "hidden";
			c.style.display = "block";
		}

		// Clear the height property so we can calculate
		// the full height of the content we are going to show.

		c.style.height = "";
		this.toHeight = c.offsetHeight;
	}

	this.distance = this.toHeight - this.fromHeight;
	this.overflow = c.style.overflow;

	c.style.height = this.fromHeight + "px";
	c.style.visibility = "visible";
	c.style.overflow = "hidden";
	c.style.display = "block";
};

Spry.Widget.CollapsiblePanel.PanelAnimator.defaultTransition = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); };

Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.start = function()
{
	var self = this;
	this.startTime = (new Date).getTime();
	this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
};

Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stop = function()
{
	if (this.timer)
	{
		clearTimeout(this.timer);

		// If we're killing the timer, restore the overflow property.

		this.content.style.overflow = this.overflow;
	}

	this.timer = null;
};

Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stepAnimation = function()
{
	var curTime = (new Date).getTime();
	var elapsedTime = curTime - this.startTime;

	if (elapsedTime >= this.duration)
	{
		if (!this.doOpen)
			this.content.style.display = "none";
		this.content.style.overflow = this.overflow;
		//this.content.style.height = this.toHeight + "px";
		this.content.style.height = "auto";
		if (this.onComplete)
			this.onComplete();
		return;
	}

	var ht = this.transition(elapsedTime, this.fromHeight, this.distance, this.duration);

	this.content.style.height = ((ht < 0) ? 0 : ht) + "px";

	var self = this;
	this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
};

Spry.Widget.CollapsiblePanelGroup = function(element, opts)
{
	this.element = this.getElement(element);
	this.opts = opts;

	this.attachBehaviors();
};

Spry.Widget.CollapsiblePanelGroup.prototype.setOptions = Spry.Widget.CollapsiblePanel.prototype.setOptions;
Spry.Widget.CollapsiblePanelGroup.prototype.getElement = Spry.Widget.CollapsiblePanel.prototype.getElement;
Spry.Widget.CollapsiblePanelGroup.prototype.getElementChildren = Spry.Widget.CollapsiblePanel.prototype.getElementChildren;

Spry.Widget.CollapsiblePanelGroup.prototype.setElementWidget = function(element, widget)
{
	if (!element || !widget)
		return;
	if (!element.spry)
		element.spry = new Object;
	element.spry.collapsiblePanel = widget;
};

Spry.Widget.CollapsiblePanelGroup.prototype.getElementWidget = function(element)
{
	return (element && element.spry && element.spry.collapsiblePanel) ? element.spry.collapsiblePanel : null;
};

Spry.Widget.CollapsiblePanelGroup.prototype.getPanels = function()
{
	if (!this.element)
		return [];
	return this.getElementChildren(this.element);
};

Spry.Widget.CollapsiblePanelGroup.prototype.getPanel = function(panelIndex)
{
	return this.getPanels()[panelIndex];
};

Spry.Widget.CollapsiblePanelGroup.prototype.attachBehaviors = function()
{
	if (!this.element)
		return;

	var cpanels = this.getPanels();
	var numCPanels = cpanels.length;
	for (var i = 0; i < numCPanels; i++)
	{
		var cpanel = cpanels[i];
		this.setElementWidget(cpanel, new Spry.Widget.CollapsiblePanel(cpanel, this.opts));
	}
};

Spry.Widget.CollapsiblePanelGroup.prototype.openPanel = function(panelIndex)
{
	var w = this.getElementWidget(this.getPanel(panelIndex));
	if (w && !w.isOpen())
		w.open();
};

Spry.Widget.CollapsiblePanelGroup.prototype.closePanel = function(panelIndex)
{
	var w = this.getElementWidget(this.getPanel(panelIndex));
	if (w && w.isOpen())
		w.close();
};

Spry.Widget.CollapsiblePanelGroup.prototype.openAllPanels = function()
{
	var cpanels = this.getPanels();
	var numCPanels = cpanels.length;
	for (var i = 0; i < numCPanels; i++)
	{
		var w = this.getElementWidget(cpanels[i]);
		if (w && !w.isOpen())
			w.open();
	}
};

Spry.Widget.CollapsiblePanelGroup.prototype.closeAllPanels = function()
{
	var cpanels = this.getPanels();
	var numCPanels = cpanels.length;
	for (var i = 0; i < numCPanels; i++)
	{
		var w = this.getElementWidget(cpanels[i]);
		if (w && w.isOpen())
			w.close();
	}
};





/*
* Begin File: "js/AC_RunActiveContent.js"
*/

//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2007 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion()
{
	var version;
	var axo;
	var e;

	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}

	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";

			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";

			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");

		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];

        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}

function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}




/*
* Begin File: "SpryAssets/SpryMenuBar.js"
*/

// SpryMenuBar.js - version 0.12 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

/*******************************************************************************

 SpryMenuBar.js
 This file handles the JavaScript for Spry Menu Bar.  You should have no need
 to edit this file.  Some highlights of the MenuBar object is that timers are
 used to keep submenus from showing up until the user has hovered over the parent
 menu item for some time, as well as a timer for when they leave a submenu to keep
 showing that submenu until the timer fires.

 *******************************************************************************/

var Spry; if (!Spry) Spry = {}; if (!Spry.Widget) Spry.Widget = {};

Spry.BrowserSniff = function()
{
	var b = navigator.appName.toString();
	var up = navigator.platform.toString();
	var ua = navigator.userAgent.toString();

	this.mozilla = this.ie = this.opera = this.safari = false;
	var re_opera = /Opera.([0-9\.]*)/i;
	var re_msie = /MSIE.([0-9\.]*)/i;
	var re_gecko = /gecko/i;
	var re_safari = /(applewebkit|safari)\/([\d\.]*)/i;
	var r = false;

	if ( (r = ua.match(re_opera))) {
		this.opera = true;
		this.version = parseFloat(r[1]);
	} else if ( (r = ua.match(re_msie))) {
		this.ie = true;
		this.version = parseFloat(r[1]);
	} else if ( (r = ua.match(re_safari))) {
		this.safari = true;
		this.version = parseFloat(r[2]);
	} else if (ua.match(re_gecko)) {
		var re_gecko_version = /rv:\s*([0-9\.]+)/i;
		r = ua.match(re_gecko_version);
		this.mozilla = true;
		this.version = parseFloat(r[1]);
	}
	this.windows = this.mac = this.linux = false;

	this.Platform = ua.match(/windows/i) ? "windows" :
					(ua.match(/linux/i) ? "linux" :
					(ua.match(/mac/i) ? "mac" :
					ua.match(/unix/i)? "unix" : "unknown"));
	this[this.Platform] = true;
	this.v = this.version;

	if (this.safari && this.mac && this.mozilla) {
		this.mozilla = false;
	}
};

Spry.is = new Spry.BrowserSniff();

// Constructor for Menu Bar
// element should be an ID of an unordered list (<ul> tag)
// preloadImage1 and preloadImage2 are images for the rollover state of a menu
Spry.Widget.MenuBar = function(element, opts)
{
	this.init(element, opts);
};

Spry.Widget.MenuBar.prototype.init = function(element, opts)
{
	this.element = this.getElement(element);

	// represents the current (sub)menu we are operating on
	this.currMenu = null;
	this.showDelay = 250;
	this.hideDelay = 600;
	if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (Spry.is.ie && typeof document.uniqueID == 'undefined'))
	{
		// bail on older unsupported browsers
		return;
	}

	// Fix IE6 CSS images flicker
	if (Spry.is.ie && Spry.is.version < 7){
		try {
			document.execCommand("BackgroundImageCache", false, true);
		} catch(err) {}
	}

	this.upKeyCode = Spry.Widget.MenuBar.KEY_UP;
	this.downKeyCode = Spry.Widget.MenuBar.KEY_DOWN;
	this.leftKeyCode = Spry.Widget.MenuBar.KEY_LEFT;
	this.rightKeyCode = Spry.Widget.MenuBar.KEY_RIGHT;
	this.escKeyCode = Spry.Widget.MenuBar.KEY_ESC;

	this.hoverClass = 'MenuBarItemHover';
	this.subHoverClass = 'MenuBarItemSubmenuHover';
	this.subVisibleClass ='MenuBarSubmenuVisible';
	this.hasSubClass = 'MenuBarItemSubmenu';
	this.activeClass = 'MenuBarActive';
	this.isieClass = 'MenuBarItemIE';
	this.verticalClass = 'MenuBarVertical';
	this.horizontalClass = 'MenuBarHorizontal';
	this.enableKeyboardNavigation = true;

	this.hasFocus = false;
	// load hover images now
	if(opts)
	{
		for(var k in opts)
		{
			if (typeof this[k] == 'undefined')
			{
				var rollover = new Image;
				rollover.src = opts[k];
			}
		}
		Spry.Widget.MenuBar.setOptions(this, opts);
	}

	// safari doesn't support tabindex
	if (Spry.is.safari)
		this.enableKeyboardNavigation = false;

	if(this.element)
	{
		this.currMenu = this.element;
		var items = this.element.getElementsByTagName('li');
		for(var i=0; i<items.length; i++)
		{
			if (i > 0 && this.enableKeyboardNavigation)
				items[i].getElementsByTagName('a')[0].tabIndex='-1';

			this.initialize(items[i], element);
			if(Spry.is.ie)
			{
				this.addClassName(items[i], this.isieClass);
				items[i].style.position = "static";
			}
		}
		if (this.enableKeyboardNavigation)
		{
			var self = this;
			this.addEventListener(document, 'keydown', function(e){self.keyDown(e); }, false);
		}

		if(Spry.is.ie)
		{
			if(this.hasClassName(this.element, this.verticalClass))
			{
				this.element.style.position = "relative";
			}
			var linkitems = this.element.getElementsByTagName('a');
			for(var i=0; i<linkitems.length; i++)
			{
				linkitems[i].style.position = "relative";
			}
		}
	}
};
Spry.Widget.MenuBar.KEY_ESC = 27;
Spry.Widget.MenuBar.KEY_UP = 38;
Spry.Widget.MenuBar.KEY_DOWN = 40;
Spry.Widget.MenuBar.KEY_LEFT = 37;
Spry.Widget.MenuBar.KEY_RIGHT = 39;

Spry.Widget.MenuBar.prototype.getElement = function(ele)
{
	if (ele && typeof ele == "string")
		return document.getElementById(ele);
	return ele;
};

Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className)
{
	if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
	{
		return false;
	}
	return true;
};

Spry.Widget.MenuBar.prototype.addClassName = function(ele, className)
{
	if (!ele || !className || this.hasClassName(ele, className))
		return;
	ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className)
{
	if (!ele || !className || !this.hasClassName(ele, className))
		return;
	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

// addEventListener for Menu Bar
// attach an event to a tag without creating obtrusive HTML code
Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
{
	try
	{
		if (element.addEventListener)
		{
			element.addEventListener(eventType, handler, capture);
		}
		else if (element.attachEvent)
		{
			element.attachEvent('on' + eventType, handler);
		}
	}
	catch (e) {}
};

// createIframeLayer for Menu Bar
// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX
Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu)
{
	var layer = document.createElement('iframe');
	layer.tabIndex = '-1';
	layer.src = 'javascript:""';
	layer.frameBorder = '0';
	layer.scrolling = 'no';
	menu.parentNode.appendChild(layer);
	
	layer.style.left = menu.offsetLeft + 'px';
	layer.style.top = menu.offsetTop + 'px';
	layer.style.width = menu.offsetWidth + 'px';
	layer.style.height = menu.offsetHeight + 'px';
};

// removeIframeLayer for Menu Bar
// removes an IFRAME underneath a menu to reveal any form controls and ActiveX
Spry.Widget.MenuBar.prototype.removeIframeLayer =  function(menu)
{
	var layers = ((menu == this.element) ? menu : menu.parentNode).getElementsByTagName('iframe');
	while(layers.length > 0)
	{
		layers[0].parentNode.removeChild(layers[0]);
	}
};

// clearMenus for Menu Bar
// root is the top level unordered list (<ul> tag)
Spry.Widget.MenuBar.prototype.clearMenus = function(root)
{
	var menus = root.getElementsByTagName('ul');
	for(var i=0; i<menus.length; i++)
		this.hideSubmenu(menus[i]);

	this.removeClassName(this.element, this.activeClass);
};

// bubbledTextEvent for Menu Bar
// identify bubbled up text events in Safari so we can ignore them
Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
{
	return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget));
};

// showSubmenu for Menu Bar
// set the proper CSS class on this menu to show it
Spry.Widget.MenuBar.prototype.showSubmenu = function(menu)
{
	if(this.currMenu)
	{
		this.clearMenus(this.currMenu);
		this.currMenu = null;
	}
	
	if(menu)
	{
		this.addClassName(menu, this.subVisibleClass);
		if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
		{
			if(!this.hasClassName(this.element, this.horizontalClass) || menu.parentNode.parentNode != this.element)
			{
				menu.style.top = menu.parentNode.offsetTop + 'px';
			}
		}
		if(Spry.is.ie && Spry.is.version < 7)
		{
			this.createIframeLayer(menu);
		}
	}
	this.addClassName(this.element, this.activeClass);
};

// hideSubmenu for Menu Bar
// remove the proper CSS class on this menu to hide it
Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu)
{
	if(menu)
	{
		this.removeClassName(menu, this.subVisibleClass);
		if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
		{
			menu.style.top = '';
			menu.style.left = '';
		}
		if(Spry.is.ie && Spry.is.version < 7)
			this.removeIframeLayer(menu);
	}
};

// initialize for Menu Bar
// create event listeners for the Menu Bar widget so we can properly
// show and hide submenus
Spry.Widget.MenuBar.prototype.initialize = function(listitem, element)
{
	var opentime, closetime;
	var link = listitem.getElementsByTagName('a')[0];
	var submenus = listitem.getElementsByTagName('ul');
	var menu = (submenus.length > 0 ? submenus[0] : null);

	if(menu)
		this.addClassName(link, this.hasSubClass);

	if(!Spry.is.ie)
	{
		// define a simple function that comes standard in IE to determine
		// if a node is within another node
		listitem.contains = function(testNode)
		{
			// this refers to the list item
			if(testNode == null)
				return false;

			if(testNode == this)
				return true;
			else
				return this.contains(testNode.parentNode);
		};
	}

	// need to save this for scope further down
	var self = this;
	this.addEventListener(listitem, 'mouseover', function(e){self.mouseOver(listitem, e);}, false);
	this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);

	if (this.enableKeyboardNavigation)
	{
		this.addEventListener(link, 'blur', function(e){self.onBlur(listitem);}, false);
		this.addEventListener(link, 'focus', function(e){self.keyFocus(listitem, e);}, false);
	}
};
Spry.Widget.MenuBar.prototype.keyFocus = function (listitem, e)
{
	this.lastOpen = listitem.getElementsByTagName('a')[0];
	this.addClassName(this.lastOpen, listitem.getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
	this.hasFocus = true;
};
Spry.Widget.MenuBar.prototype.onBlur = function (listitem)
{
	this.clearSelection(listitem);
};
Spry.Widget.MenuBar.prototype.clearSelection = function(el){
	//search any intersection with the current open element
	if (!this.lastOpen)
		return;

	if (el)
	{
		el = el.getElementsByTagName('a')[0];
		
		// check children
		var item = this.lastOpen;
		while (item != this.element)
		{
			var tmp = el;
			while (tmp != this.element)
			{
				if (tmp == item)
					return;
				try{
					tmp = tmp.parentNode;
				}catch(err){break;}
			}
			item = item.parentNode;
		}
	}
	var item = this.lastOpen;
	while (item != this.element)
	{
		this.hideSubmenu(item.parentNode);
		var link = item.getElementsByTagName('a')[0];
		this.removeClassName(link, this.hoverClass);
		this.removeClassName(link, this.subHoverClass);
		item = item.parentNode;
	}
	this.lastOpen = false;
};
Spry.Widget.MenuBar.prototype.keyDown = function (e)
{
	if (!this.hasFocus)
		return;

	if (!this.lastOpen)
	{
		this.hasFocus = false;
		return;
	}

	var e = e|| event;
	var listitem = this.lastOpen.parentNode;
	var link = this.lastOpen;
	var submenus = listitem.getElementsByTagName('ul');
	var menu = (submenus.length > 0 ? submenus[0] : null);
	var hasSubMenu = (menu) ? true : false;

	var opts = [listitem, menu, null, this.getSibling(listitem, 'previousSibling'), this.getSibling(listitem, 'nextSibling')];
	
	if (!opts[3])
		opts[2] = (listitem.parentNode.parentNode.nodeName.toLowerCase() == 'li')?listitem.parentNode.parentNode:null;

	var found = 0;
	switch (e.keyCode){
		case this.upKeyCode:
			found = this.getElementForKey(opts, 'y', 1);
			break;
		case this.downKeyCode:
			found = this.getElementForKey(opts, 'y', -1);
			break;
		case this.leftKeyCode:
			found = this.getElementForKey(opts, 'x', 1);
			break;
		case this.rightKeyCode:
			found = this.getElementForKey(opts, 'x', -1);
			break;
		case this.escKeyCode:
		case 9:
			this.clearSelection();
			this.hasFocus = false;
		default: return;
	}
	switch (found)
	{
		case 0: return;
		case 1:
			//subopts
			this.mouseOver(listitem, e);
			break;
		case 2:
			//parent
			this.mouseOut(opts[2], e);
			break;
		case 3:
		case 4:
			// left - right
			this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
			break;
	}
	var link = opts[found].getElementsByTagName('a')[0];
	if (opts[found].nodeName.toLowerCase() == 'ul')
		opts[found] = opts[found].getElementsByTagName('li')[0];

	this.addClassName(link, opts[found].getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
	this.lastOpen = link;
	opts[found].getElementsByTagName('a')[0].focus();
  
        //stop further event handling by the browser
	return Spry.Widget.MenuBar.stopPropagation(e);
};
Spry.Widget.MenuBar.prototype.mouseOver = function (listitem, e)
{
	var link = listitem.getElementsByTagName('a')[0];
	var submenus = listitem.getElementsByTagName('ul');
	var menu = (submenus.length > 0 ? submenus[0] : null);
	var hasSubMenu = (menu) ? true : false;
	if (this.enableKeyboardNavigation)
		this.clearSelection(listitem);

	if(this.bubbledTextEvent())
	{
		// ignore bubbled text events
		return;
	}

	if (listitem.closetime)
		clearTimeout(listitem.closetime);

	if(this.currMenu == listitem)
	{
		this.currMenu = null;
	}

	// move the focus too
	if (this.hasFocus)
		link.focus();

	// show menu highlighting
	this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
	this.lastOpen = link;
	if(menu && !this.hasClassName(menu, this.subHoverClass))
	{
		var self = this;
		listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay);
	}
};
Spry.Widget.MenuBar.prototype.mouseOut = function (listitem, e)
{
	var link = listitem.getElementsByTagName('a')[0];
	var submenus = listitem.getElementsByTagName('ul');
	var menu = (submenus.length > 0 ? submenus[0] : null);
	var hasSubMenu = (menu) ? true : false;
	if(this.bubbledTextEvent())
	{
		// ignore bubbled text events
		return;
	}

	var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement);
	if(!listitem.contains(related))
	{
		if (listitem.opentime) 
			clearTimeout(listitem.opentime);
		this.currMenu = listitem;

		// remove menu highlighting
		this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
		if(menu)
		{
			var self = this;
			listitem.closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, this.hideDelay);
		}
		if (this.hasFocus)
			link.blur();
	}
};
Spry.Widget.MenuBar.prototype.getSibling = function(element, sibling)
{
	var child = element[sibling];
	while (child && child.nodeName.toLowerCase() !='li')
		child = child[sibling];

	return child;
};
Spry.Widget.MenuBar.prototype.getElementForKey = function(els, prop, dir)
{
	var found = 0;
	var rect = Spry.Widget.MenuBar.getPosition;
	var ref = rect(els[found]);

	var hideSubmenu = false;
	//make the subelement visible to compute the position
	if (els[1] && !this.hasClassName(els[1], this.MenuBarSubmenuVisible))
	{
		els[1].style.visibility = 'hidden';
		this.showSubmenu(els[1]);
		hideSubmenu = true;
	}

	var isVert = this.hasClassName(this.element, this.verticalClass);
	var hasParent = els[0].parentNode.parentNode.nodeName.toLowerCase() == 'li' ? true : false;
	
	for (var i = 1; i < els.length; i++){
		//when navigating on the y axis in vertical menus, ignore children and parents
		if(prop=='y' && isVert && (i==1 || i==2))
		{
			continue;
		}
		//when navigationg on the x axis in the FIRST LEVEL of horizontal menus, ignore children and parents
		if(prop=='x' && !isVert && !hasParent && (i==1 || i==2))
		{
			continue;
		}
			
		if (els[i])
		{
			var tmp = rect(els[i]); 
			if ( (dir * tmp[prop]) < (dir * ref[prop]))
			{
				ref = tmp;
				found = i;
			}
		}
	}
	
	// hide back the submenu
	if (els[1] && hideSubmenu){
		this.hideSubmenu(els[1]);
		els[1].style.visibility =  '';
	}

	return found;
};
Spry.Widget.MenuBar.camelize = function(str)
{
	if (str.indexOf('-') == -1){
		return str;	
	}
	var oStringList = str.split('-');
	var isFirstEntry = true;
	var camelizedString = '';

	for(var i=0; i < oStringList.length; i++)
	{
		if(oStringList[i].length>0)
		{
			if(isFirstEntry)
			{
				camelizedString = oStringList[i];
				isFirstEntry = false;
			}
			else
			{
				var s = oStringList[i];
				camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
			}
		}
	}

	return camelizedString;
};

Spry.Widget.MenuBar.getStyleProp = function(element, prop)
{
	var value;
	try
	{
		if (element.style)
			value = element.style[Spry.Widget.MenuBar.camelize(prop)];

		if (!value)
			if (document.defaultView && document.defaultView.getComputedStyle)
			{
				var css = document.defaultView.getComputedStyle(element, null);
				value = css ? css.getPropertyValue(prop) : null;
			}
			else if (element.currentStyle) 
			{
					value = element.currentStyle[Spry.Widget.MenuBar.camelize(prop)];
			}
	}
	catch (e) {}

	return value == 'auto' ? null : value;
};
Spry.Widget.MenuBar.getIntProp = function(element, prop)
{
	var a = parseInt(Spry.Widget.MenuBar.getStyleProp(element, prop),10);
	if (isNaN(a))
		return 0;
	return a;
};

Spry.Widget.MenuBar.getPosition = function(el, doc)
{
	doc = doc || document;
	if (typeof(el) == 'string') {
		el = doc.getElementById(el);
	}

	if (!el) {
		return false;
	}

	if (el.parentNode === null || Spry.Widget.MenuBar.getStyleProp(el, 'display') == 'none') {
		//element must be visible to have a box
		return false;
	}

	var ret = {x:0, y:0};
	var parent = null;
	var box;

	if (el.getBoundingClientRect) { // IE
		box = el.getBoundingClientRect();
		var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
		var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
		ret.x = box.left + scrollLeft;
		ret.y = box.top + scrollTop;
	} else if (doc.getBoxObjectFor) { // gecko
		box = doc.getBoxObjectFor(el);
		ret.x = box.x;
		ret.y = box.y;
	} else { // safari/opera
		ret.x = el.offsetLeft;
		ret.y = el.offsetTop;
		parent = el.offsetParent;
		if (parent != el) {
			while (parent) {
				ret.x += parent.offsetLeft;
				ret.y += parent.offsetTop;
				parent = parent.offsetParent;
			}
		}
		// opera & (safari absolute) incorrectly account for body offsetTop
		if (Spry.is.opera || Spry.is.safari && Spry.Widget.MenuBar.getStyleProp(el, 'position') == 'absolute')
			ret.y -= doc.body.offsetTop;
	}
	if (el.parentNode)
			parent = el.parentNode;
	else
		parent = null;
	if (parent.nodeName){
		var cas = parent.nodeName.toUpperCase();
		while (parent && cas != 'BODY' && cas != 'HTML') {
			cas = parent.nodeName.toUpperCase();
			ret.x -= parent.scrollLeft;
			ret.y -= parent.scrollTop;
			if (parent.parentNode)
				parent = parent.parentNode;
			else
				parent = null;
		}
	}
	return ret;
};

Spry.Widget.MenuBar.stopPropagation = function(ev)
{
	if (ev.stopPropagation)
		ev.stopPropagation();
	else
		ev.cancelBubble = true;
	if (ev.preventDefault) 
		ev.preventDefault();
	else 
		ev.returnValue = false;
};

Spry.Widget.MenuBar.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
	if (!optionsObj)
		return;
	for (var optionName in optionsObj)
	{
		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
			continue;
		obj[optionName] = optionsObj[optionName];
	}
};




/*
* Begin File: "js/carousel.js"
*/

/*  Prototype-UI, version trunk
 *
 *  Prototype-UI is freely distributable under the terms of an MIT-style license.
 *  For details, see the PrototypeUI web site: http://www.prototype-ui.com/
 *
 *--------------------------------------------------------------------------*/

if(typeof Prototype == 'undefined' || !Prototype.Version.match("1.6"))
  throw("Prototype-UI library require Prototype library >= 1.6.0");

if (Prototype.Browser.WebKit) {
  Prototype.Browser.WebKitVersion = parseFloat(navigator.userAgent.match(/AppleWebKit\/([\d\.\+]*)/)[1]);
  Prototype.Browser.Safari2 = (Prototype.Browser.WebKitVersion < 420);
}

if (Prototype.Browser.IE) {
  Prototype.Browser.IEVersion = parseFloat(navigator.appVersion.split(';')[1].strip().split(' ')[1]);
  Prototype.Browser.IE6 =  Prototype.Browser.IEVersion == 6;
  Prototype.Browser.IE7 =  Prototype.Browser.IEVersion == 7;
}

Prototype.falseFunction = function() { return false };
Prototype.trueFunction  = function() { return true  };

/*
Namespace: UI

  Introduction:
    Prototype-UI is a library of user interface components based on the Prototype framework.
    Its aim is to easilly improve user experience in web applications.

    It also provides utilities to help developers.

  Guideline:
    - Prototype conventions are followed
    - Everything should be unobstrusive
    - All components are themable with CSS stylesheets, various themes are provided

  Warning:
    Prototype-UI is still under deep development, this release is targeted to developers only.
    All interfaces are subjects to changes, suggestions are welcome.

    DO NOT use it in production for now.

  Authors:
    - Sébastien Gruhier, <http://www.xilinus.com>
    - Samuel Lebeau, <http://gotfresh.info>
*/

var UI = {
  Abstract: { },
  Ajax: { }
};
Object.extend(Class.Methods, {
  extend: Object.extend.methodize(),

  addMethods: Class.Methods.addMethods.wrap(function(proceed, source) {
    // ensure we are not trying to add null or undefined
    if (!source) return this;

    // no callback, vanilla way
    if (!source.hasOwnProperty('methodsAdded'))
      return proceed(source);

    var callback = source.methodsAdded;
    delete source.methodsAdded;
    proceed(source);
    callback.call(source, this);
    source.methodsAdded = callback;

    return this;
  }),

  addMethod: function(name, lambda) {
    var methods = {};
    methods[name] = lambda;
    return this.addMethods(methods);
  },

  method: function(name) {
    return this.prototype[name].valueOf();
  },

  classMethod: function() {
    $A(arguments).flatten().each(function(method) {
      this[method] = (function() {
        return this[method].apply(this, arguments);
      }).bind(this.prototype);
    }, this);
    return this;
  },

  // prevent any call to this method
  undefMethod: function(name) {
    this.prototype[name] = undefined;
    return this;
  },

  // remove the class' own implementation of this method
  removeMethod: function(name) {
    delete this.prototype[name];
    return this;
  },

  aliasMethod: function(newName, name) {
    this.prototype[newName] = this.prototype[name];
    return this;
  },

  aliasMethodChain: function(target, feature) {
    feature = feature.camelcase();

    this.aliasMethod(target+"Without"+feature, target);
    this.aliasMethod(target, target+"With"+feature);

    return this;
  }
});
Object.extend(Number.prototype, {
  // Snap a number to a grid
  snap: function(round) {
    return parseInt(round == 1 ? this : (this / round).floor() * round);
  }
});
/*
Interface: String

*/

Object.extend(String.prototype, {
  camelcase: function() {
    var string = this.dasherize().camelize();
    return string.charAt(0).toUpperCase() + string.slice(1);
  },

  /*
    Method: makeElement
      toElement is unfortunately already taken :/

      Transforms html string into an extended element or null (when failed)

      > '<li><a href="#">some text</a></li>'.makeElement(); // => LI href#
      > '<img src="foo" id="bar" /><img src="bar" id="bar" />'.makeElement(); // => IMG#foo (first one)

    Returns:
      Extended element

  */
  makeElement: function() {
    var wrapper = new Element('div'); wrapper.innerHTML = this;
    return wrapper.down();
  }
});
Object.extend(Array.prototype, {
  empty: function() {
    return !this.length;
  },

  extractOptions: function() {
    return this.last().constructor === Object ? this.pop() : { };
  },

  removeAt: function(index) {
    var object = this[index];
    this.splice(index, 1);
    return object;
  },

  remove: function(object) {
    var index;
    while ((index = this.indexOf(object)) != -1)
      this.removeAt(index);
    return object;
  },

  insert: function(index) {
    var args = $A(arguments);
    args.shift();
    this.splice.apply(this, [ index, 0 ].concat(args));
    return this;
  }
});
Element.addMethods({
  getScrollDimensions: function(element) {
    return {
      width:  element.scrollWidth,
      height: element.scrollHeight
    }
  },

  getScrollOffset: function(element) {
    return Element._returnOffset(element.scrollLeft, element.scrollTop);
  },

  setScrollOffset: function(element, offset) {
    element = $(element);
    if (arguments.length == 3)
      offset = { left: offset, top: arguments[2] };
    element.scrollLeft = offset.left;
    element.scrollTop  = offset.top;
    return element;
  },

  // returns "clean" numerical style (without "px") or null if style can not be resolved
  // or is not numeric
  getNumStyle: function(element, style) {
    var value = parseFloat($(element).getStyle(style));
    return isNaN(value) ? null : value;
  },

  // by Tobie Langel (http://tobielangel.com/2007/5/22/prototype-quick-tip)
  appendText: function(element, text) {
    element = $(element);
    text = String.interpret(text);
    element.appendChild(document.createTextNode(text));
    return element;
  }
});

document.whenReady = function(callback) {
  if (document.loaded)
    callback.call(document);
  else
    document.observe('dom:loaded', callback);
};

Object.extend(document.viewport, {
  // Alias this method for consistency
  getScrollOffset: document.viewport.getScrollOffsets,

  setScrollOffset: function(offset) {
    Element.setScrollOffset(Prototype.Browser.WebKit ? document.body : document.documentElement, offset);
  },

  getScrollDimensions: function() {
    return Element.getScrollDimensions(Prototype.Browser.WebKit ? document.body : document.documentElement);
  }
});
/*
Interface: UI.Options
  Mixin to handle *options* argument in initializer pattern.

  TODO: find a better example than Circle that use an imaginary Point function,
        this example should be used in tests too.

  It assumes class defines a property called *options*, containing
  default options values.

  Instances hold their own *options* property after a first call to <setOptions>.

  Example:
    > var Circle = Class.create(UI.Options, {
    >
    >   // default options
    >   options: {
    >     radius: 1,
    >     origin: Point(0, 0)
    >   },
    >
    >   // common usage is to call setOptions in initializer
    >   initialize: function(options) {
    >     this.setOptions(options);
    >   }
    > });
    >
    > var circle = new Circle({ origin: Point(1, 4) });
    >
    > circle.options
    > // => { radius: 1, origin: Point(1,4) }

  Accessors:
    There are builtin methods to automatically write options accessors. All those
    methods can take either an array of option names nor option names as arguments.
    Notice that those methods won't override an accessor method if already present.

     * <optionsGetter> creates getters
     * <optionsSetter> creates setters
     * <optionsAccessor> creates both getters and setters

    Common usage is to invoke them on a class to create accessors for all instances
    of this class.
    Invoking those methods on a class has the same effect as invoking them on the class prototype.
    See <classMethod> for more details.

    Example:
    > // Creates getter and setter for the "radius" options of circles
    > Circle.optionsAccessor('radius');
    >
    > circle.setRadius(4);
    > // 4
    >
    > circle.getRadius();
    > // => 4 (circle.options.radius)

  Inheritance support:
    Subclasses can refine default *options* values, after a first instance call on setOptions,
    *options* attribute will hold all default options values coming from the inheritance hierarchy.
*/

(function() {
  UI.Options = {
    methodsAdded: function(klass) {
      klass.classMethod($w(' setOptions allOptions optionsGetter optionsSetter optionsAccessor '));
    },

    // Group: Methods

    /*
      Method: setOptions
        Extends object's *options* property with the given object
    */
    setOptions: function(options) {
      if (!this.hasOwnProperty('options'))
        this.options = this.allOptions();

      this.options = Object.extend(this.options, options || {});
    },

    /*
      Method: allOptions
        Computes the complete default options hash made by reverse extending all superclasses
        default options.

        > Widget.prototype.allOptions();
    */
    allOptions: function() {
      var superclass = this.constructor.superclass, ancestor = superclass && superclass.prototype;
      return (ancestor && ancestor.allOptions) ?
          Object.extend(ancestor.allOptions(), this.options) :
          Object.clone(this.options);
    },

    /*
      Method: optionsGetter
        Creates default getters for option names given as arguments.
        With no argument, creates getters for all option names.
    */
    optionsGetter: function() {
      addOptionsAccessors(this, arguments, false);
    },

    /*
      Method: optionsSetter
        Creates default setters for option names given as arguments.
        With no argument, creates setters for all option names.
    */
    optionsSetter: function() {
      addOptionsAccessors(this, arguments, true);
    },

    /*
      Method: optionsAccessor
        Creates default getters/setters for option names given as arguments.
        With no argument, creates accessors for all option names.
    */
    optionsAccessor: function() {
      this.optionsGetter.apply(this, arguments);
      this.optionsSetter.apply(this, arguments);
    }
  };

  // Internal
  function addOptionsAccessors(receiver, names, areSetters) {
    names = $A(names).flatten();

    if (names.empty())
      names = Object.keys(receiver.allOptions());

    names.each(function(name) {
      var accessorName = (areSetters ? 'set' : 'get') + name.camelcase();

      receiver[accessorName] = receiver[accessorName] || (areSetters ?
        // Setter
        function(value) { return this.options[name] = value } :
        // Getter
        function()      { return this.options[name]         });
    });
  }
})();
/*
  Class: UI.Carousel

  Main class to handle a carousel of elements in a page. A carousel :
    * could be vertical or horizontal
    * works with liquid layout
    * is designed by CSS

  Assumptions:
    * Elements should be from the same size

  Example:
    > ...
    > <div id="horizontal_carousel">
    >   <div class="previous_button"></div>
    >   <div class="container">
    >     <ul>
    >       <li> What ever you like</li>
    >     </ul>
    >   </div>
    >   <div class="next_button"></div>
    > </div>
    > <script>
    > new UI.Carousel("horizontal_carousel");
    > </script>
    > ...
*/
UI.Carousel = Class.create(UI.Options, {
  // Group: Options
  options: {
	// Property: direction
	//   Can be horizontal or vertical, horizontal by default
    direction               : "horizontal",

    // Property: previousButton
    //   Selector of previous button inside carousel element, ".previous_button" by default,
    //   set it to false to ignore previous button
    previousButton          : ".previous_button",

    // Property: nextButton
    //   Selector of next button inside carousel element, ".next_button" by default,
    //   set it to false to ignore next button
    nextButton              : ".next_button",

    // Property: container
    //   Selector of carousel container inside carousel element, ".container" by default,
    container               : ".container",

    // Property: scrollInc
    //   Define the maximum number of elements that gonna scroll each time, auto by default
    scrollInc               : "auto",

    // Property: disabledButtonSuffix
    //   Define the suffix classanme used when a button get disabled, to '_disabled' by default
    //   Previous button classname will be previous_button_disabled
    disabledButtonSuffix : '_disabled',

    // Property: overButtonSuffix
    //   Define the suffix classanme used when a button has a rollover status, '_over' by default
    //   Previous button classname will be previous_button_over
    overButtonSuffix : '_over'
  },

  /*
    Group: Attributes

      Property: element
        DOM element containing the carousel

      Property: id
        DOM id of the carousel's element

      Property: container
        DOM element containing the carousel's elements

      Property: elements
        Array containing the carousel's elements as DOM elements

      Property: previousButton
        DOM id of the previous button

      Property: nextButton
        DOM id of the next button

      Property: posAttribute
        Define if the positions are from left or top

      Property: dimAttribute
        Define if the dimensions are horizontal or vertical

      Property: elementSize
        Size of each element, it's an integer

      Property: nbVisible
        Number of visible elements, it's a float

      Property: animating
        Define whether the carousel is in animation or not
  */

  /*
    Group: Events
      List of events fired by a carousel

      Notice: Carousel custom events are automatically namespaced in "carousel:" (see Prototype custom events).

      Examples:
        This example will observe all carousels
        > document.observe('carousel:scroll:ended', function(event) {
        >   alert("Carousel with id " + event.memo.carousel.id + " has just been scrolled");
        > });

        This example will observe only this carousel
        > new UI.Carousel('horizontal_carousel').observe('scroll:ended', function(event) {
        >   alert("Carousel with id " + event.memo.carousel.id + " has just been scrolled");
        > });

      Property: previousButton:enabled
        Fired when the previous button has just been enabled

      Property: previousButton:disabled
        Fired when the previous button has just been disabled

      Property: nextButton:enabled
        Fired when the next button has just been enabled

      Property: nextButton:disabled
        Fired when the next button has just been disabled

      Property: scroll:started
        Fired when a scroll has just started

      Property: scroll:ended
        Fired when a scroll has been done,
        memo.shift = number of elements scrolled, it's a float

      Property: sizeUpdated
        Fired when the carousel size has just been updated.
        Tips: memo.carousel.currentSize() = the new carousel size
  */

  // Group: Constructor

  /*
    Method: initialize
      Constructor function, should not be called directly

    Parameters:
      element - DOM element
      options - (Hash) list of optional parameters

    Returns:
      this
  */
  initialize: function(element, options) {
    this.setOptions(options);
    this.element = $(element);
    this.id = this.element.id;
    this.container   = this.element.down(this.options.container).firstDescendant();
    this.elements    = this.container.childElements();
    this.previousButton = this.options.previousButton == false ? null : this.element.down(this.options.previousButton);
    this.nextButton = this.options.nextButton == false ? null : this.element.down(this.options.nextButton);

    this.posAttribute = (this.options.direction == "horizontal" ? "left" : "top");
    this.dimAttribute = (this.options.direction == "horizontal" ? "width" : "height");

    this.elementSize = this.computeElementSize();
    this.nbVisible = this.currentSize() / this.elementSize;

    var scrollInc = this.options.scrollInc;
    if (scrollInc == "auto")
      scrollInc = Math.floor(this.nbVisible);
    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
      var className = (button == this.nextButton ? "next_button" : "previous_button") + this.options.overButtonSuffix;
      button.clickHandler = this.scroll.bind(this, (button == this.nextButton ? -1 : 1) * scrollInc * this.elementSize);
      button.observe("click", button.clickHandler)
            .observe("mouseover", function() {button.addClassName(className)}.bind(this))
            .observe("mouseout",  function() {button.removeClassName(className)}.bind(this));
    }, this);
    this.updateButtons();
  },

  // Group: Destructor

  /*
    Method: destroy
      Cleans up DOM and memory
  */
  destroy: function($super) {
    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
        button.stopObserving("click", button.clickHandler);
    }, this);
	  this.element.remove();
	  this.fire('destroyed');
  },

  // Group: Event handling

  /*
    Method: fire
      Fires a carousel custom event automatically namespaced in "carousel:" (see Prototype custom events).
      The memo object contains a "carousel" property referring to the carousel.

    Example:
      > document.observe('carousel:scroll:ended', function(event) {
      >   alert("Carousel with id " + event.memo.carousel.id + " has just been scrolled");
      > });

    Parameters:
      eventName - an event name
      memo      - a memo object

    Returns:
      fired event
  */
  fire: function(eventName, memo) {
    memo = memo || { };
    memo.carousel = this;
    return this.element.fire('carousel:' + eventName, memo);
  },

  /*
    Method: observe
      Observe a carousel event with a handler function automatically bound to the carousel

    Parameters:
      eventName - an event name
      handler   - a handler function

    Returns:
      this
  */
  observe: function(eventName, handler) {
    this.element.observe('carousel:' + eventName, handler.bind(this));
    return this;
  },

  /*
    Method: stopObserving
      Unregisters a carousel event, it must take the same parameters as this.observe (see Prototype stopObserving).

    Parameters:
      eventName - an event name
      handler   - a handler function

    Returns:
      this
  */
  stopObserving: function(eventName, handler) {
	  this.element.stopObserving('carousel:' + eventName, handler);
	  return this;
  },

  // Group: Actions

  /*
    Method: checkScroll
      Check scroll position to avoid unused space at right or bottom

    Parameters:
      position       - position to check
      updatePosition - should the container position be updated ? true/false

    Returns:
      position
  */
  checkScroll: function(position, updatePosition) {
    if (position > 0)
      position = 0;
    else {
      var limit = this.elements.last().positionedOffset()[this.posAttribute] + this.elementSize;
      var carouselSize = this.currentSize();

      if (position + limit < carouselSize)
        position += carouselSize - (position + limit);
      position = Math.min(position, 0);
    }
    if (updatePosition)
      this.container.style[this.posAttribute] = position + "px";

    return position;
  },

  /*
    Method: scroll
      Scrolls carousel from maximum deltaPixel

    Parameters:
      deltaPixel - a float

    Returns:
      this
  */
  scroll: function(deltaPixel) {
    if (this.animating)
      return this;

    // Compute new position
    var position =  this.currentPosition() + deltaPixel;

    // Check bounds
    position = this.checkScroll(position, false);

    // Compute shift to apply
    deltaPixel = position - this.currentPosition();
    if (deltaPixel != 0) {
      this.animating = true;
      this.fire("scroll:started");

      var that = this;
      // Move effects
      this.container.morph("opacity:0.5", {duration: 0.2, afterFinish: function() {
        that.container.morph(that.posAttribute + ": " + position + "px", {
          duration: 0.4,
          delay: 0.2,
          afterFinish: function() {
            that.container.morph("opacity:1", {
              duration: 0.2,
              afterFinish: function() {
                that.animating = false;
                that.updateButtons()
                  .fire("scroll:ended", { shift: deltaPixel / that.currentSize() });
              }
            });
          }
        });
      }});
    }
    return this;
  },

  /*
    Method: scrollTo
      Scrolls carousel, so that element with specified index is the left-most.
      This method is convenient when using carousel in a tabbed navigation.
      Clicking on first tab should scroll first container into view, clicking on a fifth - fifth one, etc.
      Indexing starts with 0.

    Parameters:
      Index of an element which will be a left-most visible in the carousel

    Returns:
      this
  */
  scrollTo: function(index) {
    if (this.animating || index < 0 || index > this.elements.length || index == this.currentIndex() || isNaN(parseInt(index)))
      return this;
    return this.scroll((this.currentIndex() - index) * this.elementSize);
  },

  /*
    Method: updateButtons
      Update buttons status to enabled or disabled
      Them status is defined by classNames and fired as carousel's custom events

    Returns:
      this
  */
  updateButtons: function() {
	  this.updatePreviousButton();
    this.updateNextButton();
    return this;
  },

  updatePreviousButton: function() {
    var position = this.currentPosition();
    var previousClassName = "previous_button" + this.options.disabledButtonSuffix;

    if (this.previousButton.hasClassName(previousClassName) && position != 0) {
      this.previousButton.removeClassName(previousClassName);
      this.fire('previousButton:enabled');
    }
    if (!this.previousButton.hasClassName(previousClassName) && position == 0) {
	    this.previousButton.addClassName(previousClassName);
      this.fire('previousButton:disabled');
    }
  },

  updateNextButton: function() {
    var lastPosition = this.currentLastPosition();
    var size = this.currentSize();
    var nextClassName = "next_button" + this.options.disabledButtonSuffix;

    if (this.nextButton.hasClassName(nextClassName) && lastPosition != size) {
      this.nextButton.removeClassName(nextClassName);
      this.fire('nextButton:enabled');
    }
    if (!this.nextButton.hasClassName(nextClassName) && lastPosition == size) {
	    this.nextButton.addClassName(nextClassName);
      this.fire('nextButton:disabled');
    }
  },

  // Group: Size and Position

  /*
    Method: computeElementSize
      Return elements size in pixel, height or width depends on carousel orientation.

    Returns:
      an integer value
  */
  computeElementSize: function() {
    return this.elements.first().getDimensions()[this.dimAttribute];
  },

  /*
    Method: currentIndex
      Returns current visible index of a carousel.
      For example, a horizontal carousel with image #3 on left will return 3 and with half of image #3 will return 3.5
      Don't forget that the first image have an index 0

    Returns:
      a float value
  */
  currentIndex: function() {
    return - this.currentPosition() / this.elementSize;
  },

  /*
    Method: currentLastPosition
      Returns the current position from the end of the last element. This value is in pixel.

    Returns:
      an integer value, if no images a present it will return 0
  */
  currentLastPosition: function() {
    if (this.container.childElements().empty())
      return 0;
    return this.currentPosition() +
           this.elements.last().positionedOffset()[this.posAttribute] +
           this.elementSize;
  },

  /*
    Method: currentPosition
      Returns the current position in pixel.
      Tips: To get the position in elements use currentIndex()

    Returns:
      an integer value
  */
  currentPosition: function() {
    return this.container.getNumStyle(this.posAttribute);
  },

  /*
    Method: currentSize
      Returns the current size of the carousel in pixel

    Returns:
      Carousel's size in pixel
  */
  currentSize: function() {
    return this.container.parentNode.getDimensions()[this.dimAttribute];
  },

  /*
    Method: updateSize
      Should be called if carousel size has been changed (usually called with a liquid layout)

    Returns:
      this
  */
  updateSize: function() {
    this.nbVisible = this.currentSize() / this.elementSize;
    var scrollInc = this.options.scrollInc;
    if (scrollInc == "auto")
      scrollInc = Math.floor(this.nbVisible);

    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
      button.stopObserving("click", button.clickHandler);
      button.clickHandler = this.scroll.bind(this, (button == this.nextButton ? -1 : 1) * scrollInc * this.elementSize);
      button.observe("click", button.clickHandler);
    }, this);

    this.checkScroll(this.currentPosition(), true);
    this.updateButtons().fire('sizeUpdated');
    return this;
  }
});
/*
  Class: UI.Ajax.Carousel

  Gives the AJAX power to carousels. An AJAX carousel :
    * Use AJAX to add new elements on the fly

  Example:
    > new UI.Ajax.Carousel("horizontal_carousel",
    >   {url: "get-more-elements", elementSize: 250});
*/
UI.Ajax.Carousel = Class.create(UI.Carousel, {
  // Group: Options
  //
  //   Notice:
  //     It also include of all carousel's options
  options: {
	// Property: elementSize
	//   Required, it define the size of all elements
    elementSize : -1,

	// Property: url
	//   Required, it define the URL used by AJAX carousel to request new elements details
    url         : null
  },

  /*
    Group: Attributes

      Notice:
        It also include of all carousel's attributes

      Property: elementSize
        Size of each elements, it's an integer

      Property: endIndex
        Index of the last loaded element

      Property: hasMore
        Flag to define if there's still more elements to load

      Property: requestRunning
        Define whether a request is processing or not

      Property: updateHandler
        Callback to update carousel, usually used after request success

      Property: url
        URL used to request additional elements
  */

  /*
    Group: Events
      List of events fired by an AJAX carousel, it also include of all carousel's custom events

      Property: request:started
        Fired when the request has just started

      Property: request:ended
        Fired when the request has succeed
  */

  // Group: Constructor

  /*
    Method: initialize
      Constructor function, should not be called directly

    Parameters:
      element - DOM element
      options - (Hash) list of optional parameters

    Returns:
      this
  */
  initialize: function($super, element, options) {
    if (!options.url)
      throw("url option is required for UI.Ajax.Carousel");
    if (!options.elementSize)
      throw("elementSize option is required for UI.Ajax.Carousel");

    $super(element, options);

    this.endIndex = 0;
    this.hasMore  = true;

    // Cache handlers
    this.updateHandler = this.update.bind(this);
    this.updateAndScrollHandler = function(nbElements, transport, json) {
	    this.update(transport, json);
	    this.scroll(nbElements);
	  }.bind(this);

    // Run first ajax request to fill the carousel
    this.runRequest.bind(this).defer({parameters: {from: 0, to: Math.ceil(this.nbVisible) - 1}, onSuccess: this.updateHandler});
  },

  // Group: Actions

  /*
    Method: runRequest
      Request the new elements details

    Parameters:
      options - (Hash) list of optional parameters

    Returns:
      this
  */
  runRequest: function(options) {
    this.requestRunning = true;
    new Ajax.Request(this.options.url, Object.extend({method: "GET"}, options));
    this.fire("request:started");
    return this;
  },

  /*
    Method: scroll
      Scrolls carousel from maximum deltaPixel

    Parameters:
      deltaPixel - a float

    Returns:
      this
  */
  scroll: function($super, deltaPixel) {
    if (this.animating || this.requestRunning)
      return this;

    var nbElements = (-deltaPixel) / this.elementSize;
    // Check if there is not enough
    if (this.hasMore && nbElements > 0 && this.currentIndex() + this.nbVisible + nbElements - 1 > this.endIndex) {
      var from = this.endIndex + 1;
      var to   = Math.ceil(from + this.nbVisible - 1);
      this.runRequest({parameters: {from: from, to: to}, onSuccess: this.updateAndScrollHandler.curry(deltaPixel).bind(this)});
      return this;
    }
    else
      $super(deltaPixel);
  },

  /*
    Method: update
      Update the carousel

    Parameters:
      transport - XMLHttpRequest object
      json      - JSON object

    Returns:
      this
  */
  update: function(transport, json) {
    this.requestRunning = false;
    this.fire("request:ended");
    if (!json)
      json = transport.responseJSON;
    this.hasMore = json.more;

    this.endIndex = Math.max(this.endIndex, json.to);
    this.elements = this.container.insert({bottom: json.html}).childElements();
    return this.updateButtons();
  },

  // Group: Size and Position

  /*
    Method: computeElementSize
      Return elements size in pixel

    Returns:
      an integer value
  */
  computeElementSize: function() {
    return this.options.elementSize;
  },

  /*
    Method: updateSize
      Should be called if carousel size has been changed (usually called with a liquid layout)

    Returns:
      this
  */
  updateSize: function($super) {
    var nbVisible = this.nbVisible;
    $super();
    // If we have enough space for at least a new element
    if (Math.floor(this.nbVisible) - Math.floor(nbVisible) >= 1 && this.hasMore) {
      if (this.currentIndex() + Math.floor(this.nbVisible) >= this.endIndex) {
        var nbNew = Math.floor(this.currentIndex() + Math.floor(this.nbVisible) - this.endIndex);
        this.runRequest({parameters: {from: this.endIndex + 1, to: this.endIndex + nbNew}, onSuccess: this.updateHandler});
      }
    }
    return this;
  },

  updateNextButton: function($super) {
    var lastPosition = this.currentLastPosition();
    var size = this.currentSize();
    var nextClassName = "next_button" + this.options.disabledButtonSuffix;

    if (this.nextButton.hasClassName(nextClassName) && lastPosition != size) {
      this.nextButton.removeClassName(nextClassName);
      this.fire('nextButton:enabled');
    }
    if (!this.nextButton.hasClassName(nextClassName) && lastPosition == size && !this.hasMore) {
	    this.nextButton.addClassName(nextClassName);
      this.fire('nextButton:disabled');
    }
  }
});




/*
* Begin File: "js/mail_to_friend.js"
*/

// JavaScript Document

/**
 * Mail To A Friend 
 *    
 *  add this function to a mailto: <a href and it will pop a javascript box to help the user send to a friend, 
 *   E.G. <a href="mailto:example@email.co.uk?subject=abc&body=aaaaa" onclick="mailToFriend(this); return false;">
 * 	        Email To Friend 
 * 		  </a>
 */
var a_obj, emailAddy, subjectPos, subject, emailbodyPos, emailbody;
function mailToFriend(a_obj) {
	
	// if mailto: ...
	if(a_obj.href.match('mailto')) {
		emailAddy = unescape(a_obj.href.replace('mailto:', ''));
		emailAddy = emailAddy.replace('?', '&');
		
		// if mailto contains 'subject' before body (if body at all)
		if(emailAddy.match('&subject=')) {
			
			subjectPos = emailAddy.indexOf('&subject=');
			subject = emailAddy.substring(subjectPos).replace('&subject=', '');
			
			emailAddy = emailAddy.replace( emailAddy.substring(subjectPos), '');
			
			// if mailto conatins 'body' 
			if(subject.match('&body=')) {
				
				emailbodyPos = subject.indexOf('&body=');
				emailbody = subject.substring(emailbodyPos).replace('&body=', '');
				
				subject = subject.replace( subject.substring(emailbodyPos), '');
			}
		}
			
		// if mailto conatins 'body' before subject (if subject at all)	
		if(emailAddy.match('&body=')) {
			
			emailbodyPos = emailAddy.indexOf('&body=');
			emailbody = emailAddy.substring(emailbodyPos).replace('&body=', '');
			
			emailAddy = emailAddy.replace( emailAddy.substring(emailbodyPos), '');
			
			// if body conatins 'subject' 
			if(emailbody.match('&subject=')) {
				
				subjectPos = emailbody.indexOf('&subject=');
				subject = emailbody.substring(subjectPos).replace('&subject=', '');
				
				emailbody = emailbody.replace( emailbody.substring(emailbodyPos), '');
			}
		}		
		
		//alert( emailAddy );
		//alert( subject );
		//alert( emailbody );
		
		// pop box 
		popSendToFriend(emailAddy, subject, emailbody, a_obj)
			
	}
	else {
		alert('Failed to send email');
	}
}

// ** URL encode function ** 
function urlencode(str) {
	return escape(str).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
}

// ** URL decode function ** 
function urldecode(str) {
	return unescape(str.replace(/\+/g, ' ')); 
}

/**
 * Pop javascript send to friend box! 
 */
var makeEmailInputEditable, makeSubjectInputEditable, makeBodyInputEditable, mainEmailOverallTitle, addInExtraFieldName, sendOnToThanksPage, sendOnToThanksPageText;
function popSendToFriend(emailAddy, subject, emailbody, a_obj, makeEmailInputEditable, makeSubjectInputEditable, makeBodyInputEditable, mainEmailOverallTitle, addInExtraFieldName, sendOnToThanksPage) {
	
	subject = urldecode(subject);
	
	if(a_obj==undefined) a_obj = '';
	
		// If IE 6, and hide all drop down menus on-open (they showed over the top of the modal), re-show them on close
		if(isRunningIE6OrBelow) {
			$$('select').each(function(el) {
				  el.style.display = "none";
			});
		}
	
	if(mainEmailOverallTitle==undefined) mainEmailOverallTitle = 'Send To A Friend.';
	if(mainEmailOverallTitle=='') mainEmailOverallTitle = 'Send To A Friend.';
	
	if(makeEmailInputEditable==undefined) makeEmailInputEditable = true;
	if(makeSubjectInputEditable==undefined) makeSubjectInputEditable = true;
	if(makeBodyInputEditable==undefined) makeBodyInputEditable = true;
	
	 var oDiv = document.createElement('div');
	 
	 var randomnumber = Math.floor(Math.random()*11);
	 
	 var oinner_part_content = '';
	 
	 // Added Optional Extra Part
	 if(addInExtraFieldName!=undefined) {
		 oinner_part_content += ' <span> <strong>' + addInExtraFieldName + ':</strong> \
		 	<input type="text" name="email_extra_part" id="email_extra_part" value="" /> \
			<input type="hidden" name="email_extra_part" id="email_extra_part_name" value="' + addInExtraFieldName + '" /> \
			</span> <br /> ';
	 }
	 
	 if(sendOnToThanksPage) sendOnToThanksPageText = "true";
	 else sendOnToThanksPageText = "false";
	 
	// Email To (show as text or editable)
	 if(!makeEmailInputEditable) {
		 oinner_part_content += ' <span> <strong>Send to:</strong> ' + emailAddy + ' </span> <br /> \
		 	<input type="hidden" name="email_input_part" id="email_input_part" value="' + emailAddy + '" />';
	 }
	 else {
		 oinner_part_content += ' <span> <strong>Send to:</strong> \
		 	<input type="text" name="email_input_part" id="email_input_part" value="' + emailAddy + '" /> \
			</span> <br /> ';
	 }
	 
	// Email Subject (show as text or editable)
	 if(!makeSubjectInputEditable) {
		 oinner_part_content += ' <span> <strong>Subject:</strong> ' + subject + ' </span> <br /> \
		 	<input type="hidden" name="subject_input_part" id="subject_input_part" value="' + subject + '" />';
	 }
	 else {
		 oinner_part_content += ' <span> <strong>Subject:</strong> \
		 	<input type="text" name="subject_input_part" id="subject_input_part" value="' + subject + '" /> \
			</span> <br /> ';
	 }
	
	// Email Body (show as text or editable)
	 if(!makeBodyInputEditable) {
		 oinner_part_content += ' <span> <strong>Body:</strong> ' + emailbody + ' </span> <br /> \
		 	<input type="hidden" name="body_input_part" id="body_input_part" value="' + subject + '" />';
	 }
	 else {
		 oinner_part_content += ' <span> <strong>Body:</strong> \
		 	<textarea name="body_input_part" id="body_input_part">' + emailbody + '</textarea> \
			</span> <br /> ';
	 }
	 
	 oDiv.id = 'email_popup_box_' + randomnumber;
	 
	 var addedLineAboutMultiSend = '';
	 if(makeEmailInputEditable) {
		 addedLineAboutMultiSend = '<p> <em> You can send to multiple emails by seperating each one with a semi-colon followed by a space E.g."email@address.com; another@email.com" </em> </p>';
	 }
	 
	 oDiv.innerHTML = "<div id='email_popup_box_back'> &nbsp; </div>";
	 oDiv.innerHTML += '<div id=\'email_popup_box_main_pos\'> \
	 						 <div id=\'email_popup_box_main\'> \
							 <form onsubmit="void(0); return false;"> \
							 <span class="email_close_button" onclick="popSendToFriendClose(\'' + oDiv.id + '\');"> <img src=\"images/glossy_icons/cancel.png\" width=\"20\" height=\"20\" alt=\"Close\" /> </span>\
							 \
							 <h3> ' + mainEmailOverallTitle + ' </h3>\
							 \
							 '+ addedLineAboutMultiSend +' \
							 \
							 <span> <strong>From:</strong> \
		 	<input type="text" name="email_input_from" id="email_input_from" value="YOUR EMAIL" /> \
			</span> <br /> ' + oinner_part_content + ' <input type="submit" value="Send" onclick="sendTheToFriendemail(\'' + oDiv.id + '\', ' + sendOnToThanksPageText + '); return false;" /> \
	 		</form> </div> </div> ';
	 
	 //if(a_obj == '') document.body.appendChild(oDiv);
	 //else insertAfter( oDiv, a_obj );
	 
	 document.body.appendChild(oDiv);
	 
	 setTimeout(function() {
	 	
		new Effect.Opacity('email_popup_box_back', { from: 0, to: 0.7, duration: 0.5, queue: 'end' });
	
		 setTimeout(function() {
			new Effect.Opacity('email_popup_box_main_pos', { from: 0, to: 1.1, duration: 0.5 });
			new Effect.SlideDown('email_popup_box_main_pos', { duration: 0.5 });	
		 }, 1000);
	 }, 200);
}

/**
 * Close pop-up send to friend box 
 */
function sendTheToFriendemail(sendBoxId, sendOnToThanksPage) {
	
	var sendEmailUrl = "pages/send_to_friend.php"; 
	var email_input_part = $('email_input_part').value; 
	var subject_input_part = $('subject_input_part').value; 
	var body_input_part = $('body_input_part').value; 
	var email_input_from = $('email_input_from').value; 
	var email_extra_part = ($('email_extra_part')) ? $('email_extra_part_name').value : ''; 
	var email_extra_part_name = ($('email_extra_part_name')) ? $('email_extra_part_name').value : ''; 
	
	new Ajax.Request(sendEmailUrl, {
		method:'POST',
		parameters: { 
			email_part: email_input_part, 
			subject_part: subject_input_part, 
			body_part: body_input_part,
			email_from: email_input_from,
			email_extra_part: email_extra_part,
			email_extra_part_name: email_extra_part_name
		}, 
		onSuccess: function(transport){
		  var response = transport.responseText || "no response text";
		  alert(response);
		  
		  if(sendOnToThanksPage) window.location = "thanks.php";
		},
		onFailure: function(){ alert('Sorry, but there was an error with your request? Please try again.') }
    });
	
	// close Box 
	popSendToFriendClose(sendBoxId); 
}

//** DOM SHORTCUT FUNCTION **
function insertAfter(newChild, refChild) { 
 	refChild.parentNode.insertBefore(newChild, refChild.nextSibling); 
} 

/**
 * Close pop-up send to friend box 
 */
var sendBoxId;
function popSendToFriendClose(sendBoxId) {
	 	
	$('email_popup_box_back').fade();
	$('email_popup_box_main_pos').fade();
	 
	 setTimeout(function() {
		document.body.removeChild( document.getElementById(sendBoxId) ); 
		// If IE 6, re-open the closed select 
		if(isRunningIE6OrBelow) {
			$$('select').each(function(el) {
				  el.style.display = "inline";
			});
		}
	 }, 600);
	
}



/*
* Begin File: "js/modal.class.js"
*/

/** 
 * Modal Window Class
 *	All modal functions should be controlled by this class 
 */
// Start With The Base ModalWindow Class 
var ModalWindow = Class.create({
	
	// On init of class, run the following 
	initialize: function(settingsObj) {
		
		this.title 		= ""; 
		this.content 	= ""; 
		
		// A constant status keeping track of the modal window
		this.status 	= "begin";
		
		this.outer_id 				= "obj_modal_outer";
		this.background_id			= "obj_modal_background";
		this.content_position_id	= "obj_modal_content_positioning";
		
		if(settingsObj.title) 	 	this.title 		= settingsObj.title;
		if(settingsObj.content)  	this.content 	= settingsObj.content;
		if(settingsObj.closeAfter)	this.closeAfter	= settingsObj.closeAfter;
		
		// position
		if(settingsObj.position)	this.position	= settingsObj.position;
		
		//** IE 6 specific 
		// requires you to have set this var previously to true or false/undefined 
		if(isRunningIE6OrBelow) {
			this.position	= "absolute"; // must always be absulute posistion 
		}
		
		if(this.content!='') {
			this.open();
		}
		
		if(settingsObj.scrollTo) Effect.ScrollTo(this.content_position_id);
		
		if(this.closeAfter) {
			
			setTimeout(this.close.bind(this), this.closeAfter);
		}
		
	},
	
	// Open the modal window 
	open: function(modal_content) {
		
	   // first make sure the modal window is not already open
	   if(!this.isOpen()) {
		
		if(modal_content==undefined) modal_content = this.content;
	
		var backDiv = document.createElement('div'); 
		backDiv.id = this.outer_id;
		
		backDiv.innerHTML  = "<div id='"+ this.background_id +"'> &nbsp; </div>";
		backDiv.innerHTML += "<div id='"+ this.content_position_id +"'> "+ modal_content +" </div>";
		
		document.body.appendChild(backDiv);
		
		// set positioning of modal inner part (content_position_id) 
		if(this.position) $(this.content_position_id).style.position = this.position; 
		
		//setTimeout(function() {
		
			//alert(this.background_id);
			new Effect.Opacity(this.background_id, { from: 0, to: 0.8, duration: 0.5, queue: 'end' });
		
			//setTimeout(function() {
				new Effect.Opacity(this.content_position_id, { from: 0, to: 1.1, duration: 0.5 });
				new Effect.SlideDown(this.content_position_id, { duration: 0.5 });	
			//}, 1000);
		//}, 200); 
		
		// set the status to be open 
		this.status = "open";
		
		// if there is a title for this modal then set the browsers page title to be this title (remember to save the old title for later)
		if((this.title!='') && document.title) { 
			this.sites_old_title = document.title;
			document.title = this.title;
		}
		
		// If IE 6, and hide all drop down menus on-open (they showed over the top of the modal), re-show them on close
		if(isRunningIE6OrBelow) {
			$$('select').each(function(el) {
				  el.style.display = "none";
			});
		}
		
	   }
		
	},
	
	// Close the modal window 
	close: function() { 
		
	   // first make sure the modal window has not already been closed 
	   if(this.isOpen()) {
	 	
		$(this.background_id).fade();
		
		new Effect.SlideUp(this.content_position_id, { duration: 0.8 });	
		$(this.content_position_id).fade();
		 
		setTimeout(this.removeOuterElement.bind(this), 600);
		
		// set the status to be closed 
		this.status = "closed";
		
		// if there is a title set for this modal than it will have changed the browser title on open, so now we need to change it back
		if((this.title!='') && document.title) document.title = this.sites_old_title;
		
	   }
		
		setTimeout(function() { 
			// If IE 6, re-open the closed select 
			if(isRunningIE6OrBelow) {
				$$('select').each(function(el) {
					  el.style.display = "inline";
				});
			}
		}, 600);
		
	},
	
	// Remove the outer div of the modal (its container) 
	removeOuterElement: function() {
		document.body.removeChild(document.getElementById(this.outer_id)); 
	},
	
	// Test the modal to check if its currently open or not, returns true or false, 
	isOpen: function() {
		if(this.status=='open') return true;
		else return false;
	}
	
	/**
	 * Additional methods to add later 
	 *  - ajax load content (with optional object loaded fetaures (such as loading icon, and more)
	 *  - auto close button generation? might have to look into other ways of closing the modal? 
	 *  - sub classes for cart, send to friend and more 
	 *  - log that can be turned on and off either using firebug or an element to print to ? fot help with testing
	 *  - load counter?
	 *  - styling, such as positioning type for content? fixed or absolute?
	 *  - in built title placement? or maybe title is used on a sub class using a prebuilt layout? 
	 *  - 
	 *  - 
	 */

	
// End Class 
});



/*
* Begin File: "js/common.js"
*/

// Common Js functions 

// if ie6 this will become true, otherwise it will remain undefined/false
var isRunningIE6OrBelow; 

function help_appear(popup)
{
	var object = $(popup);
	new Effect.Appear(object, { duration: 1.0, from: 0.0, to: 1.0 });
}
function hide_help (popup)
{
	var object = $(popup);
	new Effect.Fade(object, { duration: 1.0 });
}

// refresh_cart_content() - Refresh Cart Summary
function refresh_cart_content() {

	if($('refresh_cart_ajax_box')) { // if the side bar app for the cart content is showing on this page, then...
	
		new Ajax.Updater('refresh_cart_ajax_box', 'apps/sidebar_apps/cart_summar_refreshy.inc.php', { method: 'get' });
	 }
}


var myfunc;

/* Function that allows you to add onload events with ease 
 */
function addNewOnload(myfunc) {

	if(window.addEventListener)
		 window.addEventListener('load', myfunc, false);
	else if(window.attachEvent)
		 window.attachEvent('onload', myfunc);
}
//addNewOnload(alert('a'));


/* Function that allows you to add functions to different events on the go
 */
function addNewEvent(e, myfunc) {  
	 
	 var old_event = this[e];  
	 if (old_event) {  
		 this[e] = function(e) {  
			 old_event();  
			 myfunc();  
		 };  
	 }  
	 else this[e] = myfunc();  
} 
//addNewEvent(onload,alert('b'));


/* Function that tests if another function exists
 */
 function functionPreExists(myfunc) {
 
	if (typeof myfunc == "function") return true;
	else return false;
 }
//if(functionPreExists(addNewEvent)) { addNewEvent(onload,alert('b')); }	


// Highlight product 
function highlightProduct(productId,newColor,newBorder) {
	
	var newID = $(productId);
	newID.style.background = newColor;
	newID.style.borderTop = newBorder;
}


/**
 * AJAX 
 */	
function makeObject(){ 
	var x; 
	if (window.ActiveXObject) { 
		x = new ActiveXObject("Microsoft.XMLHTTP"); 
	}else if (window.XMLHttpRequest) { 
		x = new XMLHttpRequest(); 
	} 
	return x; 
} 
var request = makeObject(); 

var the_content; 
<!--// 1st //-->
function check_content(the_content){ 
	request.open('get', the_content); 
	request.onreadystatechange = parseCheck_content; 
	request.send(''); 
} 
function parseCheck_content(){ 
	if(request.readyState == 1){ 
	$('recently_used').innerHTML = "<img src='images/4-1.gif' alt='loading...' title='loading...' />"; 
	} 
	if(request.readyState == 4){ 
		var answer = request.responseText; 
		$('recently_used').innerHTML = answer; 
	}
} 


// Contact form functions  
function pleasewait()
{
	$('submit').value = 'Sending, Please wait...';
}

// Callback function that will update the response_form1 div with the response that comes from the server

function updateResponseDiv(req) 
{
	$('submit').value = 'Re-send';
	Spry.Utils.setInnerHTML('response_form1', req.xhRequest.responseText);

	whenContactFinished();
}



var mainModTitle, modaltoppart, mainInnerContent;
function openModalTop(mainModTitle, mainInnerContent) {
		
	if(mainModTitle==undefined) mainModTitle = "";
	if(mainInnerContent==undefined) mainInnerContent = "<h1> TEST </h1>";
	
	// Init New Modal Window
	modaltoppart = new ModalWindow({
		title	 	: mainModTitle,
		content	 	: '<div class="obj_modal_slide_top"> \
						<div class="obj_main"> \
						 '+ mainInnerContent +'\
						</div> \
						<a class="obj_modal_close" onclick="modaltoppart.close();">close</a> \
					   </div>',
		scrollTo 	: true,
		closeAfter	: 8000
	});
}

var mainModTitle, cartbox, mainInnerContent, modBoxWidth;
function openModalBox(mainModTitle, mainInnerContent, modBoxWidth) {
	
	if(mainModTitle==undefined) mainModTitle = "";
	if(mainInnerContent==undefined) mainInnerContent = "<h1> TEST </h1>";
	if(modBoxWidth==undefined) modBoxWidth = "400px";
	
	var boxContent;
	boxContent  = '<div class="obj_modal_box" style="width:'+ modBoxWidth +'">';
	boxContent += '<a class="obj_modal_close" onclick="cartbox.close();">close</a>';
	boxContent += mainInnerContent;
	boxContent += '</div>';
		
	// Init New Modal Window
	cartbox = new ModalWindow({
		title	 	: mainModTitle,
		content	 	: boxContent,
		position	: 'fixed',
		closeAfter	: 8000
	});
}

var product_name, enquireBox;
function enquireAboutProduct(product_name) {
	
	var mainModTitle = "Enquiry about: " + product_name;
	
	var boxContent;
	boxContent  = '<div class="obj_modal_box enquire_about_products">';
	boxContent += '<a class="obj_modal_close" onclick="enquireBox.close();"><img src="images/icons/cancel.png" alt="Cancel" title="Cancel" /></a>';
	boxContent += '<h2> '+ mainModTitle +' </h2>';
	boxContent += '\
	<form method="POST" onsubmit="enquireAboutProductSubmit();return false;">\
	<table width="100%" cellspacing="0" cellpadding="0">\
		<tr>\
			<td> Product Name: </td>\
			<td> <input type="text" name="enquire_product_name" id="enquire_product_name" value="'+ product_name +'" size="40" /> </td>\
		</tr>\
		<tr>\
			<td> Your Name: </td>\
			<td> <input type="text" name="enquire_your_name" id="enquire_your_name" value="" size="40" /> </td>\
		</tr>\
		<tr>\
			<td> Company Name: </td>\
			<td> <input type="text" name="enquire_company_name" id="enquire_company_name" value="" size="40" /> </td>\
		</tr>\
		<tr>\
			<td> Telephone Number: </td>\
			<td> <input type="text" name="enquire_tel_no" id="enquire_tel_no" value="" size="40" /> </td>\
		</tr>\
		<tr>\
			<td> Email Address: </td>\
			<td> <input type="text" name="enquire_email_address" id="enquire_email_address" value="" size="40" /> </td>\
		</tr>\
		<tr>\
			<td colspan="2"> Message: </td>\
		</tr>\
		<tr>\
			<td colspan="2"> <textarea name="enquire_message" id="enquire_message" cols="40" rows="4"></textarea> </td>\
		</tr>\
		<tr>\
			<td colspan="2" align="center"> <input type="submit" name="enquire_submit" id="enquire_submit" value="Submit" /> </td>\
		</tr>\
	</table>\
	';
	boxContent += '</div>';
		
	// Init New Modal Window
	enquireBox = new ModalWindow({
		title	 	: mainModTitle,
		content	 	: boxContent,
		position	: 'fixed'
	});
}

function enquireAboutProductSubmit() {
	
	if($('enquire_product_name')) {
		
		var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
		
		if($('enquire_product_name').value=='') {
			alert('Please enter a product name!');
		}
		else if($('enquire_your_name').value=='') {
			alert('Please enter a your own name!');
		}
		else if($('enquire_tel_no').value=='') {
			alert('Please enter a telephone number.');
		}
		else if($('enquire_email_address').value=='') {
			alert('Please enter an email address.');
		}
		else if($('enquire_message').value=='') {
			alert('Please enter your enquiry text.');
		}
		
		else if(reg.test($('enquire_email_address').value) == false) {
			alert('Please enter a valid email address.');
		}
		
		else {
		new Ajax.Request('includes/enquire_about_product.inc.php', {
			method: 'get',
			parameters: { // these are the variables to be passed into the script
					     product_name: $('enquire_product_name').value,
					     your_name: $('enquire_your_name').value,
					     company_name: $('enquire_company_name').value,
					     tel_no: $('enquire_tel_no').value,
					     email_address: $('enquire_email_address').value,
					     message: $('enquire_message').value
					    },		 
			onLoading: function(){				
			  $('enquire_submit').value = "Sending...";
			}, 
			onSuccess: function(transport){			  
			  var response = transport.responseText || "no response text";
			  $('enquire_submit').value = response;			 
			  // finished and send the user to the thanks page
			  enquireBox.close(); 
			  document.location = "thanks.php";			  
			},
			onFailure: function(){ 
			  $('enquire_submit').value = "Failed to send enquiry, please try again";
			  enquireBox.close();
		   }
		});
		}
	}
}


/**
 * Affiliates Links Modal Functions 
 */

// Affiliates Links , bring up the charitys picker and then forward the user on to the other site. 
var product_id, pickerBox; 
function affiliate_link_charity_picker(product_id) {
	
	// bring in the charity picker
	new Ajax.Request('includes/affiliate_link/charity_picker.php', {
			method: 'get',
			parameters: { // these are the variables to be passed into the script
					     product_id: product_id
					    },		 
			onLoading: function(){			
				//alert('loading...');	
			}, 
			onSuccess: function(transport){			  
			  var response = transport.responseText || "no response text";
			  	
				// Init New Modal Window
				pickerBox = new ModalWindow({
					content	 	: response,
					scrollTo 	: true
				});
			},
			onFailure: function(){ 
				alert('Error, please contact support!');
		   }
		});
}

// if the charity/school is not found...
var linkURL;
function affiliateCharityNotFound(linkURL) {
	
	
	// bring in the charity picker
	new Ajax.Request('includes/affiliate_link/request_new_school.inc.php', {
			method: 'get',
			parameters: { // these are the variables to be passed into the script
					     search_term: $('search_term_input').value,
						 site_url: linkURL
					    },		 
			onLoading: function(){	
				$('charity_picker_search').innerHTML = '<img src="images/ajax-loader.gif" alt="Loading..." title="Loading..." />Loading...';
			}, 
			onSuccess: function(transport){
			  var response = transport.responseText || "no response text";
			  $('charity_picker_search').innerHTML = response;
			  
			  // Now redirect user to the affilate site 
			  setTimeout(function(){ window.location = linkURL; }, 1200);
			  
			},
			onFailure: function(){ 	
			  $('charity_picker_search').innerHTML = 'Error, please contact support!';
		   }
		});

}

// if the charity/school is not found...
function affiliateCharitySearch(linkURL) {
	 
	// bring in the charity picker
	new Ajax.Request('includes/affiliate_link/loop_all_charitys.inc.php', {
			method: 'get',
			parameters: { // these are the variables to be passed into the script
					     search_term: $('search_term_input').value,
						 site_url: linkURL
					    },		 
			onLoading: function(){	
				$('charity_picker_search').innerHTML = '<img src="images/ajax-loader.gif" alt="Loading..." title="Loading..." />Loading...';
			}, 
			onSuccess: function(transport){
			  var response = transport.responseText || "no response text";
			  $('charity_picker_search').innerHTML = response;
			  Effect.Highlight('charity_picker_search');
			  
			},
			onFailure: function(){ 	
			  $('charity_picker_search').innerHTML = 'Error, please contact support!';
		   }
		});

}

/**
* Set Homepage Link plugin
*
* Copyright (c) 2009 Bibby Chung
* Blog: http://bibby.be
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* just for ie and firefox
*
* @example 
* $j('#Button1').click(function() {
*  $j.setHomepage('http://google.com');
* });     
*                    
* or set an elements onClick to... 
* $j.setHomepage(window.location);
*/
                
jQuery.extend({
setHomepage: function(url) {
if (document.all) {
 document.body.style.behavior = 'url(#default#homepage)';
 document.body.setHomePage(url);
}
else if (window.sidebar) {
 if (window.netscape) {
  try {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  }
  catch (e) {
   var strTemp = '';       
   strTemp += " Your browser does not allow us to do this automatically. ";
   strTemp += " To do so manually try going to: Tools -> Options -> Homepage";
   strTemp += " Or to enable us to do so, please enter about:config in your address line,";
   strTemp += " and change the value of signed.applets.codebase_principal_support to true";
   alert(strTemp);
  }
 }
 var prefs = Components.classes['@mozilla.org/preferences-service;1']
     .getService(Components.interfaces.nsIPrefBranch);
 prefs.setCharPref('browser.startup.homepage', url);
}
}
});



var menuSliderId = "bottom_menu_slider";
var menuSliderBackId = "bottom_menu_slider_back";

function open_bottom_menu() {	
	
	new Effect.SlideUp(menuSliderId, { 
		duration: 0.9, 
		scaleFrom: 0, 
		scaleTo: 100, 
		scaleContent:true, 
		beforeStart: function() { // on start of this effect
			new Effect.Opacity(menuSliderId, { from: 0, to: 1.1, duration: 0.6 });
		}, 
		afterFinish: function() { // on finish of this effect
			$(menuSliderId).style.display = 'block';
		} 
	});
	
	new Effect.SlideUp(menuSliderBackId, { 
		duration: 0.9, 
		scaleFrom: 0, 
		scaleTo: 100, 
		scaleContent:true, 
		beforeStart: function() { // on start of this effect
			new Effect.Opacity(menuSliderBackId, { from: 0, to: 0.9, duration: 0.9 });
		}, 
		afterFinish: function() {// on finish of this effect
			$(menuSliderBackId).style.display = 'block';
		} 
	});
	
}

function close_bottom_menu() {	
	
	new Effect.SlideDown(menuSliderId, { 
		duration: 0.9, 
		scaleFrom: 100, 
		scaleTo: 0, 
		scaleContent:true, 
		beforeStart: function() { // on start of this effect
			new Effect.Opacity(menuSliderId, { from: 1.0, to: 0, duration: 0.6 });
		}, 
		afterFinish: function() { // on finish of this effect
			$(menuSliderId).style.display = 'none';
		} 
	});
	
	new Effect.SlideUp(menuSliderBackId, { 
		duration: 0.9, 
		scaleFrom: 100, 
		scaleTo: 0, 
		scaleContent:true, 
		beforeStart: function() { // on start of this effect
			new Effect.Opacity(menuSliderBackId, { from: 1.0, to: 0, duration: 0.9 });
		}, 
		afterFinish: function() {// on finish of this effect
			$(menuSliderBackId).style.display = 'none';
			//document.body.removeChild($(menuSliderBackId)); 
		} 
	});	
		
}


// Open the hidden secure site box 
function openHiddenSecureBox() {

	var theUrlToRequest = "includes/request_secure_file_content.php";
	
	new Ajax.Request(theUrlToRequest,
	  {
		method:'post',
  		parameters: {
			url: document.domain, 
			limit: 12
		},
		onSuccess: function(transport){
		  var response = transport.responseText || "no response text";
		  $('hidden_secure_box').innerHTML = response;
		  Effect.toggle('hidden_secure_box', 'appear', { duration: 0.4 });
		},
		onFailure: function(){ 
			return true;
		}
	  });
}


// Bookmark Site  
var title;
var url;
function bookmarkSite(title, url)
{

 if (window.opera && window.print) // opera
  {
	 var element = document.createElement("a");
	 element.setAttribute("href", url);
	 element.setAttribute("title", title);
	 element.setAttribute("rel", "sidebar");
	 element.click();
  } 
  else if (document.all) // ie
  {
	 window.external.AddFavorite(url, title);
  } 
  else if (window.sidebar) // firefox
  {
	 window.sidebar.addPanel(title, url, "");
  }
}

function toggleAddThis() {

	Effect.toggle('faves_box_hidden', 'blind', { duration: 0.4 }); return false;
}
	
	
var the_new_content;
function change_faq_content(the_new_content){ 
	
var this_new_content = 'includes/site_construct/expert_system.inc.php'+the_new_content;
	
	new Ajax.Request(this_new_content, {
		method:'get',
		onLoading: function(){
			//$('return_ajax_content').innerHTML = '<img src="images/ajax-loader.gif"/>'; 
		},
		onSuccess: function(transport){
		 	var response = transport.responseText || "no response text";
			$('return_ajax_content').innerHTML = response;
		},
		onFailure: function(){ 
			// alert('Something went wrong...');
		}
	  });

} 


/**
* Refreshing function for all png capture images 
*/
var epci, elImg;
function refresh_php_png_img(elImg) {
	
	// if specific img defined, just refresh that one,
	if(elImg != undefined) {
		var queryMark = "?";
		if(elImg.src.indexOf("?")!=-1) queryMark = "&";
		elImg.src = elImg.src + queryMark + 'additional=' + Math.random();
	} 
	// otherwise refresh them all to be sure 
	else {
		$$('img.png_capture_img').each(function(epci) {
						
			//var newImage = document.createElement("img"); 
			var newImage = new Image();
			var queryMark = "?";
			if(epci.src.indexOf("?")!=-1) queryMark = "&";
			newImage.src = epci.src + queryMark + 'additional=' + Math.random();
			newImage.onclick = function() { refresh_php_png_img(this); };
			newImage.className = "png_capture_img";
			newImage.title = "Please type in the value of this image";
			newImage.alt = newImage.title;
			newImage.align = "middle";
			newImage.width = "75";
			newImage.height = "35";
			epci.parentNode.replaceChild(newImage, epci); 
			//alert('src = ' + newImage.src);
			//epci.src = epci.src;
		});
	}
}


// Init canvas text 
if(!functionPreExists('initCanvas')) { 
	function initCanvas(canvas) {
		if (window.G_vmlCanvasManager && window.attachEvent && !window.opera) {
		  canvas = window.G_vmlCanvasManager.initElement(canvas);
		}
		return canvas;
	}
}



// Toggle Category 
var obj;
var subObj;
var parentObj;
function toggleCategory(obj) {

	parentObj = $(obj.id).up(0);
	subObj = parentObj.down('div');

	if(parentObj.className != 'current') {
		//subObj.style.display = 'block';
		Effect.toggle(subObj.id,'slide', {
			duration: 0.8,
			afterFinish: function() {
				parentObj.addClassName('current');
				obj.innerHTML = '&laquo;';//'<img src="images/icons/delete.png" alt="Close" />'; 
				obj.style.fontSize = '18px';
			}
		});
	}
	else {
		//subObj.style.display = ''; 
		Effect.toggle(subObj.id,'slide', {
			duration: 0.8,
			afterFinish: function() {
				parentObj.removeClassName('current');
				obj.innerHTML = '&raquo;';//'<img src="images/icons/add.png" alt="Open" />';
				obj.style.fontSize = '24px';
			}
		});
	}
	
	//if(parentObj.up(0).tagName=='LI');
	if(parentObj.up(0).up(0).up(0).tagName=='LI') {
		
		setTimeout(function(){ 
			var above_span = parentObj.up(0).up(0).up(0).down('span');
			var above_div = parentObj.up(0).up(0).up(0).down('div');
			
			if(above_div.style.display=='none') {
				toggleCategory( above_span ); 
			}
		}, 1000);
	}
}



// Insert a flash file 
var myFlashVideo = {}; // Flash video config object
function insertFlashObject(myFlashVideo) {
	
  var randNum = Math.floor(Math.random()*999);
  
  myFlashVideo.elementId = "myFlashSliderContent_" + randNum;
  myFlashVideo.flashVersion = "9.0.0";
  myFlashVideo.params = { // Flash object params
    menu: "false",
    play: "true",
    wmode: "transparent",
    bgcolor: "#000000",
    allowfullscreen: "false",
    allowscriptaccess: "sameDomain"
  };
  myFlashVideo.attributes = { // Flash object attributes
    id: "myDynamicContent_" + randNum, name: "myDynamicContent_" + randNum
  };
    
  document.write('<div id="myFlashSliderContent_'+randNum+'"><!-- If flash is not installed... -->\
  <a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a>\
</div>');
  // Embed the flash into the page
  return swfobject.embedSWF(myFlashVideo.src, myFlashVideo.elementId, myFlashVideo.width, myFlashVideo.height, myFlashVideo.flashVersion,"expressInstall.swf", myFlashVideo.flashvars, myFlashVideo.params, myFlashVideo.attributes);	
}

function popupFancyBoxImage(flashObjSrc) {
   $j.fancybox({ 'title' : '', 'href' : flashObjSrc });
}




/*
* Begin File: "js/menu-animations.js"
*/

/** 
 * jQuery Header Menu Animations 
 *  (And IE6 Fix) 
 */
jQuery(document).ready(function() {
	
	var isSubMenu;
	
	// Ignore currently if safari TEMP ONLY ~UNTILL FIX FINISHED !! 
	if( navigator.userAgent.toLowerCase().search(/safari/i) !== 99 ) { 
	
	// List Menu Hovers 
    jQuery("ul.header-menu li").hover(						   
		function() {    
			jQuery(this).addClass("hover");
			jQuery('ul',this).css('display', 'block');
			jQuery('li ul',this).css('display', 'none');
			
			if(!jQuery(this).hasClass('current')) { 
				jQuery('a',this).css('background-color', defaultHeaderSubMenuColor);
			 	jQuery('>a',this).css('background-color', defaultHeaderMenuColor);
			}
			
			jQuery(">a",this).animate({
				backgroundColor: hoverHeaderMenuColor,
				paddingTop: "10px"
			}, 'fast' );
		}, 
		function() {    
        	jQuery(this).removeClass("hover");
        	jQuery('ul',this).css('display', 'none');
			
			aboveListTagName = jQuery(this).parent().parent().parent().get(0).tagName;
			isSubMenu = ((aboveListTagName=='UL') || (aboveListTagName=='LI')) ? 1 : 0;
						
			jQuery('a',this).css('background-color', hoverHeaderMenuColor);
			jQuery(">a",this).animate({
				backgroundColor: ( this.className=='current' ? hoverHeaderMenuColor : (isSubMenu ? defaultHeaderSubMenuColor : defaultHeaderMenuColor ) ),
				paddingTop: "6px"
			}, 'fast' );
		}
	);
			

	// Sub Menu Hovers 
    jQuery("ul.header-menu ul").hover(						   
		function() {    
			jQuery(this).addClass("hover");
		}, 
		function() {    
        	jQuery(this).removeClass("hover");
		}
	);

	}

	// Add Arrows 
   	if(!isRunningIE6OrBelow) jQuery("ul.header-menu ul li:has(ul)").find("a:first").prepend(" <span>&raquo;</span> ");
	if(!isRunningIE6OrBelow) jQuery("ul.header-menu>li:has(ul)").find("a:first").append("<span>&raquo;</span>");
	

});
//-->









/*
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */

(function(jQuery){

	// We override the animation for all of these color styles
	jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
		jQuery.fx.step[attr] = function(fx){
			if (fx.state == 0 || fx.start.constructor != Array || fx.end.constructor != Array) {
				fx.start = getColor( fx.elem, attr );
				if (fx.end == "transparent") fx.end = getColor(fx.elem.parentNode, "backgroundColor");
				fx.end = getRGB( fx.end );
			}
			
			fx.elem.style[attr] = "rgb(" + [
				Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
				Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
				Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
			].join(",") + ")";
		}
	});

	// Color Conversion functions from highlightFade
	// By Blair Mitchelmore
	// http://jquery.offput.ca/highlightFade/

	// Parse strings looking for color tuples [255,255,255]
	function getRGB(color) {
		var result;

		// Check if we're already dealing with an array of colors
		if ( color && color.constructor == Array && color.length == 3 )
			return color;

		// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
			return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

		// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
			return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

		// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
			return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

		// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
			return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

		// Otherwise, we're most likely dealing with a named color
		return colors[jQuery.trim(color).toLowerCase()];
	}
	
	function getColor(elem, attr) {
		var color;

		do {
			color = jQuery.curCSS(elem, attr);

			// Keep going until we find an element that has color, or we hit the body
			if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
				break; 

			attr = "backgroundColor";
		} while ( elem = elem.parentNode );

		return getRGB(color);
	};
	
	// Some named colors to work with
	// From Interface by Stefan Petre
	// http://interface.eyecon.ro/

	var colors = {
		aqua:[0,255,255],
		azure:[240,255,255],
		beige:[245,245,220],
		black:[0,0,0],
		blue:[0,0,255],
		brown:[165,42,42],
		cyan:[0,255,255],
		darkblue:[0,0,139],
		darkcyan:[0,139,139],
		darkgrey:[169,169,169],
		darkgreen:[0,100,0],
		darkkhaki:[189,183,107],
		darkmagenta:[139,0,139],
		darkolivegreen:[85,107,47],
		darkorange:[255,140,0],
		darkorchid:[153,50,204],
		darkred:[139,0,0],
		darksalmon:[233,150,122],
		darkviolet:[148,0,211],
		fuchsia:[255,0,255],
		gold:[255,215,0],
		green:[0,128,0],
		indigo:[75,0,130],
		khaki:[240,230,140],
		lightblue:[173,216,230],
		lightcyan:[224,255,255],
		lightgreen:[144,238,144],
		lightgrey:[211,211,211],
		lightpink:[255,182,193],
		lightyellow:[255,255,224],
		lime:[0,255,0],
		magenta:[255,0,255],
		maroon:[128,0,0],
		navy:[0,0,128],
		olive:[128,128,0],
		orange:[255,165,0],
		pink:[255,192,203],
		purple:[128,0,128],
		violet:[128,0,128],
		red:[255,0,0],
		silver:[192,192,192],
		white:[255,255,255],
		yellow:[255,255,0]
	};
	
})(jQuery);



/*
* Begin File: "js/swfobject.js"
*/

/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();



/*
* Begin File: "js/lightbox.js"
*/

// -----------------------------------------------------------------------------------
//
//	Lightbox v2.04
//	by Lokesh Dhakar - http://www.lokeshdhakar.com
//	Last Modification: 2/9/08
//
//	For more information, visit:
//	http://lokeshdhakar.com/projects/lightbox2/
//
//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//  	- Free for use in both personal and commercial projects
//		- Attribution requires leaving author name, author link, and the license info intact.
//	
//  Thanks: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), and Thomas Fuchs(mir.aculo.us) for ideas, libs, and snippets.
//  		Artemy Tregubenko (arty.name) for cleanup and help in updating to latest ver of proto-aculous.
//
// -----------------------------------------------------------------------------------
/*

    Table of Contents
    -----------------
    Configuration

    Lightbox Class Declaration
    - initialize()
    - updateImageList()
    - start()
    - changeImage()
    - resizeImageContainer()
    - showImage()
    - updateDetails()
    - updateNav()
    - enableKeyboardNav()
    - disableKeyboardNav()
    - keyboardAction()
    - preloadNeighborImages()
    - end()
    
    Function Calls
    - document.observe()
   
*/
// -----------------------------------------------------------------------------------

//
//  Configurationl
//
LightboxOptions = Object.extend({
    fileLoadingImage:        'images/loading.gif',     
    fileBottomNavCloseImage: 'images/closelabel.gif',

    overlayOpacity: 0.8,   // controls transparency of shadow overlay

    animate: true,         // toggles resizing animations
    resizeSpeed: 7,        // controls the speed of the image resizing animations (1=slowest and 10=fastest)

    borderSize: 10,         //if you adjust the padding in the CSS, you will need to update this variable

	// When grouping images this is used to write: Image # of #.
	// Change it for non-english localization
	labelImage: "Image",
	labelOf: "of"
}, window.LightboxOptions || {});

// -----------------------------------------------------------------------------------

var Lightbox = Class.create();

Lightbox.prototype = {
    imageArray: [],
    activeImage: undefined,
    
    // initialize()
    // Constructor runs on completion of the DOM loading. Calls updateImageList and then
    // the function inserts html at the bottom of the page which is used to display the shadow 
    // overlay and the image container.
    //
    initialize: function() {    
        
        this.updateImageList();
        
        this.keyboardAction = this.keyboardAction.bindAsEventListener(this);

        if (LightboxOptions.resizeSpeed > 10) LightboxOptions.resizeSpeed = 10;
        if (LightboxOptions.resizeSpeed < 1)  LightboxOptions.resizeSpeed = 1;

	    this.resizeDuration = LightboxOptions.animate ? ((11 - LightboxOptions.resizeSpeed) * 0.15) : 0;
	    this.overlayDuration = LightboxOptions.animate ? 0.2 : 0;  // shadow fade in/out duration

        // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
        // If animations are turned off, it will be hidden as to prevent a flicker of a
        // white 250 by 250 box.
        var size = (LightboxOptions.animate ? 250 : 1) + 'px';
        

        // Code inserts html at the bottom of the page that looks similar to this:
        //
        //  <div id="overlay"></div>
        //  <div id="lightbox">
        //      <div id="outerImageContainer">
        //          <div id="imageContainer">
        //              <img id="lightboxImage">
        //              <div style="" id="hoverNav">
        //                  <a href="#" id="prevLink"></a>
        //                  <a href="#" id="nextLink"></a>
        //              </div>
        //              <div id="loading">
        //                  <a href="#" id="loadingLink">
        //                      <img src="images/loading.gif">
        //                  </a>
        //              </div>
        //          </div>
        //      </div>
        //      <div id="imageDataContainer">
        //          <div id="imageData">
        //              <div id="imageDetails">
        //                  <span id="caption"></span>
        //                  <span id="numberDisplay"></span>
        //              </div>
        //              <div id="bottomNav">
        //                  <a href="#" id="bottomNavClose">
        //                      <img src="images/close.gif">
        //                  </a>
        //              </div>
        //          </div>
        //      </div>
        //  </div>


        var objBody = $$('body')[0];

		objBody.appendChild(Builder.node('div',{id:'overlay'}));
	
        objBody.appendChild(Builder.node('div',{id:'lightbox'}, [
            Builder.node('div',{id:'outerImageContainer'}, 
                Builder.node('div',{id:'imageContainer'}, [
                    Builder.node('img',{id:'lightboxImage'}), 
                    Builder.node('div',{id:'hoverNav'}, [
                        Builder.node('a',{id:'prevLink', href: '#' }),
                        Builder.node('a',{id:'nextLink', href: '#' })
                    ]),
                    Builder.node('div',{id:'loading'}, 
                        Builder.node('a',{id:'loadingLink', href: '#' }, 
                            Builder.node('img', {src: LightboxOptions.fileLoadingImage})
                        )
                    )
                ])
            ),
            Builder.node('div', {id:'imageDataContainer'},
                Builder.node('div',{id:'imageData'}, [
                    Builder.node('div',{id:'imageDetails'}, [
                        Builder.node('span',{id:'caption'}),
                        Builder.node('span',{id:'numberDisplay'})
                    ]),
                    Builder.node('div',{id:'bottomNav'},
                        Builder.node('a',{id:'bottomNavClose', href: '#' },
                            Builder.node('img', { src: LightboxOptions.fileBottomNavCloseImage })
                        )
                    )
                ])
            )
        ]));


		$('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
		$('lightbox').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
		$('outerImageContainer').setStyle({ width: size, height: size });
		$('prevLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage - 1); }).bindAsEventListener(this));
		$('nextLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage + 1); }).bindAsEventListener(this));
		$('loadingLink').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
		$('bottomNavClose').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));

        var th = this;
        (function(){
            var ids = 
                'overlay lightbox outerImageContainer imageContainer lightboxImage hoverNav prevLink nextLink loading loadingLink ' + 
                'imageDataContainer imageData imageDetails caption numberDisplay bottomNav bottomNavClose';   
            $w(ids).each(function(id){ th[id] = $(id); });
        }).defer();
    },

    //
    // updateImageList()
    // Loops through anchor tags looking for 'lightbox' references and applies onclick
    // events to appropriate links. You can rerun after dynamically adding images w/ajax.
    //
    updateImageList: function() {   
        this.updateImageList = Prototype.emptyFunction;

        document.observe('click', (function(event){
            var target = event.findElement('a[rel^=lightbox]') || event.findElement('area[rel^=lightbox]');
            if (target) {
                event.stop();
                this.start(target);
            }
        }).bind(this));
    },
    
    //
    //  start()
    //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
    //
    start: function(imageLink) {    

        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

        // stretch overlay to fill page and fade in
        var arrayPageSize = this.getPageSize();
        $('overlay').setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });

        new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: LightboxOptions.overlayOpacity });

        this.imageArray = [];
        var imageNum = 0;       

        if ((imageLink.rel == 'lightbox')){
            // if image is NOT part of a set, add single image to imageArray
            this.imageArray.push([imageLink.href, imageLink.title]);         
        } else {
            // if image is part of a set..
            /*
		    this.imageArray = 
                $$(imageLink.tagName + '[href][rel="' + imageLink.rel + '"]').
                collect(function(anchor){ return [anchor.href, anchor.title]; }).
                uniq();
			*/
				this.imageArray = 
				$$(imageLink.tagName + '[href][rel="' + imageLink.rel + '"]').
				collect(function(anchor){ return [anchor.href, anchor.title]; }).
				invoke("toJSON").uniq().invoke("evalJSON");
			
			while (this.imageArray[imageNum][0] != imageLink.href) { imageNum++; }
        }

        // calculate top and left offset for the lightbox 
        var arrayPageScroll = document.viewport.getScrollOffsets();
        var lightboxTop = arrayPageScroll[1] + (document.viewport.getHeight() / 10);
        var lightboxLeft = arrayPageScroll[0];
        this.lightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
        
        this.changeImage(imageNum);
    },

    //
    //  changeImage()
    //  Hide most elements and preload image in preparation for resizing image container.
    //
    changeImage: function(imageNum) {   
        
        this.activeImage = imageNum; // update global var

        // hide elements during transition
        if (LightboxOptions.animate) this.loading.show();
        this.lightboxImage.hide();
        this.hoverNav.hide();
        this.prevLink.hide();
        this.nextLink.hide();
		// HACK: Opera9 does not currently support scriptaculous opacity and appear fx
        this.imageDataContainer.setStyle({opacity: .0001});
        this.numberDisplay.hide();      
        
        var imgPreloader = new Image();
        
        // once image is preloaded, resize image container


        imgPreloader.onload = (function(){
            this.lightboxImage.src = this.imageArray[this.activeImage][0];
            this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
        }).bind(this);
        imgPreloader.src = this.imageArray[this.activeImage][0];
    },

    //
    //  resizeImageContainer()
    //
    resizeImageContainer: function(imgWidth, imgHeight) {

        // get current width and height
        var widthCurrent  = this.outerImageContainer.getWidth();
        var heightCurrent = this.outerImageContainer.getHeight();

        // get new width and height
        var widthNew  = (imgWidth  + LightboxOptions.borderSize * 2);
        var heightNew = (imgHeight + LightboxOptions.borderSize * 2);

        // scalars based on change from old to new
        var xScale = (widthNew  / widthCurrent)  * 100;
        var yScale = (heightNew / heightCurrent) * 100;

        // calculate size difference between new and old image, and resize if necessary
        var wDiff = widthCurrent - widthNew;
        var hDiff = heightCurrent - heightNew;

        if (hDiff != 0) new Effect.Scale(this.outerImageContainer, yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'}); 
        if (wDiff != 0) new Effect.Scale(this.outerImageContainer, xScale, {scaleY: false, duration: this.resizeDuration, delay: this.resizeDuration}); 

        // if new and old image are same size and no scaling transition is necessary, 
        // do a quick pause to prevent image flicker.
        var timeout = 0;
        if ((hDiff == 0) && (wDiff == 0)){
            timeout = 100;
            if (Prototype.Browser.IE) timeout = 250;   
        }

        (function(){
            this.prevLink.setStyle({ height: imgHeight + 'px' });
            this.nextLink.setStyle({ height: imgHeight + 'px' });
            this.imageDataContainer.setStyle({ width: widthNew + 'px' });

            this.showImage();
        }).bind(this).delay(timeout / 1000);
    },
    
    //
    //  showImage()
    //  Display image and begin preloading neighbors.
    //
    showImage: function(){
        this.loading.hide();
        new Effect.Appear(this.lightboxImage, { 
            duration: this.resizeDuration, 
            queue: 'end', 
            afterFinish: (function(){ this.updateDetails(); }).bind(this) 
        });
        this.preloadNeighborImages();
    },

    //
    //  updateDetails()
    //  Display caption, image number, and bottom nav.
    //
    updateDetails: function() {
    
        // if caption is not null
        if (this.imageArray[this.activeImage][1] != ""){
            this.caption.update(this.imageArray[this.activeImage][1]).show();
        }
        
        // if image is part of set display 'Image x of x' 
        if (this.imageArray.length > 1){
            this.numberDisplay.update( LightboxOptions.labelImage + ' ' + (this.activeImage + 1) + ' ' + LightboxOptions.labelOf + '  ' + this.imageArray.length).show();
        }

        new Effect.Parallel(
            [ 
                new Effect.SlideDown(this.imageDataContainer, { sync: true, duration: this.resizeDuration, from: 0.0, to: 1.0 }), 
                new Effect.Appear(this.imageDataContainer, { sync: true, duration: this.resizeDuration }) 
            ], 
            { 
                duration: this.resizeDuration, 
                afterFinish: (function() {
	                // update overlay size and update nav
	                var arrayPageSize = this.getPageSize();
	                this.overlay.setStyle({ height: arrayPageSize[1] + 'px' });
	                this.updateNav();
                }).bind(this)
            } 
        );
    },

    //
    //  updateNav()
    //  Display appropriate previous and next hover navigation.
    //
    updateNav: function() {

        this.hoverNav.show();               

        // if not first image in set, display prev image button
        if (this.activeImage > 0) this.prevLink.show();

        // if not last image in set, display next image button
        if (this.activeImage < (this.imageArray.length - 1)) this.nextLink.show();
        
        this.enableKeyboardNav();
    },

    //
    //  enableKeyboardNav()
    //
    enableKeyboardNav: function() {
        document.observe('keydown', this.keyboardAction); 
    },

    //
    //  disableKeyboardNav()
    //
    disableKeyboardNav: function() {
        document.stopObserving('keydown', this.keyboardAction); 
    },

    //
    //  keyboardAction()
    //
    keyboardAction: function(event) {
        var keycode = event.keyCode;

        var escapeKey;
        if (event.DOM_VK_ESCAPE) {  // mozilla
            escapeKey = event.DOM_VK_ESCAPE;
        } else { // ie
            escapeKey = 27;
        }

        var key = String.fromCharCode(keycode).toLowerCase();
        
        if (key.match(/x|o|c/) || (keycode == escapeKey)){ // close lightbox
            this.end();
        } else if ((key == 'p') || (keycode == 37)){ // display previous image
            if (this.activeImage != 0){
                this.disableKeyboardNav();
                this.changeImage(this.activeImage - 1);
            }
        } else if ((key == 'n') || (keycode == 39)){ // display next image
            if (this.activeImage != (this.imageArray.length - 1)){
                this.disableKeyboardNav();
                this.changeImage(this.activeImage + 1);
            }
        }
    },

    //
    //  preloadNeighborImages()
    //  Preload previous and next images.
    //
    preloadNeighborImages: function(){
        var preloadNextImage, preloadPrevImage;
        if (this.imageArray.length > this.activeImage + 1){
            preloadNextImage = new Image();
            preloadNextImage.src = this.imageArray[this.activeImage + 1][0];
        }
        if (this.activeImage > 0){
            preloadPrevImage = new Image();
            preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];
        }
    
    },

    //
    //  end()
    //
    end: function() {
        this.disableKeyboardNav();
        this.lightbox.hide();
        new Effect.Fade(this.overlay, { duration: this.overlayDuration });
        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
    },

    //
    //  getPageSize()
    //
    getPageSize: function() {
	        
	     var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;
		
		if (self.innerHeight) {	// all except Explorer
			if(document.documentElement.clientWidth){
				windowWidth = document.documentElement.clientWidth; 
			} else {
				windowWidth = self.innerWidth;
			}
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}
	
		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = xScroll;		
		} else {
			pageWidth = windowWidth;
		}

		return [pageWidth,pageHeight];
	}
}
document.observe('dom:loaded', function () { new Lightbox(); }); 




/*
* Begin File: "js/jquery.mousewheel-3.0.2.pack.js"
*/

/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 * 
 * Requires: 1.2.2+
 */

(function(b){function d(a){var f=[].slice.call(arguments,1),e=0;a=b.event.fix(a||window.event);a.type="mousewheel";if(a.wheelDelta)e=a.wheelDelta/120;if(a.detail)e=-a.detail/3;f.unshift(a,e);return b.event.handle.apply(this,f)}var c=["DOMMouseScroll","mousewheel"];b.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],d,false);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],
d,false);else this.onmousewheel=null}};b.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);



/*
* Begin File: "js/jquery.easing-1.3.pack.js"
*/

/*
 * jQuery Easing Compatibility v1 - http://gsgd.co.uk/sandbox/jquery.easing.php
 *
 * Adds compatibility for applications that use the pre 1.2 easing names
 *
 * Copyright (c) 2007 George Smith
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */

jQuery.extend( jQuery.easing,
{
	easeIn: function (x, t, b, c, d) {
		return jQuery.easing.easeInQuad(x, t, b, c, d);
	},
	easeOut: function (x, t, b, c, d) {
		return jQuery.easing.easeOutQuad(x, t, b, c, d);
	},
	easeInOut: function (x, t, b, c, d) {
		return jQuery.easing.easeInOutQuad(x, t, b, c, d);
	},
	expoin: function(x, t, b, c, d) {
		return jQuery.easing.easeInExpo(x, t, b, c, d);
	},
	expoout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutExpo(x, t, b, c, d);
	},
	expoinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutExpo(x, t, b, c, d);
	},
	bouncein: function(x, t, b, c, d) {
		return jQuery.easing.easeInBounce(x, t, b, c, d);
	},
	bounceout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutBounce(x, t, b, c, d);
	},
	bounceinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutBounce(x, t, b, c, d);
	},
	elasin: function(x, t, b, c, d) {
		return jQuery.easing.easeInElastic(x, t, b, c, d);
	},
	elasout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutElastic(x, t, b, c, d);
	},
	elasinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutElastic(x, t, b, c, d);
	},
	backin: function(x, t, b, c, d) {
		return jQuery.easing.easeInBack(x, t, b, c, d);
	},
	backout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutBack(x, t, b, c, d);
	},
	backinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutBack(x, t, b, c, d);
	}
});



/*
* Begin File: "js/jquery.fancybox-1.3.1.pack.js"
*/

/*
 * FancyBox - jQuery Plugin
 * Simple and fancy lightbox alternative
 *
 * Examples and documentation at: http://fancybox.net
 * 
 * Copyright (c) 2008 - 2010 Janis Skarnelis
 *
 * Version: 1.3.1 (05/03/2010)
 * Requires: jQuery v1.3+
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

(function(b){var m,u,x,g,D,i,z,A,B,p=0,e={},q=[],n=0,c={},j=[],E=null,s=new Image,G=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,S=/[^\.]\.(swf)\s*$/i,H,I=1,k,l,h=false,y=b.extend(b("<div/>")[0],{prop:0}),v=0,O=!b.support.opacity&&!window.XMLHttpRequest,J=function(){u.hide();s.onerror=s.onload=null;E&&E.abort();m.empty()},P=function(){b.fancybox('<p id="fancybox_error">The requested content cannot be loaded.<br />Please try again later.</p>',{scrolling:"no",padding:20,transitionIn:"none",transitionOut:"none"})},
K=function(){return[b(window).width(),b(window).height(),b(document).scrollLeft(),b(document).scrollTop()]},T=function(){var a=K(),d={},f=c.margin,o=c.autoScale,t=(20+f)*2,w=(20+f)*2,r=c.padding*2;if(c.width.toString().indexOf("%")>-1){d.width=a[0]*parseFloat(c.width)/100-40;o=false}else d.width=c.width+r;if(c.height.toString().indexOf("%")>-1){d.height=a[1]*parseFloat(c.height)/100-40;o=false}else d.height=c.height+r;if(o&&(d.width>a[0]-t||d.height>a[1]-w))if(e.type=="image"||e.type=="swf"){t+=r;
w+=r;o=Math.min(Math.min(a[0]-t,c.width)/c.width,Math.min(a[1]-w,c.height)/c.height);d.width=Math.round(o*(d.width-r))+r;d.height=Math.round(o*(d.height-r))+r}else{d.width=Math.min(d.width,a[0]-t);d.height=Math.min(d.height,a[1]-w)}d.top=a[3]+(a[1]-(d.height+40))*0.5;d.left=a[2]+(a[0]-(d.width+40))*0.5;if(c.autoScale===false){d.top=Math.max(a[3]+f,d.top);d.left=Math.max(a[2]+f,d.left)}return d},U=function(a){if(a&&a.length)switch(c.titlePosition){case "inside":return a;case "over":return'<span id="fancybox-title-over">'+
a+"</span>";default:return'<span id="fancybox-title-wrap"><span id="fancybox-title-left"></span><span id="fancybox-title-main">'+a+'</span><span id="fancybox-title-right"></span></span>'}return false},V=function(){var a=c.title,d=l.width-c.padding*2,f="fancybox-title-"+c.titlePosition;b("#fancybox-title").remove();v=0;if(c.titleShow!==false){a=b.isFunction(c.titleFormat)?c.titleFormat(a,j,n,c):U(a);if(!(!a||a==="")){b('<div id="fancybox-title" class="'+f+'" />').css({width:d,paddingLeft:c.padding,
paddingRight:c.padding}).html(a).appendTo("body");switch(c.titlePosition){case "inside":v=b("#fancybox-title").outerHeight(true)-c.padding;l.height+=v;break;case "over":b("#fancybox-title").css("bottom",c.padding);break;default:b("#fancybox-title").css("bottom",b("#fancybox-title").outerHeight(true)*-1);break}b("#fancybox-title").appendTo(D).hide()}}},W=function(){b(document).unbind("keydown.fb").bind("keydown.fb",function(a){if(a.keyCode==27&&c.enableEscapeButton){a.preventDefault();b.fancybox.close()}else if(a.keyCode==
37){a.preventDefault();b.fancybox.prev()}else if(a.keyCode==39){a.preventDefault();b.fancybox.next()}});if(b.fn.mousewheel){g.unbind("mousewheel.fb");j.length>1&&g.bind("mousewheel.fb",function(a,d){a.preventDefault();h||d===0||(d>0?b.fancybox.prev():b.fancybox.next())})}if(c.showNavArrows){if(c.cyclic&&j.length>1||n!==0)A.show();if(c.cyclic&&j.length>1||n!=j.length-1)B.show()}},X=function(){var a,d;if(j.length-1>n){a=j[n+1].href;if(typeof a!=="undefined"&&a.match(G)){d=new Image;d.src=a}}if(n>0){a=
j[n-1].href;if(typeof a!=="undefined"&&a.match(G)){d=new Image;d.src=a}}},L=function(){i.css("overflow",c.scrolling=="auto"?c.type=="image"||c.type=="iframe"||c.type=="swf"?"hidden":"auto":c.scrolling=="yes"?"auto":"visible");if(!b.support.opacity){i.get(0).style.removeAttribute("filter");g.get(0).style.removeAttribute("filter")}b("#fancybox-title").show();c.hideOnContentClick&&i.one("click",b.fancybox.close);c.hideOnOverlayClick&&x.one("click",b.fancybox.close);c.showCloseButton&&z.show();W();b(window).bind("resize.fb",
b.fancybox.center);c.centerOnScroll?b(window).bind("scroll.fb",b.fancybox.center):b(window).unbind("scroll.fb");b.isFunction(c.onComplete)&&c.onComplete(j,n,c);h=false;X()},M=function(a){var d=Math.round(k.width+(l.width-k.width)*a),f=Math.round(k.height+(l.height-k.height)*a),o=Math.round(k.top+(l.top-k.top)*a),t=Math.round(k.left+(l.left-k.left)*a);g.css({width:d+"px",height:f+"px",top:o+"px",left:t+"px"});d=Math.max(d-c.padding*2,0);f=Math.max(f-(c.padding*2+v*a),0);i.css({width:d+"px",height:f+
"px"});if(typeof l.opacity!=="undefined")g.css("opacity",a<0.5?0.5:a)},Y=function(a){var d=a.offset();d.top+=parseFloat(a.css("paddingTop"))||0;d.left+=parseFloat(a.css("paddingLeft"))||0;d.top+=parseFloat(a.css("border-top-width"))||0;d.left+=parseFloat(a.css("border-left-width"))||0;d.width=a.width();d.height=a.height();return d},Q=function(){var a=e.orig?b(e.orig):false,d={};if(a&&a.length){a=Y(a);d={width:a.width+c.padding*2,height:a.height+c.padding*2,top:a.top-c.padding-20,left:a.left-c.padding-
20}}else{a=K();d={width:1,height:1,top:a[3]+a[1]*0.5,left:a[2]+a[0]*0.5}}return d},N=function(){u.hide();if(g.is(":visible")&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){b.event.trigger("fancybox-cancel");h=false;return}j=q;n=p;c=e;i.get(0).scrollTop=0;i.get(0).scrollLeft=0;if(c.overlayShow){O&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});
x.css({"background-color":c.overlayColor,opacity:c.overlayOpacity}).unbind().show()}l=T();V();if(g.is(":visible")){b(z.add(A).add(B)).hide();var a=g.position(),d;k={top:a.top,left:a.left,width:g.width(),height:g.height()};d=k.width==l.width&&k.height==l.height;i.fadeOut(c.changeFade,function(){var f=function(){i.html(m.contents()).fadeIn(c.changeFade,L)};b.event.trigger("fancybox-change");i.empty().css("overflow","hidden");if(d){i.css({top:c.padding,left:c.padding,width:Math.max(l.width-c.padding*
2,1),height:Math.max(l.height-c.padding*2-v,1)});f()}else{i.css({top:c.padding,left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)});y.prop=0;b(y).animate({prop:1},{duration:c.changeSpeed,easing:c.easingChange,step:M,complete:f})}})}else{g.css("opacity",1);if(c.transitionIn=="elastic"){k=Q();i.css({top:c.padding,left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)}).html(m.contents());g.css(k).show();if(c.opacity)l.opacity=
0;y.prop=0;b(y).animate({prop:1},{duration:c.speedIn,easing:c.easingIn,step:M,complete:L})}else{i.css({top:c.padding,left:c.padding,width:Math.max(l.width-c.padding*2,1),height:Math.max(l.height-c.padding*2-v,1)}).html(m.contents());g.css(l).fadeIn(c.transitionIn=="none"?0:c.speedIn,L)}}},F=function(){m.width(e.width);m.height(e.height);if(e.width=="auto")e.width=m.width();if(e.height=="auto")e.height=m.height();N()},Z=function(){h=true;e.width=s.width;e.height=s.height;b("<img />").attr({id:"fancybox-img",
src:s.src,alt:e.title}).appendTo(m);N()},C=function(){J();var a=q[p],d,f,o,t,w;e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));o=a.title||b(a).title||e.title||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?b(a).children("img:first"):b(a);if(o===""&&e.orig)o=e.orig.attr("alt");d=a.nodeName&&/^(?:javascript|#)/i.test(a.href)?e.href||null:e.href||a.href||null;if(e.type){f=e.type;if(!d)d=e.content}else if(e.content)f="html";else if(d)if(d.match(G))f=
"image";else if(d.match(S))f="swf";else if(b(a).hasClass("iframe"))f="iframe";else if(d.match(/#/)){a=d.substr(d.indexOf("#"));f=b(a).length>0?"inline":"ajax"}else f="ajax";else f="inline";e.type=f;e.href=d;e.title=o;if(e.autoDimensions&&e.type!=="iframe"&&e.type!=="swf"){e.width="auto";e.height="auto"}if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=false;e.enableEscapeButton=false;e.showCloseButton=false}if(b.isFunction(e.onStart))if(e.onStart(q,p,e)===false){h=false;
return}m.css("padding",20+e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(i.children())});switch(f){case "html":m.html(e.content);F();break;case "inline":b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",function(){b(this).replaceWith(i.children())}).bind("fancybox-cancel",function(){b(this).replaceWith(m.children())});b(a).appendTo(m);F();break;case "image":h=false;b.fancybox.showActivity();
s=new Image;s.onerror=function(){P()};s.onload=function(){s.onerror=null;s.onload=null;Z()};s.src=d;break;case "swf":t='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+d+'"></param>';w="";b.each(e.swf,function(r,R){t+='<param name="'+r+'" value="'+R+'"></param>';w+=" "+r+'="'+R+'"'});t+='<embed src="'+d+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+w+"></embed></object>";m.html(t);
F();break;case "ajax":a=d.split("#",2);f=e.ajax.data||{};if(a.length>1){d=a[0];if(typeof f=="string")f+="&selector="+a[1];else f.selector=a[1]}h=false;b.fancybox.showActivity();E=b.ajax(b.extend(e.ajax,{url:d,data:f,error:P,success:function(r){if(E.status==200){m.html(r);F()}}}));break;case "iframe":b('<iframe id="fancybox-frame" name="fancybox-frame'+(new Date).getTime()+'" frameborder="0" hspace="0" scrolling="'+e.scrolling+'" src="'+e.href+'"></iframe>').appendTo(m);N();break}},$=function(){if(u.is(":visible")){b("div",
u).css("top",I*-40+"px");I=(I+1)%12}else clearInterval(H)},aa=function(){if(!b("#fancybox-wrap").length){b("body").append(m=b('<div id="fancybox-tmp"></div>'),u=b('<div id="fancybox-loading"><div></div></div>'),x=b('<div id="fancybox-overlay"></div>'),g=b('<div id="fancybox-wrap"></div>'));if(!b.support.opacity){g.addClass("fancybox-ie");u.addClass("fancybox-ie")}D=b('<div id="fancybox-outer"></div>').append('<div class="fancy-bg" id="fancy-bg-n"></div><div class="fancy-bg" id="fancy-bg-ne"></div><div class="fancy-bg" id="fancy-bg-e"></div><div class="fancy-bg" id="fancy-bg-se"></div><div class="fancy-bg" id="fancy-bg-s"></div><div class="fancy-bg" id="fancy-bg-sw"></div><div class="fancy-bg" id="fancy-bg-w"></div><div class="fancy-bg" id="fancy-bg-nw"></div>').appendTo(g);
D.append(i=b('<div id="fancybox-inner"></div>'),z=b('<a id="fancybox-close"></a>'),A=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),B=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));z.click(b.fancybox.close);u.click(b.fancybox.cancel);A.click(function(a){a.preventDefault();b.fancybox.prev()});B.click(function(a){a.preventDefault();b.fancybox.next()});if(O){x.get(0).style.setExpression("height",
"document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'");u.get(0).style.setExpression("top","(-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px'");D.prepend('<iframe id="fancybox-hide-sel-frame" src="javascript:\'\';" scrolling="no" frameborder="0" ></iframe>')}}};
b.fn.fancybox=function(a){b(this).data("fancybox",b.extend({},a,b.metadata?b(this).metadata():{})).unbind("click.fb").bind("click.fb",function(d){d.preventDefault();if(!h){h=true;b(this).blur();q=[];p=0;d=b(this).attr("rel")||"";if(!d||d==""||d==="nofollow")q.push(this);else{q=b("a[rel="+d+"], area[rel="+d+"]");p=q.index(this)}C();return false}});return this};b.fancybox=function(a,d){if(!h){h=true;d=typeof d!=="undefined"?d:{};q=[];p=d.index||0;if(b.isArray(a)){for(var f=0,o=a.length;f<o;f++)if(typeof a[f]==
"object")b(a[f]).data("fancybox",b.extend({},d,a[f]));else a[f]=b({}).data("fancybox",b.extend({content:a[f]},d));q=jQuery.merge(q,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},d,a));else a=b({}).data("fancybox",b.extend({content:a},d));q.push(a)}if(p>q.length||p<0)p=0;C()}};b.fancybox.showActivity=function(){clearInterval(H);u.show();H=setInterval($,66)};b.fancybox.hideActivity=function(){u.hide()};b.fancybox.next=function(){return b.fancybox.pos(n+1)};b.fancybox.prev=function(){return b.fancybox.pos(n-
1)};b.fancybox.pos=function(a){if(!h){a=parseInt(a,10);if(a>-1&&j.length>a){p=a;C()}if(c.cyclic&&j.length>1&&a<0){p=j.length-1;C()}if(c.cyclic&&j.length>1&&a>=j.length){p=0;C()}}};b.fancybox.cancel=function(){if(!h){h=true;b.event.trigger("fancybox-cancel");J();e&&b.isFunction(e.onCancel)&&e.onCancel(q,p,e);h=false}};b.fancybox.close=function(){function a(){x.fadeOut("fast");g.hide();b.event.trigger("fancybox-cleanup");i.empty();b.isFunction(c.onClosed)&&c.onClosed(j,n,c);j=e=[];n=p=0;c=e={};h=false}
if(!(h||g.is(":hidden"))){h=true;if(c&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){h=false;return}J();b(z.add(A).add(B)).hide();b("#fancybox-title").remove();g.add(i).add(x).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");i.css("overflow","hidden");if(c.transitionOut=="elastic"){k=Q();var d=g.position();l={top:d.top,left:d.left,width:g.width(),height:g.height()};if(c.opacity)l.opacity=1;y.prop=1;b(y).animate({prop:0},{duration:c.speedOut,easing:c.easingOut,
step:M,complete:a})}else g.fadeOut(c.transitionOut=="none"?0:c.speedOut,a)}};b.fancybox.resize=function(){var a,d;if(!(h||g.is(":hidden"))){h=true;a=i.wrapInner("<div style='overflow:auto'></div>").children();d=a.height();g.css({height:d+c.padding*2+v});i.css({height:d});a.replaceWith(a.children());b.fancybox.center()}};b.fancybox.center=function(){h=true;var a=K(),d=c.margin,f={};f.top=a[3]+(a[1]-(g.height()-v+40))*0.5;f.left=a[2]+(a[0]-(g.width()+40))*0.5;f.top=Math.max(a[3]+d,f.top);f.left=Math.max(a[2]+
d,f.left);g.css(f);h=false};b.fn.fancybox.defaults={padding:10,margin:20,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.3,overlayColor:"#666",titleShow:true,titlePosition:"outside",titleFormat:null,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",
easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,onStart:null,onCancel:null,onComplete:null,onCleanup:null,onClosed:null};b(document).ready(function(){aa()})})(jQuery);



/*
* Begin File: "js/jquery.jcarousel.min.js"
*/

/*!
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 *
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */

(function($){$.fn.jcarousel=function(o){if(typeof o=='string'){var instance=$(this).data('jcarousel'),args=Array.prototype.slice.call(arguments,1);return instance[o].apply(instance,args);}else
return this.each(function(){$(this).data('jcarousel',new $jc(this,o));});};var defaults={vertical:false,start:1,offset:1,size:null,scroll:3,visible:null,animation:'normal',easing:'swing',auto:0,wrap:null,initCallback:null,reloadCallback:null,itemLoadCallback:null,itemFirstInCallback:null,itemFirstOutCallback:null,itemLastInCallback:null,itemLastOutCallback:null,itemVisibleInCallback:null,itemVisibleOutCallback:null,buttonNextHTML:'<div></div>',buttonPrevHTML:'<div></div>',buttonNextEvent:'click',buttonPrevEvent:'click',buttonNextCallback:null,buttonPrevCallback:null};$.jcarousel=function(e,o){this.options=$.extend({},defaults,o||{});this.locked=false;this.container=null;this.clip=null;this.list=null;this.buttonNext=null;this.buttonPrev=null;this.wh=!this.options.vertical?'width':'height';this.lt=!this.options.vertical?'left':'top';var skin='',split=e.className.split(' ');for(var i=0;i<split.length;i++){if(split[i].indexOf('jcarousel-skin')!=-1){$(e).removeClass(split[i]);skin=split[i];break;}}if(e.nodeName=='UL'||e.nodeName=='OL'){this.list=$(e);this.container=this.list.parent();if(this.container.hasClass('jcarousel-clip')){if(!this.container.parent().hasClass('jcarousel-container'))this.container=this.container.wrap('<div></div>');this.container=this.container.parent();}else if(!this.container.hasClass('jcarousel-container'))this.container=this.list.wrap('<div></div>').parent();}else{this.container=$(e);this.list=this.container.find('ul,ol').eq(0);}if(skin!=''&&this.container.parent()[0].className.indexOf('jcarousel-skin')==-1)this.container.wrap('<div class=" '+skin+'"></div>');this.clip=this.list.parent();if(!this.clip.length||!this.clip.hasClass('jcarousel-clip'))this.clip=this.list.wrap('<div></div>').parent();this.buttonNext=$('.jcarousel-next',this.container);if(this.buttonNext.size()==0&&this.options.buttonNextHTML!=null)this.buttonNext=this.clip.after(this.options.buttonNextHTML).next();this.buttonNext.addClass(this.className('jcarousel-next'));this.buttonPrev=$('.jcarousel-prev',this.container);if(this.buttonPrev.size()==0&&this.options.buttonPrevHTML!=null)this.buttonPrev=this.clip.after(this.options.buttonPrevHTML).next();this.buttonPrev.addClass(this.className('jcarousel-prev'));this.clip.addClass(this.className('jcarousel-clip')).css({overflow:'hidden',position:'relative'});this.list.addClass(this.className('jcarousel-list')).css({overflow:'hidden',position:'relative',top:0,left:0,margin:0,padding:0});this.container.addClass(this.className('jcarousel-container')).css({position:'relative'});var di=this.options.visible!=null?Math.ceil(this.clipping()/this.options.visible):null;var li=this.list.children('li');var self=this;if(li.size()>0){var wh=0,i=this.options.offset;li.each(function(){self.format(this,i++);wh+=self.dimension(this,di);});this.list.css(this.wh,wh+'px');if(!o||o.size===undefined)this.options.size=li.size();}this.container.css('display','block');this.buttonNext.css('display','block');this.buttonPrev.css('display','block');this.funcNext=function(){self.next();};this.funcPrev=function(){self.prev();};this.funcResize=function(){self.reload();};if(this.options.initCallback!=null)this.options.initCallback(this,'init');if($.browser.safari){this.buttons(false,false);$(window).bind('load.jcarousel',function(){self.setup();});}else
this.setup();};var $jc=$.jcarousel;$jc.fn=$jc.prototype={jcarousel:'0.2.4'};$jc.fn.extend=$jc.extend=$.extend;$jc.fn.extend({setup:function(){this.first=null;this.last=null;this.prevFirst=null;this.prevLast=null;this.animating=false;this.timer=null;this.tail=null;this.inTail=false;if(this.locked)return;this.list.css(this.lt,this.pos(this.options.offset)+'px');var p=this.pos(this.options.start);this.prevFirst=this.prevLast=null;this.animate(p,false);$(window).unbind('resize.jcarousel',this.funcResize).bind('resize.jcarousel',this.funcResize);},reset:function(){this.list.empty();this.list.css(this.lt,'0px');this.list.css(this.wh,'10px');if(this.options.initCallback!=null)this.options.initCallback(this,'reset');this.setup();},reload:function(){if(this.tail!=null&&this.inTail)this.list.css(this.lt,$jc.intval(this.list.css(this.lt))+this.tail);this.tail=null;this.inTail=false;if(this.options.reloadCallback!=null)this.options.reloadCallback(this);if(this.options.visible!=null){var self=this;var di=Math.ceil(this.clipping()/this.options.visible),wh=0,lt=0;$('li',this.list).each(function(i){wh+=self.dimension(this,di);if(i+1<self.first)lt=wh;});this.list.css(this.wh,wh+'px');this.list.css(this.lt,-lt+'px');}this.scroll(this.first,false);},lock:function(){this.locked=true;this.buttons();},unlock:function(){this.locked=false;this.buttons();},size:function(s){if(s!=undefined){this.options.size=s;if(!this.locked)this.buttons();}return this.options.size;},has:function(i,i2){if(i2==undefined||!i2)i2=i;if(this.options.size!==null&&i2>this.options.size)i2=this.options.size;for(var j=i;j<=i2;j++){var e=this.get(j);if(!e.length||e.hasClass('jcarousel-item-placeholder'))return false;}return true;},get:function(i){return $('.jcarousel-item-'+i,this.list);},add:function(i,s){var e=this.get(i),old=0,add=0;if(e.length==0){var c,e=this.create(i),j=$jc.intval(i);while(c=this.get(--j)){if(j<=0||c.length){j<=0?this.list.prepend(e):c.after(e);break;}}}else
old=this.dimension(e);e.removeClass(this.className('jcarousel-item-placeholder'));typeof s=='string'?e.html(s):e.empty().append(s);var di=this.options.visible!=null?Math.ceil(this.clipping()/this.options.visible):null;var wh=this.dimension(e,di)-old;if(i>0&&i<this.first)this.list.css(this.lt,$jc.intval(this.list.css(this.lt))-wh+'px');this.list.css(this.wh,$jc.intval(this.list.css(this.wh))+wh+'px');return e;},remove:function(i){var e=this.get(i);if(!e.length||(i>=this.first&&i<=this.last))return;var d=this.dimension(e);if(i<this.first)this.list.css(this.lt,$jc.intval(this.list.css(this.lt))+d+'px');e.remove();this.list.css(this.wh,$jc.intval(this.list.css(this.wh))-d+'px');},next:function(){this.stopAuto();if(this.tail!=null&&!this.inTail)this.scrollTail(false);else
this.scroll(((this.options.wrap=='both'||this.options.wrap=='last')&&this.options.size!=null&&this.last==this.options.size)?1:this.first+this.options.scroll);},prev:function(){this.stopAuto();if(this.tail!=null&&this.inTail)this.scrollTail(true);else
this.scroll(((this.options.wrap=='both'||this.options.wrap=='first')&&this.options.size!=null&&this.first==1)?this.options.size:this.first-this.options.scroll);},scrollTail:function(b){if(this.locked||this.animating||!this.tail)return;var pos=$jc.intval(this.list.css(this.lt));!b?pos-=this.tail:pos+=this.tail;this.inTail=!b;this.prevFirst=this.first;this.prevLast=this.last;this.animate(pos);},scroll:function(i,a){if(this.locked||this.animating)return;this.animate(this.pos(i),a);},pos:function(i){var pos=$jc.intval(this.list.css(this.lt));if(this.locked||this.animating)return pos;if(this.options.wrap!='circular')i=i<1?1:(this.options.size&&i>this.options.size?this.options.size:i);var back=this.first>i;var f=this.options.wrap!='circular'&&this.first<=1?1:this.first;var c=back?this.get(f):this.get(this.last);var j=back?f:f-1;var e=null,l=0,p=false,d=0,g;while(back?--j>=i:++j<i){e=this.get(j);p=!e.length;if(e.length==0){e=this.create(j).addClass(this.className('jcarousel-item-placeholder'));c[back?'before':'after'](e);if(this.first!=null&&this.options.wrap=='circular'&&this.options.size!==null&&(j<=0||j>this.options.size)){g=this.get(this.index(j));if(g.length)this.add(j,g.children().clone(true));}}c=e;d=this.dimension(e);if(p)l+=d;if(this.first!=null&&(this.options.wrap=='circular'||(j>=1&&(this.options.size==null||j<=this.options.size))))pos=back?pos+d:pos-d;}var clipping=this.clipping();var cache=[];var visible=0,j=i,v=0;var c=this.get(i-1);while(++visible){e=this.get(j);p=!e.length;if(e.length==0){e=this.create(j).addClass(this.className('jcarousel-item-placeholder'));c.length==0?this.list.prepend(e):c[back?'before':'after'](e);if(this.first!=null&&this.options.wrap=='circular'&&this.options.size!==null&&(j<=0||j>this.options.size)){g=this.get(this.index(j));if(g.length)this.add(j,g.find('>*').clone(true));}}c=e;var d=this.dimension(e);if(d==0){alert('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');return 0;}if(this.options.wrap!='circular'&&this.options.size!==null&&j>this.options.size)cache.push(e);else if(p)l+=d;v+=d;if(v>=clipping)break;j++;}for(var x=0;x<cache.length;x++)cache[x].remove();if(l>0){this.list.css(this.wh,this.dimension(this.list)+l+'px');if(back){pos-=l;this.list.css(this.lt,$jc.intval(this.list.css(this.lt))-l+'px');}}var last=i+visible-1;if(this.options.wrap!='circular'&&this.options.size&&last>this.options.size)last=this.options.size;if(j>last){visible=0,j=last,v=0;while(++visible){var e=this.get(j--);if(!e.length)break;v+=this.dimension(e);if(v>=clipping)break;}}var first=last-visible+1;if(this.options.wrap!='circular'&&first<1)first=1;if(this.inTail&&back){pos+=this.tail;this.inTail=false;}this.tail=null;if(this.options.wrap!='circular'&&last==this.options.size&&(last-visible+1)>=1){var m=$jc.margin(this.get(last),!this.options.vertical?'marginRight':'marginBottom');if((v-m)>clipping)this.tail=v-clipping-m;}while(i-->first)pos+=this.dimension(this.get(i));this.prevFirst=this.first;this.prevLast=this.last;this.first=first;this.last=last;return pos;},animate:function(p,a){if(this.locked||this.animating)return;this.animating=true;var self=this;var scrolled=function(){self.animating=false;if(p==0)self.list.css(self.lt,0);if(self.options.wrap=='circular'||self.options.wrap=='both'||self.options.wrap=='last'||self.options.size==null||self.last<self.options.size)self.startAuto();self.buttons();self.notify('onAfterAnimation');};this.notify('onBeforeAnimation');if(!this.options.animation||a==false){this.list.css(this.lt,p+'px');scrolled();}else{var o=!this.options.vertical?{'left':p}:{'top':p};this.list.animate(o,this.options.animation,this.options.easing,scrolled);}},startAuto:function(s){if(s!=undefined)this.options.auto=s;if(this.options.auto==0)return this.stopAuto();if(this.timer!=null)return;var self=this;this.timer=setTimeout(function(){self.next();},this.options.auto*1000);},stopAuto:function(){if(this.timer==null)return;clearTimeout(this.timer);this.timer=null;},buttons:function(n,p){if(n==undefined||n==null){var n=!this.locked&&this.options.size!==0&&((this.options.wrap&&this.options.wrap!='first')||this.options.size==null||this.last<this.options.size);if(!this.locked&&(!this.options.wrap||this.options.wrap=='first')&&this.options.size!=null&&this.last>=this.options.size)n=this.tail!=null&&!this.inTail;}if(p==undefined||p==null){var p=!this.locked&&this.options.size!==0&&((this.options.wrap&&this.options.wrap!='last')||this.first>1);if(!this.locked&&(!this.options.wrap||this.options.wrap=='last')&&this.options.size!=null&&this.first==1)p=this.tail!=null&&this.inTail;}var self=this;this.buttonNext[n?'bind':'unbind'](this.options.buttonNextEvent+'.jcarousel',this.funcNext)[n?'removeClass':'addClass'](this.className('jcarousel-next-disabled')).attr('disabled',n?false:true);this.buttonPrev[p?'bind':'unbind'](this.options.buttonPrevEvent+'.jcarousel',this.funcPrev)[p?'removeClass':'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled',p?false:true);if(this.buttonNext.length>0&&(this.buttonNext[0].jcarouselstate==undefined||this.buttonNext[0].jcarouselstate!=n)&&this.options.buttonNextCallback!=null){this.buttonNext.each(function(){self.options.buttonNextCallback(self,this,n);});this.buttonNext[0].jcarouselstate=n;}if(this.buttonPrev.length>0&&(this.buttonPrev[0].jcarouselstate==undefined||this.buttonPrev[0].jcarouselstate!=p)&&this.options.buttonPrevCallback!=null){this.buttonPrev.each(function(){self.options.buttonPrevCallback(self,this,p);});this.buttonPrev[0].jcarouselstate=p;}},notify:function(evt){var state=this.prevFirst==null?'init':(this.prevFirst<this.first?'next':'prev');this.callback('itemLoadCallback',evt,state);if(this.prevFirst!==this.first){this.callback('itemFirstInCallback',evt,state,this.first);this.callback('itemFirstOutCallback',evt,state,this.prevFirst);}if(this.prevLast!==this.last){this.callback('itemLastInCallback',evt,state,this.last);this.callback('itemLastOutCallback',evt,state,this.prevLast);}this.callback('itemVisibleInCallback',evt,state,this.first,this.last,this.prevFirst,this.prevLast);this.callback('itemVisibleOutCallback',evt,state,this.prevFirst,this.prevLast,this.first,this.last);},callback:function(cb,evt,state,i1,i2,i3,i4){if(this.options[cb]==undefined||(typeof this.options[cb]!='object'&&evt!='onAfterAnimation'))return;var callback=typeof this.options[cb]=='object'?this.options[cb][evt]:this.options[cb];if(!$.isFunction(callback))return;var self=this;if(i1===undefined)callback(self,state,evt);else if(i2===undefined)this.get(i1).each(function(){callback(self,this,i1,state,evt);});else{for(var i=i1;i<=i2;i++)if(i!==null&&!(i>=i3&&i<=i4))this.get(i).each(function(){callback(self,this,i,state,evt);});}},create:function(i){return this.format('<li></li>',i);},format:function(e,i){var $e=$(e).addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-'+i)).css({'float':'left','list-style':'none'});$e.attr('jcarouselindex',i);return $e;},className:function(c){return c+' '+c+(!this.options.vertical?'-horizontal':'-vertical');},dimension:function(e,d){var el=e.jquery!=undefined?e[0]:e;var old=!this.options.vertical?el.offsetWidth+$jc.margin(el,'marginLeft')+$jc.margin(el,'marginRight'):el.offsetHeight+$jc.margin(el,'marginTop')+$jc.margin(el,'marginBottom');if(d==undefined||old==d)return old;var w=!this.options.vertical?d-$jc.margin(el,'marginLeft')-$jc.margin(el,'marginRight'):d-$jc.margin(el,'marginTop')-$jc.margin(el,'marginBottom');$(el).css(this.wh,w+'px');return this.dimension(el);},clipping:function(){return!this.options.vertical?this.clip[0].offsetWidth-$jc.intval(this.clip.css('borderLeftWidth'))-$jc.intval(this.clip.css('borderRightWidth')):this.clip[0].offsetHeight-$jc.intval(this.clip.css('borderTopWidth'))-$jc.intval(this.clip.css('borderBottomWidth'));},index:function(i,s){if(s==undefined)s=this.options.size;return Math.round((((i-1)/s)-Math.floor((i-1)/s))*s)+1;}});$jc.extend({defaults:function(d){return $.extend(defaults,d||{});},margin:function(e,p){if(!e)return 0;var el=e.jquery!=undefined?e[0]:e;if(p=='marginRight'&&$.browser.safari){var old={'display':'block','float':'none','width':'auto'},oWidth,oWidth2;$.swap(el,old,function(){oWidth=el.offsetWidth;});old['marginRight']=0;$.swap(el,old,function(){oWidth2=el.offsetWidth;});return oWidth2-oWidth;}return $jc.intval($.css(el,p));},intval:function(v){v=parseInt(v);return isNaN(v)?0:v;}});})(jQuery);




/*
* Begin File: "js/fadeslideshow.js"
*/

/* Ultimate Fade-in slideshow (v2.1)
* Last updated: Sept 10th, 2009. This notice must stay intact for usage 
* Author: Dynamic Drive at http://www.dynamicdrive.com/
* Visit http://www.dynamicdrive.com/ for full source code
*/

//Oct 6th, 09' (v2.1): Adds option to randomize display order of images, via new option displaymode.randomize

var fadeSlideShow_descpanel={
	controls: [['images/fadeslideshow/x.png',7,7], ['images/fadeslideshow/restore.png',10,11], ['images/fadeslideshow/loading.gif',54,55]], //full URL and dimensions of close, restore, and loading images
	fontStyle: 'normal 11px Verdana', //font style for text descriptions
	slidespeed: 200 //speed of description panel animation (in millisec)
}

//No need to edit beyond here...

jQuery.noConflict()

function fadeSlideShow(settingarg){
	this.setting=settingarg
	settingarg=null
	var setting=this.setting
	setting.fadeduration=setting.fadeduration? parseInt(setting.fadeduration) : 500
	setting.curimage=(setting.persist)? fadeSlideShow.routines.getCookie("gallery-"+setting.wrapperid) : 0
	setting.curimage=setting.curimage || 0 //account for curimage being null if cookie is empty
	setting.currentstep=0 //keep track of # of slides slideshow has gone through (applicable in displaymode='auto' only)
	setting.totalsteps=setting.imagearray.length*(setting.displaymode.cycles>0? setting.displaymode.cycles : Infinity) //Total steps limit (applicable in displaymode='auto' only w/ cycles>0)
	setting.fglayer=0, setting.bglayer=1 //index of active and background layer (switches after each change of slide)
	setting.oninit=setting.oninit || function(){}
	setting.onslide=setting.onslide || function(){}
	if (setting.displaymode.randomize) //randomly shuffle order of images?
		setting.imagearray.sort(function() {return 0.5 - Math.random()})
	var preloadimages=[] //preload images
	setting.longestdesc="" //get longest description of all slides. If no desciptions defined, variable contains ""
	for (var i=0; i<setting.imagearray.length; i++){ //preload images
		preloadimages[i]=new Image()
		preloadimages[i].src=setting.imagearray[i][0]
		if (setting.imagearray[i][3] && setting.imagearray[i][3].length>setting.longestdesc.length)
			setting.longestdesc=setting.imagearray[i][3]
	}
	var closebutt=fadeSlideShow_descpanel.controls[0] //add close button to "desc" panel if descreveal="always"
	setting.closebutton=(setting.descreveal=="always")? '<img class="close" src="'+closebutt[0]+'" style="float:right;cursor:hand;cursor:pointer;width:'+closebutt[1]+'px;height:'+closebutt[2]+'px;margin-left:2px" title="Hide Description" />' : ''
	var slideshow=this
	jQuery(document).ready(function($){ //fire on DOM ready
		var setting=slideshow.setting
		var fullhtml=fadeSlideShow.routines.getFullHTML(setting.imagearray) //get full HTML of entire slideshow
		setting.$wrapperdiv=$('#'+setting.wrapperid).css({position:'relative', visibility:'visible', background:'black', overflow:'hidden', width:setting.dimensions[0], height:setting.dimensions[1]}).empty() //main slideshow DIV
		if (setting.$wrapperdiv.length==0){ //if no wrapper DIV found
			alert("Error: DIV with ID \""+setting.wrapperid+"\" not found on page.")
			return
		}
		setting.$gallerylayers=$('<div class="gallerylayer"></div><div class="gallerylayer"></div>') //two stacked DIVs to display the actual slide 
			.css({position:'absolute', left:0, top:0, width:'100%', height:'100%', background:'black'})
			.appendTo(setting.$wrapperdiv)
		var $loadingimg=$('<img src="'+fadeSlideShow_descpanel.controls[2][0]+'" style="position:absolute;width:'+fadeSlideShow_descpanel.controls[2][1]+';height:'+fadeSlideShow_descpanel.controls[2][2]+'" />')
			.css({left:setting.dimensions[0]/2-fadeSlideShow_descpanel.controls[2][1]/2, top:setting.dimensions[1]/2-fadeSlideShow_descpanel.controls[2][2]}) //center loading gif
			.appendTo(setting.$wrapperdiv)
		var $curimage=setting.$gallerylayers.html(fullhtml).find('img').hide().eq(setting.curimage) //prefill both layers with entire slideshow content, hide all images, and return current image
		if (setting.longestdesc!=""){ //if at least one slide contains a description (feature is enabled)
			fadeSlideShow.routines.adddescpanel($, setting)
			if (setting.descreveal=="always"){ //position desc panel so it's visible to begin with
				setting.$descpanel.css({top:setting.dimensions[1]-setting.panelheight})
				setting.$descinner.click(function(e){ //asign click behavior to "close" icon
					if (e.target.className=="close"){
						slideshow.showhidedescpanel('hide')
					}
				})
				setting.$restorebutton.click(function(e){ //asign click behavior to "restore" icon
					slideshow.showhidedescpanel('show')
					$(this).css({visibility:'hidden'})
				})
			}
			else{ //display desc panel on demand (mouseover)
				setting.$wrapperdiv.bind('mouseenter', function(){slideshow.showhidedescpanel('show')})
				setting.$wrapperdiv.bind('mouseleave', function(){slideshow.showhidedescpanel('hide')})
			}
		}
		setting.$wrapperdiv.bind('mouseenter', function(){setting.ismouseover=true}) //pause slideshow mouseover
		setting.$wrapperdiv.bind('mouseleave', function(){setting.ismouseover=false})
		if ($curimage.get(0).complete){ //accounf for IE not firing image.onload
			$loadingimg.hide()
			slideshow.paginateinit($)
			slideshow.showslide(setting.curimage)
		}
		else{ //initialize slideshow when first image has fully loaded
			$loadingimg.hide()
			slideshow.paginateinit($)
			$curimage.bind('load', function(){slideshow.showslide(setting.curimage)})
		}
		setting.oninit.call(slideshow) //trigger oninit() event
		$(window).bind('unload', function(){ //clean up and persist
			if (slideshow.setting.persist) //remember last shown image's index
				fadeSlideShow.routines.setCookie("gallery-"+setting.wrapperid, setting.curimage)
			jQuery.each(slideshow.setting, function(k){
				if (slideshow.setting[k] instanceof Array){
					for (var i=0; i<slideshow.setting[k].length; i++){
						if (slideshow.setting[k][i].tagName=="DIV") //catches 2 gallerylayer divs, gallerystatus div
							slideshow.setting[k][i].innerHTML=null
						slideshow.setting[k][i]=null
					}
				}
			})
			slideshow=slideshow.setting=null
		})
	})
}

fadeSlideShow.prototype={

	navigate:function(keyword){
		var setting=this.setting
		clearTimeout(setting.playtimer)
		if (setting.displaymode.type=="auto"){ //in auto mode
			setting.displaymode.type="manual" //switch to "manual" mode when nav buttons are clicked on
			setting.displaymode.wraparound=true //set wraparound option to true
		}
		if (!isNaN(parseInt(keyword))){ //go to specific slide?
			this.showslide(parseInt(keyword))
		}
		else if (/(prev)|(next)/i.test(keyword)){ //go back or forth inside slide?
			this.showslide(keyword.toLowerCase())
		}
	},

	showslide:function(keyword){
		var slideshow=this
		var setting=slideshow.setting
		if (setting.displaymode.type=="auto" && setting.ismouseover && setting.currentstep<=setting.totalsteps){ //if slideshow in autoplay mode and mouse is over it, pause it
			setting.playtimer=setTimeout(function(){slideshow.showslide('next')}, setting.displaymode.pause)
			return
		}
		var totalimages=setting.imagearray.length
		var imgindex=(keyword=="next")? (setting.curimage<totalimages-1? setting.curimage+1 : 0)
			: (keyword=="prev")? (setting.curimage>0? setting.curimage-1 : totalimages-1)
			: Math.min(keyword, totalimages-1)
		var $slideimage=setting.$gallerylayers.eq(setting.bglayer).find('img').hide().eq(imgindex).show() //hide all images except current one
		var imgdimensions=[$slideimage.width(), $slideimage.height()] //center align image
		$slideimage.css({marginLeft: (imgdimensions[0]>0 && imgdimensions[0]<setting.dimensions[0])? setting.dimensions[0]/2-imgdimensions[0]/2 : 0})
		$slideimage.css({marginTop: (imgdimensions[1]>0 && imgdimensions[1]<setting.dimensions[1])? setting.dimensions[1]/2-imgdimensions[1]/2 : 0})
		setting.$gallerylayers.eq(setting.bglayer).css({zIndex:1000, opacity:0}) //background layer becomes foreground
			.stop().css({opacity:0}).animate({opacity:1}, setting.fadeduration, function(){ //Callback function after fade animation is complete:
				clearTimeout(setting.playtimer)
				try{
					setting.onslide.call(slideshow, setting.$gallerylayers.eq(setting.fglayer).get(0), setting.curimage)
				}catch(e){
					alert("Fade In Slideshow error: An error has occured somwhere in your code attached to the \"onslide\" event: "+e)
				}
				setting.currentstep+=1
				if (setting.displaymode.type=="auto"){
					if (setting.currentstep<=setting.totalsteps || setting.displaymode.cycles==0)
						setting.playtimer=setTimeout(function(){slideshow.showslide('next')}, setting.displaymode.pause)
				}
			}) //end callback function
		setting.$gallerylayers.eq(setting.fglayer).css({zIndex:999}) //foreground layer becomes background
		setting.fglayer=setting.bglayer
		setting.bglayer=(setting.bglayer==0)? 1 : 0
		setting.curimage=imgindex
		if (setting.$descpanel)
			setting.$descpanel.css({visibility:(setting.imagearray[imgindex][3])? 'visible' : 'hidden'})
		if (setting.imagearray[imgindex][3])
			setting.$descinner.empty().html(setting.closebutton + setting.imagearray[imgindex][3])
		if (setting.displaymode.type=="manual" && !setting.displaymode.wraparound){
			this.paginatecontrol()
		}
		if (setting.$status) //if status container defined
			setting.$status.html(setting.curimage+1 + "/" + totalimages)
	},

	showhidedescpanel:function(state, showcontrol){
		var setting=this.setting
		var endpoint=(state=="show")? setting.dimensions[1]-setting.panelheight : this.setting.dimensions[1]
		setting.$descpanel.stop().animate({top:endpoint}, fadeSlideShow_descpanel.slidespeed, function(){
			if (setting.descreveal=="always" && state=="hide")
				setting.$restorebutton.css({visibility:'visible'}) //show restore button
		})
	},

	paginateinit:function($){
		var slideshow=this
		var setting=this.setting
		if (setting.togglerid){ //if toggler div defined
			setting.$togglerdiv=$("#"+setting.togglerid)
			setting.$prev=setting.$togglerdiv.find('.prev').data('action', 'prev')
			setting.$next=setting.$togglerdiv.find('.next').data('action', 'next')
			setting.$prev.add(setting.$next).click(function(e){ //assign click behavior to prev and next controls
				var $target=$(this)
				slideshow.navigate($target.data('action'))
				e.preventDefault()
			})
			setting.$status=setting.$togglerdiv.find('.status')
		}
	},

	paginatecontrol:function(){
		var setting=this.setting
			setting.$prev.css({opacity:(setting.curimage==0)? 0.4 : 1}).data('action', (setting.curimage==0)? 'none' : 'prev')
			setting.$next.css({opacity:(setting.curimage==setting.imagearray.length-1)? 0.4 : 1}).data('action', (setting.curimage==setting.imagearray.length-1)? 'none' : 'next')
			if (document.documentMode==8){ //in IE8 standards mode, apply opacity to inner image of link
				setting.$prev.find('img:eq(0)').css({opacity:(setting.curimage==0)? 0.4 : 1})
				setting.$next.find('img:eq(0)').css({opacity:(setting.curimage==setting.imagearray.length-1)? 0.4 : 1})
			}
	}

	
}

fadeSlideShow.routines={

	getSlideHTML:function(imgelement){
		var layerHTML=(imgelement[1])? '<a href="'+imgelement[1]+'" target="'+imgelement[2]+'">\n' : '' //hyperlink slide?
		layerHTML+='<img src="'+imgelement[0]+'" style="border-width:0;" />\n'
		layerHTML+=(imgelement[1])? '</a>\n' : ''
		return layerHTML //return HTML for this layer
	},

	getFullHTML:function(imagearray){
		var preloadhtml=''
		for (var i=0; i<imagearray.length; i++)
			preloadhtml+=this.getSlideHTML(imagearray[i])
		return preloadhtml
	},

	adddescpanel:function($, setting){
		setting.$descpanel=$('<div class="fadeslidedescdiv"></div>')
			.css({position:'absolute', visibility:'hidden', width:'100%', left:0, top:setting.dimensions[1], font:fadeSlideShow_descpanel.fontStyle, zIndex:'1001'})
			.appendTo(setting.$wrapperdiv)
		$('<div class="descpanelbg"></div><div class="descpanelfg"></div>') //create inner nav panel DIVs
			.css({position:'absolute', left:0, top:0, width:setting.$descpanel.width()-8, padding:'4px'})
			.eq(0).css({background:'black', opacity:0.7}).end() //"descpanelbg" div
			.eq(1).css({color:'white'}).html(setting.closebutton + setting.longestdesc).end() //"descpanelfg" div
			.appendTo(setting.$descpanel)
		setting.$descinner=setting.$descpanel.find('div.descpanelfg')
		setting.panelheight=setting.$descinner.outerHeight()
		setting.$descpanel.css({height:setting.panelheight}).find('div').css({height:'100%'})
		if (setting.descreveal=="always"){ //create restore button
			setting.$restorebutton=$('<img class="restore" title="Restore Description" src="' + fadeSlideShow_descpanel.controls[1][0] +'" style="position:absolute;visibility:hidden;right:0;bottom:0;z-index:1002;width:'+fadeSlideShow_descpanel.controls[1][1]+'px;height:'+fadeSlideShow_descpanel.controls[1][2]+'px;cursor:pointer;cursor:hand" />')
				.appendTo(setting.$wrapperdiv)


		}
	},


	getCookie:function(Name){ 
		var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
		if (document.cookie.match(re)) //if cookie found
			return document.cookie.match(re)[0].split("=")[1] //return its value
		return null
	},

	setCookie:function(name, value){
		document.cookie = name+"=" + value + ";path=/"
	}
}

