//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var MooTools={version:"1.12"};function $defined(a){return(a!=undefined)}function $type(b){if(!$defined(b)){return false}if(b.htmlElement){return"element"}var a=typeof b;if(a=="object"&&b.nodeName){switch(b.nodeType){case 1:return"element";case 3:return(/\S/).test(b.nodeValue)?"textnode":"whitespace"}}if(a=="object"||a=="function"){switch(b.constructor){case Array:return"array";case RegExp:return"regexp";case Class:return"class"}if(typeof b.length=="number"){if(b.item){return"collection"}if(b.callee){return"arguments"}}}return a}function $merge(){var c={};for(var b=0;b<arguments.length;b++){for(var f in arguments[b]){var a=arguments[b][f];var d=c[f];if(d&&$type(a)=="object"&&$type(d)=="object"){c[f]=$merge(d,a)}else{c[f]=a}}}return c}var $extend=function(){var a=arguments;if(!a[1]){a=[this,a[0]]}for(var b in a[1]){a[0][b]=a[1][b]}return a[0]};var $native=function(){for(var b=0,a=arguments.length;b<a;b++){arguments[b].extend=function(c){for(var d in c){if(!this.prototype[d]){this.prototype[d]=c[d]}if(!this[d]){this[d]=$native.generic(d)}}}}};$native.generic=function(a){return function(b){return this.prototype[a].apply(b,Array.prototype.slice.call(arguments,1))}};$native(Function,Array,String,Number);function $chk(a){return !!(a||a===0)}function $pick(b,a){return $defined(b)?b:a}function $random(b,a){return Math.floor(Math.random()*(a-b+1)+b)}function $time(){return new Date().getTime()}function $clear(a){clearTimeout(a);clearInterval(a);return null}var Abstract=function(a){a=a||{};a.extend=$extend;return a};var Window=new Abstract(window);var Document=new Abstract(document);document.head=document.getElementsByTagName("head")[0];window.xpath=!!(document.evaluate);if(window.ActiveXObject){window.ie=window[window.XMLHttpRequest?"ie7":"ie6"]=true}else{if(document.childNodes&&!document.all&&!navigator.taintEnabled){window.webkit=window[window.xpath?"webkit420":"webkit419"]=true}else{if(document.getBoxObjectFor!=null||window.mozInnerScreenX!=null){window.gecko=true}}}window.khtml=window.webkit;Object.extend=$extend;if(typeof HTMLElement=="undefined"){var HTMLElement=function(){};if(window.webkit){document.createElement("iframe")}HTMLElement.prototype=(window.webkit)?window["[[DOMElement.prototype]]"]:{}}HTMLElement.prototype.htmlElement=function(){};if(window.ie6){try{document.execCommand("BackgroundImageCache",false,true)}catch(e){}}var Class=function(b){var a=function(){return(arguments[0]!==null&&this.initialize&&$type(this.initialize)=="function")?this.initialize.apply(this,arguments):this};$extend(a,this);a.prototype=b;a.constructor=Class;return a};Class.empty=function(){};Class.prototype={extend:function(b){var c=new this(null);for(var d in b){var a=c[d];c[d]=Class.Merge(a,b[d])}return new Class(c)},implement:function(){for(var b=0,a=arguments.length;b<a;b++){$extend(this.prototype,arguments[b])}}};Class.Merge=function(c,d){if(c&&c!=d){var b=$type(d);if(b!=$type(c)){return d}switch(b){case"function":var a=function(){this.parent=arguments.callee.parent;return d.apply(this,arguments)};a.parent=c;return a;case"object":return $merge(c,d)}}return d};var Chain=new Class({chain:function(a){this.chains=this.chains||[];this.chains.push(a);return this},callChain:function(){if(this.chains&&this.chains.length){this.chains.shift().delay(10,this)}},clearChain:function(){this.chains=[]}});var Events=new Class({addEvent:function(b,a){if(a!=Class.empty){this.$events=this.$events||{};this.$events[b]=this.$events[b]||[];this.$events[b].include(a)}return this},fireEvent:function(c,b,a){if(this.$events&&this.$events[c]){this.$events[c].each(function(d){d.create({bind:this,delay:a,"arguments":b})()},this)}return this},removeEvent:function(b,a){if(this.$events&&this.$events[b]){this.$events[b].remove(a)}return this}});var Options=new Class({setOptions:function(){this.options=$merge.apply(null,[this.options].extend(arguments));if(this.addEvent){for(var a in this.options){if($type(this.options[a]=="function")&&(/^on[A-Z]/).test(a)){this.addEvent(a,this.options[a])}}}return this}});Array.extend({forEach:function(c,d){for(var b=0,a=this.length;b<a;b++){c.call(d,this[b],b,this)}},filter:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){if(d.call(f,this[b],b,this)){c.push(this[b])}}return c},map:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){c[b]=d.call(f,this[b],b,this)}return c},every:function(c,d){for(var b=0,a=this.length;b<a;b++){if(!c.call(d,this[b],b,this)){return false}}return true},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if(c.call(d,this[b],b,this)){return true}}return false},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b}}return -1},copy:function(d,c){d=d||0;if(d<0){d=this.length+d}c=c||(this.length-d);var a=[];for(var b=0;b<c;b++){a[b]=this[d++]}return a},remove:function(c){var b=0;var a=this.length;while(b<a){if(this[b]===c){this.splice(b,1);a--}else{b++}}return this},contains:function(a,b){return this.indexOf(a,b)!=-1},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a]}return d},extend:function(c){for(var b=0,a=c.length;b<a;b++){this.push(c[b])}return this},merge:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b])}return this},include:function(a){if(!this.contains(a)){this.push(a)}return this},getRandom:function(){return this[$random(0,this.length-1)]||null},getLast:function(){return this[this.length-1]||null}});Array.prototype.each=Array.prototype.forEach;Array.each=Array.forEach;function $A(a){return Array.copy(a)}function $each(c,b,d){if(c&&typeof c.length=="number"&&$type(c)!="object"){Array.forEach(c,b,d)}else{for(var a in c){b.call(d||c,c[a],a)}}}Array.prototype.test=Array.prototype.contains;String.extend({test:function(a,b){return(($type(a)=="string")?new RegExp(a,b):a).test(this)},toInt:function(){return parseInt(this,10)},toFloat:function(){return parseFloat(this)},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase()})},hyphenate:function(){return this.replace(/\w[A-Z]/g,function(a){return(a.charAt(0)+"-"+a.charAt(1).toLowerCase())})},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase()})},trim:function(){return this.replace(/^\s+|\s+$/g,"")},clean:function(){return this.replace(/\s{2,}/g," ").trim()},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):false},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);return(a)?a.slice(1).hexToRgb(b):false},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1},escapeRegExp:function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")}});Array.extend({rgbToHex:function(d){if(this.length<3){return false}if(this.length==4&&this[3]==0&&!d){return"transparent"}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c)}return d?b:"#"+b.join("")},hexToRgb:function(c){if(this.length!=3){return false}var a=[];for(var b=0;b<3;b++){a.push(parseInt((this[b].length==1)?this[b]+this[b]:this[b],16))}return c?a:"rgb("+a.join(",")+")"}});Function.extend({create:function(a){var b=this;a=$merge({bind:b,event:false,"arguments":null,delay:false,periodical:false,attempt:false},a);if($chk(a.arguments)&&$type(a.arguments)!="array"){a.arguments=[a.arguments]}return function(f){var c;if(a.event){f=f||window.event;c=[(a.event===true)?f:new a.event(f)];if(a.arguments){c.extend(a.arguments)}}else{c=a.arguments||arguments}var g=function(){return b.apply($pick(a.bind,b),c)};if(a.delay){return setTimeout(g,a.delay)}if(a.periodical){return setInterval(g,a.periodical)}if(a.attempt){try{return g()}catch(d){return false}}return g()}},pass:function(a,b){return this.create({"arguments":a,bind:b})},attempt:function(a,b){return this.create({"arguments":a,bind:b,attempt:true})()},bind:function(b,a){return this.create({bind:b,"arguments":a})},bindAsEventListener:function(b,a){return this.create({bind:b,event:true,"arguments":a})},delay:function(b,c,a){return this.create({delay:b,bind:c,"arguments":a})()},periodical:function(a,c,b){return this.create({periodical:a,bind:c,"arguments":b})()}});Number.extend({toInt:function(){return parseInt(this)},toFloat:function(){return parseFloat(this)},limit:function(b,a){return Math.min(a,Math.max(b,this))},round:function(a){a=Math.pow(10,a||0);return Math.round(this*a)/a},times:function(b){for(var a=0;a<this;a++){b(a)}}});var Element=new Class({initialize:function(d,c){if($type(d)=="string"){if(window.ie&&c&&(c.name||c.type)){var a=(c.name)?' name="'+c.name+'"':"";var b=(c.type)?' type="'+c.type+'"':"";delete c.name;delete c.type;d="<"+d+a+b+">"}d=document.createElement(d)}d=$(d);return(!c||!d)?d:d.set(c)}});var Elements=new Class({initialize:function(a){return(a)?$extend(a,this):this}});Elements.extend=function(a){for(var b in a){this.prototype[b]=a[b];this[b]=$native.generic(b)}};function $(b){if(!b){return null}if(b.htmlElement){return Garbage.collect(b)}if([window,document].contains(b)){return b}var a=$type(b);if(a=="string"){b=document.getElementById(b);a=(b)?"element":false}if(a!="element"){return null}if(b.htmlElement){return Garbage.collect(b)}if(["object","embed"].contains(b.tagName.toLowerCase())){return b}$extend(b,Element.prototype);b.htmlElement=function(){};return Garbage.collect(b)}document.getElementsBySelector=document.getElementsByTagName;function $$(){var d=[];for(var c=0,b=arguments.length;c<b;c++){var a=arguments[c];switch($type(a)){case"element":d.push(a);case"boolean":break;case false:break;case"string":a=document.getElementsBySelector(a,true);default:d.extend(a)}}return $$.unique(d)}$$.unique=function(j){var f=[];for(var c=0,a=j.length;c<a;c++){if(j[c].$included){continue}var b=$(j[c]);if(b&&!b.$included){b.$included=true;f.push(b)}}for(var h=0,g=f.length;h<g;h++){f[h].$included=null}return new Elements(f)};Elements.Multi=function(a){return function(){var d=arguments;var b=[];var h=true;for(var f=0,c=this.length,g;f<c;f++){g=this[f][a].apply(this[f],d);if($type(g)!="element"){h=false}b.push(g)}return(h)?$$.unique(b):b}};Element.extend=function(a){for(var b in a){HTMLElement.prototype[b]=a[b];Element.prototype[b]=a[b];Element[b]=$native.generic(b);var c=(Array.prototype[b])?b+"Elements":b;Elements.prototype[c]=Elements.Multi(b)}};Element.extend({set:function(a){for(var c in a){var b=a[c];switch(c){case"styles":this.setStyles(b);break;case"events":if(this.addEvents){this.addEvents(b)}break;case"properties":this.setProperties(b);break;default:this.setProperty(c,b)}}return this},inject:function(c,a){c=$(c);switch(a){case"before":c.parentNode.insertBefore(this,c);break;case"after":var b=c.getNext();if(!b){c.parentNode.appendChild(this)}else{c.parentNode.insertBefore(this,b)}break;case"top":var d=c.firstChild;if(d){c.insertBefore(this,d);break}default:c.appendChild(this)}return this},injectBefore:function(a){return this.inject(a,"before")},injectAfter:function(a){return this.inject(a,"after")},injectInside:function(a){return this.inject(a,"bottom")},injectTop:function(a){return this.inject(a,"top")},adopt:function(){var a=[];$each(arguments,function(b){a=a.concat(b)});$$(a).inject(this);return this},remove:function(){return this.parentNode.removeChild(this)},clone:function(c){var b=$(this.cloneNode(c!==false));if(!b.$events){return b}b.$events={};for(var a in this.$events){b.$events[a]={keys:$A(this.$events[a].keys),values:$A(this.$events[a].values)}}return b.removeEvents()},replaceWith:function(a){a=$(a);this.parentNode.replaceChild(a,this);return a},appendText:function(a){this.appendChild(document.createTextNode(a));return this},hasClass:function(a){return this.className.contains(a," ")},addClass:function(a){if(!this.hasClass(a)){this.className=(this.className+" "+a).clean()}return this},removeClass:function(a){this.className=this.className.replace(new RegExp("(^|\\s)"+a+"(?:\\s|$)"),"$1").clean();return this},toggleClass:function(a){return this.hasClass(a)?this.removeClass(a):this.addClass(a)},setStyle:function(b,a){switch(b){case"opacity":return this.setOpacity(parseFloat(a));case"float":b=(window.ie)?"styleFloat":"cssFloat"}b=b.camelCase();switch($type(a)){case"number":if(!["zIndex","zoom"].contains(b)){a+="px"}break;case"array":a="rgb("+a.join(",")+")"}this.style[b]=a;return this},setStyles:function(a){switch($type(a)){case"object":Element.setMany(this,"setStyle",a);break;case"string":this.style.cssText=a}return this},setOpacity:function(a){if(a==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden"}}else{if(this.style.visibility!="visible"){this.style.visibility="visible"}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1}if(window.ie){this.style.filter=(a==1)?"":"alpha(opacity="+a*100+")"}this.style.opacity=this.$tmp.opacity=a;return this},getStyle:function(c){c=c.camelCase();var a=this.style[c];if(!$chk(a)){if(c=="opacity"){return this.$tmp.opacity}a=[];for(var b in Element.Styles){if(c==b){Element.Styles[b].each(function(g){var f=this.getStyle(g);a.push(parseInt(f)?f:"0px")},this);if(c=="border"){var d=a.every(function(f){return(f==a[0])});return(d)?a[0]:false}return a.join(" ")}}if(c.contains("border")){if(Element.Styles.border.contains(c)){return["Width","Style","Color"].map(function(f){return this.getStyle(c+f)},this).join(" ")}else{if(Element.borderShort.contains(c)){return["Top","Right","Bottom","Left"].map(function(f){return this.getStyle("border"+f+c.replace("border",""))},this).join(" ")}}}if(document.defaultView){a=document.defaultView.getComputedStyle(this,null).getPropertyValue(c.hyphenate())}else{if(this.currentStyle){a=this.currentStyle[c]}}}if(window.ie){a=Element.fixStyle(c,a,this)}if(a&&c.test(/color/i)&&a.contains("rgb")){return a.split("rgb").splice(1,4).map(function(f){return f.rgbToHex()}).join(" ")}return a},getStyles:function(){return Element.getMany(this,"getStyle",arguments)},walk:function(a,c){a+="Sibling";var b=(c)?this[c]:this[a];while(b&&$type(b)!="element"){b=b[a]}return $(b)},getPrevious:function(){return this.walk("previous")},getNext:function(){return this.walk("next")},getFirst:function(){return this.walk("next","firstChild")},getLast:function(){return this.walk("previous","lastChild")},getParent:function(){return $(this.parentNode)},getChildren:function(){return $$(this.childNodes)},hasChild:function(a){return !!$A(this.getElementsByTagName("*")).contains(a)},getProperty:function(d){var b=Element.Properties[d];if(b){return this[b]}var a=Element.PropertiesIFlag[d]||0;if(!window.ie||a){return this.getAttribute(d,a)}var c=this.attributes[d];return(c)?c.nodeValue:null},removeProperty:function(b){var a=Element.Properties[b];if(a){this[a]=""}else{this.removeAttribute(b)}return this},getProperties:function(){return Element.getMany(this,"getProperty",arguments)},setProperty:function(c,b){var a=Element.Properties[c];if(a){this[a]=b}else{this.setAttribute(c,b)}return this},setProperties:function(a){return Element.setMany(this,"setProperty",a)},setHTML:function(){this.innerHTML=$A(arguments).join("");return this},setText:function(b){var a=this.getTag();if(["style","script"].contains(a)){if(window.ie){if(a=="style"){this.styleSheet.cssText=b}else{if(a=="script"){this.setProperty("text",b)}}return this}else{this.removeChild(this.firstChild);return this.appendText(b)}}this[$defined(this.innerText)?"innerText":"textContent"]=b;return this},getText:function(){var a=this.getTag();if(["style","script"].contains(a)){if(window.ie){if(a=="style"){return this.styleSheet.cssText}else{if(a=="script"){return this.getProperty("text")}}}else{return this.innerHTML}}return($pick(this.innerText,this.textContent))},getTag:function(){return this.tagName.toLowerCase()},empty:function(){Garbage.trash(this.getElementsByTagName("*"));return this.setHTML("")}});Element.fixStyle=function(f,a,d){if($chk(parseInt(a))){return a}if(["height","width"].contains(f)){var b=(f=="width")?["left","right"]:["top","bottom"];var c=0;b.each(function(g){c+=d.getStyle("border-"+g+"-width").toInt()+d.getStyle("padding-"+g).toInt()});return d["offset"+f.capitalize()]-c+"px"}else{if(f.test(/border(.+)Width|margin|padding/)){return"0px"}}return a};Element.Styles={border:[],padding:[],margin:[]};["Top","Right","Bottom","Left"].each(function(b){for(var a in Element.Styles){Element.Styles[a].push(a+b)}});Element.borderShort=["borderWidth","borderStyle","borderColor"];Element.getMany=function(b,d,c){var a={};$each(c,function(f){a[f]=b[d](f)});return a};Element.setMany=function(b,d,c){for(var a in c){b[d](a,c[a])}return b};Element.Properties=new Abstract({"class":"className","for":"htmlFor",colspan:"colSpan",rowspan:"rowSpan",accesskey:"accessKey",tabindex:"tabIndex",maxlength:"maxLength",readonly:"readOnly",frameborder:"frameBorder",value:"value",disabled:"disabled",checked:"checked",multiple:"multiple",selected:"selected"});Element.PropertiesIFlag={href:2,src:2};Element.Methods={Listeners:{addListener:function(b,a){if(this.addEventListener){this.addEventListener(b,a,false)}else{this.attachEvent("on"+b,a)}return this},removeListener:function(b,a){if(this.removeEventListener){this.removeEventListener(b,a,false)}else{this.detachEvent("on"+b,a)}return this}}};window.extend(Element.Methods.Listeners);document.extend(Element.Methods.Listeners);Element.extend(Element.Methods.Listeners);var Garbage={elements:[],collect:function(a){if(!a.$tmp){Garbage.elements.push(a);a.$tmp={opacity:1}}return a},trash:function(f){for(var b=0,a=f.length,c;b<a;b++){if(!(c=f[b])||!c.$tmp){continue}if(c.$events){c.fireEvent("trash").removeEvents()}for(var g in c.$tmp){c.$tmp[g]=null}for(var h in Element.prototype){c[h]=null}Garbage.elements[Garbage.elements.indexOf(c)]=null;c.htmlElement=c.$tmp=c=null}Garbage.elements.remove(null)},empty:function(){Garbage.collect(window);Garbage.collect(document);Garbage.trash(Garbage.elements)}};window.addListener("beforeunload",function(){window.addListener("unload",Garbage.empty);if(window.ie){window.addListener("unload",CollectGarbage)}});var Event=new Class({initialize:function(c){if(c&&c.$extended){return c}this.$extended=true;c=c||window.event;this.event=c;this.type=c.type;this.target=c.target||c.srcElement;if(this.target.nodeType==3){this.target=this.target.parentNode}this.shift=c.shiftKey;this.control=c.ctrlKey;this.alt=c.altKey;this.meta=c.metaKey;if(["DOMMouseScroll","mousewheel"].contains(this.type)){this.wheel=(c.wheelDelta)?c.wheelDelta/120:-(c.detail||0)/3}else{if(this.type.contains("key")){this.code=c.which||c.keyCode;for(var b in Event.keys){if(Event.keys[b]==this.code){this.key=b;break}}if(this.type=="keydown"){var a=this.code-111;if(a>0&&a<13){this.key="f"+a}}this.key=this.key||String.fromCharCode(this.code).toLowerCase()}else{if(this.type.test(/(click|mouse|menu)/)){this.page={x:c.pageX||c.clientX+document.documentElement.scrollLeft,y:c.pageY||c.clientY+document.documentElement.scrollTop};this.client={x:c.pageX?c.pageX-window.pageXOffset:c.clientX,y:c.pageY?c.pageY-window.pageYOffset:c.clientY};this.rightClick=(c.which==3)||(c.button==2);switch(this.type){case"mouseover":this.relatedTarget=c.relatedTarget||c.fromElement;break;case"mouseout":this.relatedTarget=c.relatedTarget||c.toElement}this.fixRelatedTarget()}}}return this},stop:function(){return this.stopPropagation().preventDefault()},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation()}else{this.event.cancelBubble=true}return this},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault()}else{this.event.returnValue=false}return this}});Event.fix={relatedTarget:function(){if(this.relatedTarget&&this.relatedTarget.nodeType==3){this.relatedTarget=this.relatedTarget.parentNode}},relatedTargetGecko:function(){try{Event.fix.relatedTarget.call(this)}catch(a){this.relatedTarget=this.target}}};Event.prototype.fixRelatedTarget=(window.gecko)?Event.fix.relatedTargetGecko:Event.fix.relatedTarget;Event.keys=new Abstract({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Element.Methods.Events={addEvent:function(c,b){this.$events=this.$events||{};this.$events[c]=this.$events[c]||{keys:[],values:[]};if(this.$events[c].keys.contains(b)){return this}this.$events[c].keys.push(b);var a=c;var d=Element.Events[c];if(d){if(d.add){d.add.call(this,b)}if(d.map){b=d.map}if(d.type){a=d.type}}if(!this.addEventListener){b=b.create({bind:this,event:true})}this.$events[c].values.push(b);return(Element.NativeEvents.contains(a))?this.addListener(a,b):this},removeEvent:function(c,b){if(!this.$events||!this.$events[c]){return this}var g=this.$events[c].keys.indexOf(b);if(g==-1){return this}var a=this.$events[c].keys.splice(g,1)[0];var f=this.$events[c].values.splice(g,1)[0];var d=Element.Events[c];if(d){if(d.remove){d.remove.call(this,b)}if(d.type){c=d.type}}return(Element.NativeEvents.contains(c))?this.removeListener(c,f):this},addEvents:function(a){return Element.setMany(this,"addEvent",a)},removeEvents:function(a){if(!this.$events){return this}if(!a){for(var b in this.$events){this.removeEvents(b)}this.$events=null}else{if(this.$events[a]){this.$events[a].keys.each(function(c){this.removeEvent(a,c)},this);this.$events[a]=null}}return this},fireEvent:function(c,b,a){if(this.$events&&this.$events[c]){this.$events[c].keys.each(function(d){d.create({bind:this,delay:a,"arguments":b})()},this)}return this},cloneEvents:function(c,a){if(!c.$events){return this}if(!a){for(var b in c.$events){this.cloneEvents(c,b)}}else{if(c.$events[a]){c.$events[a].keys.each(function(d){this.addEvent(a,d)},this)}}return this}};window.extend(Element.Methods.Events);document.extend(Element.Methods.Events);Element.extend(Element.Methods.Events);Element.Events=new Abstract({mouseenter:{type:"mouseover",map:function(a){a=new Event(a);if(a.relatedTarget!=this&&!this.hasChild(a.relatedTarget)){this.fireEvent("mouseenter",a)}}},mouseleave:{type:"mouseout",map:function(a){a=new Event(a);if(a.relatedTarget!=this&&!this.hasChild(a.relatedTarget)){this.fireEvent("mouseleave",a)}}},mousewheel:{type:(window.gecko)?"DOMMouseScroll":"mousewheel"}});Element.NativeEvents=["click","dblclick","mouseup","mousedown","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","keydown","keypress","keyup","load","unload","beforeunload","resize","move","focus","blur","change","submit","reset","select","error","abort","contextmenu","scroll"];Function.extend({bindWithEvent:function(b,a){return this.create({bind:b,"arguments":a,event:Event})}});Elements.extend({filterByTag:function(a){return new Elements(this.filter(function(b){return(Element.getTag(b)==a)}))},filterByClass:function(a,c){var b=this.filter(function(d){return(d.className&&d.className.contains(a," "))});return(c)?b:new Elements(b)},filterById:function(c,b){var a=this.filter(function(d){return(d.id==c)});return(b)?a:new Elements(a)},filterByAttribute:function(b,a,d,f){var c=this.filter(function(g){var h=Element.getProperty(g,b);if(!h){return false}if(!a){return true}switch(a){case"=":return(h==d);case"*=":return(h.contains(d));case"^=":return(h.substr(0,d.length)==d);case"$=":return(h.substr(h.length-d.length)==d);case"!=":return(h!=d);case"~=":return h.contains(d," ")}return false});return(f)?c:new Elements(c)}});function $E(a,b){return($(b)||document).getElement(a)}function $ES(a,b){return($(b)||document).getElementsBySelector(a)}$$.shared={regexp:/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,xpath:{getParam:function(b,d,f,c){var a=[d.namespaceURI?"xhtml:":"",f[1]];if(f[2]){a.push('[@id="',f[2],'"]')}if(f[3]){a.push('[contains(concat(" ", @class, " "), " ',f[3],' ")]')}if(f[4]){if(f[5]&&f[6]){switch(f[5]){case"*=":a.push("[contains(@",f[4],', "',f[6],'")]');break;case"^=":a.push("[starts-with(@",f[4],', "',f[6],'")]');break;case"$=":a.push("[substring(@",f[4],", string-length(@",f[4],") - ",f[6].length,' + 1) = "',f[6],'"]');break;case"=":a.push("[@",f[4],'="',f[6],'"]');break;case"!=":a.push("[@",f[4],'!="',f[6],'"]')}}else{a.push("[@",f[4],"]")}}b.push(a.join(""));return b},getItems:function(b,f,h){var g=[];var a=document.evaluate(".//"+b.join("//"),f,$$.shared.resolver,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);for(var d=0,c=a.snapshotLength;d<c;d++){g.push(a.snapshotItem(d))}return(h)?g:new Elements(g.map($))}},normal:{getParam:function(a,c,f,b){if(b==0){if(f[2]){var d=c.getElementById(f[2]);if(!d||((f[1]!="*")&&(Element.getTag(d)!=f[1]))){return false}a=[d]}else{a=$A(c.getElementsByTagName(f[1]))}}else{a=$$.shared.getElementsByTagName(a,f[1]);if(f[2]){a=Elements.filterById(a,f[2],true)}}if(f[3]){a=Elements.filterByClass(a,f[3],true)}if(f[4]){a=Elements.filterByAttribute(a,f[4],f[5],f[6],true)}return a},getItems:function(a,b,c){return(c)?a:$$.unique(a)}},resolver:function(a){return(a=="xhtml")?"http://www.w3.org/1999/xhtml":false},getElementsByTagName:function(d,c){var f=[];for(var b=0,a=d.length;b<a;b++){f.extend(d[b].getElementsByTagName(c))}return f}};$$.shared.method=(window.xpath)?"xpath":"normal";Element.Methods.Dom={getElements:function(a,k){var c=[];a=a.trim().split(" ");for(var f=0,d=a.length;f<d;f++){var g=a[f];var h=g.match($$.shared.regexp);if(!h){break}h[1]=h[1]||"*";var b=$$.shared[$$.shared.method].getParam(c,this,h,f);if(!b){break}c=b}return $$.shared[$$.shared.method].getItems(c,this,k)},getElement:function(a){return $(this.getElements(a,true)[0]||false)},getElementsBySelector:function(a,f){var d=[];a=a.split(",");for(var c=0,b=a.length;c<b;c++){d=d.concat(this.getElements(a[c],true))}return(f)?d:$$.unique(d)}};Element.extend({getElementById:function(c){var b=document.getElementById(c);if(!b){return false}for(var a=b.parentNode;a!=this;a=a.parentNode){if(!a){return false}}return b},getElementsByClassName:function(a){return this.getElements("."+a)}});document.extend(Element.Methods.Dom);Element.extend(Element.Methods.Dom);Element.extend({getValue:function(){switch(this.getTag()){case"select":var a=[];$each(this.options,function(b){if(b.selected){a.push($pick(b.value,b.text))}});return(this.multiple)?a:a[0];case"input":if(!(this.checked&&["checkbox","radio"].contains(this.type))&&!["hidden","text","password"].contains(this.type)){break}case"textarea":return this.value}return false},getFormElements:function(){return $$(this.getElementsByTagName("input"),this.getElementsByTagName("select"),this.getElementsByTagName("textarea"))},toQueryString:function(){var a=[];this.getFormElements().each(function(d){var c=d.name;var f=d.getValue();if(f===false||!c||d.disabled){return}var b=function(g){a.push(c+"="+encodeURIComponent(g))};if($type(f)=="array"){f.each(b)}else{b(f)}});return a.join("&")}});Element.extend({scrollTo:function(a,b){this.scrollLeft=a;this.scrollTop=b},getSize:function(){return{scroll:{x:this.scrollLeft,y:this.scrollTop},size:{x:this.offsetWidth,y:this.offsetHeight},scrollSize:{x:this.scrollWidth,y:this.scrollHeight}}},getPosition:function(a){a=a||[];var b=this,d=0,c=0;do{d+=b.offsetLeft||0;c+=b.offsetTop||0;b=b.offsetParent}while(b);a.each(function(f){d-=f.scrollLeft||0;c-=f.scrollTop||0});return{x:d,y:c}},getTop:function(a){return this.getPosition(a).y},getLeft:function(a){return this.getPosition(a).x},getCoordinates:function(b){var a=this.getPosition(b);var c={width:this.offsetWidth,height:this.offsetHeight,left:a.x,top:a.y};c.right=c.left+c.width;c.bottom=c.top+c.height;return c}});Element.Events.domready={add:function(b){if(window.loaded){b.call(this);return}var a=function(){if(window.loaded){return}window.loaded=true;window.timer=$clear(window.timer);this.fireEvent("domready")}.bind(this);if(document.readyState&&window.webkit){window.timer=function(){if(["loaded","complete"].contains(document.readyState)){a()}}.periodical(50)}else{if(document.readyState&&window.ie){if(!$("ie_ready")){var c=(window.location.protocol=="https:")?"://0":"javascript:void(0)";document.write('<script id="ie_ready" defer src="'+c+'"><\/script>');$("ie_ready").onreadystatechange=function(){if(this.readyState=="complete"){a()}}}}else{window.addListener("load",a);document.addListener("DOMContentLoaded",a)}}}};window.onDomReady=function(a){return this.addEvent("domready",a)};window.extend({getWidth:function(){if(this.webkit419){return this.innerWidth}if(this.opera){return document.body.clientWidth}return document.documentElement.clientWidth},getHeight:function(){if(this.webkit419){return this.innerHeight}if(this.opera){return document.body.clientHeight}return document.documentElement.clientHeight},getScrollWidth:function(){if(this.ie){return Math.max(document.documentElement.offsetWidth,document.documentElement.scrollWidth)}if(this.webkit){return document.body.scrollWidth}return document.documentElement.scrollWidth},getScrollHeight:function(){if(this.ie){return Math.max(document.documentElement.offsetHeight,document.documentElement.scrollHeight)}if(this.webkit){return document.body.scrollHeight}return document.documentElement.scrollHeight},getScrollLeft:function(){return this.pageXOffset||document.documentElement.scrollLeft},getScrollTop:function(){return this.pageYOffset||document.documentElement.scrollTop},getSize:function(){return{size:{x:this.getWidth(),y:this.getHeight()},scrollSize:{x:this.getScrollWidth(),y:this.getScrollHeight()},scroll:{x:this.getScrollLeft(),y:this.getScrollTop()}}},getPosition:function(){return{x:0,y:0}}});var Fx={};Fx.Base=new Class({options:{onStart:Class.empty,onComplete:Class.empty,onCancel:Class.empty,transition:function(a){return -(Math.cos(Math.PI*a)-1)/2},duration:500,unit:"px",wait:true,fps:50},initialize:function(a){this.element=this.element||null;this.setOptions(a);if(this.options.initialize){this.options.initialize.call(this)}},step:function(){var a=$time();if(a<this.time+this.options.duration){this.delta=this.options.transition((a-this.time)/this.options.duration);this.setNow();this.increase()}else{this.stop(true);this.set(this.to);this.fireEvent("onComplete",this.element,10);this.callChain()}},set:function(a){this.now=a;this.increase();return this},setNow:function(){this.now=this.compute(this.from,this.to)},compute:function(b,a){return(a-b)*this.delta+b},start:function(b,a){if(!this.options.wait){this.stop()}else{if(this.timer){return this}}this.from=b;this.to=a;this.change=this.to-this.from;this.time=$time();this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);this.fireEvent("onStart",this.element);return this},stop:function(a){if(!this.timer){return this}this.timer=$clear(this.timer);if(!a){this.fireEvent("onCancel",this.element)}return this},custom:function(b,a){return this.start(b,a)},clearTimer:function(a){return this.stop(a)}});Fx.Base.implement(new Chain,new Events,new Options);Fx.CSS={select:function(b,c){if(b.test(/color/i)){return this.Color}var a=$type(c);if((a=="array")||(a=="string"&&c.contains(" "))){return this.Multi}return this.Single},parse:function(c,d,a){if(!a.push){a=[a]}var g=a[0],f=a[1];if(!$chk(f)){f=g;g=c.getStyle(d)}var b=this.select(d,f);return{from:b.parse(g),to:b.parse(f),css:b}}};Fx.CSS.Single={parse:function(a){return parseFloat(a)},getNow:function(c,b,a){return a.compute(c,b)},getValue:function(c,a,b){if(a=="px"&&b!="opacity"){c=Math.round(c)}return c+a}};Fx.CSS.Multi={parse:function(a){return a.push?a:a.split(" ").map(function(b){return parseFloat(b)})},getNow:function(f,d,c){var a=[];for(var b=0;b<f.length;b++){a[b]=c.compute(f[b],d[b])}return a},getValue:function(c,a,b){if(a=="px"&&b!="opacity"){c=c.map(Math.round)}return c.join(a+" ")+a}};Fx.CSS.Color={parse:function(a){return a.push?a:a.hexToRgb(true)},getNow:function(f,d,c){var a=[];for(var b=0;b<f.length;b++){a[b]=Math.round(c.compute(f[b],d[b]))}return a},getValue:function(a){return"rgb("+a.join(",")+")"}};Fx.Style=Fx.Base.extend({initialize:function(b,c,a){this.element=$(b);this.property=c;this.parent(a)},hide:function(){return this.set(0)},setNow:function(){this.now=this.css.getNow(this.from,this.to,this)},set:function(a){this.css=Fx.CSS.select(this.property,a);return this.parent(this.css.parse(a))},start:function(c,b){if(this.timer&&this.options.wait){return this}var a=Fx.CSS.parse(this.element,this.property,[c,b]);this.css=a.css;return this.parent(a.from,a.to)},increase:function(){this.element.setStyle(this.property,this.css.getValue(this.now,this.options.unit,this.property))}});Element.extend({effect:function(b,a){return new Fx.Style(this,b,a)}});Fx.Styles=Fx.Base.extend({initialize:function(b,a){this.element=$(b);this.parent(a)},setNow:function(){for(var a in this.from){this.now[a]=this.css[a].getNow(this.from[a],this.to[a],this)}},set:function(c){var a={};this.css={};for(var b in c){this.css[b]=Fx.CSS.select(b,c[b]);a[b]=this.css[b].parse(c[b])}return this.parent(a)},start:function(c){if(this.timer&&this.options.wait){return this}this.now={};this.css={};var f={},d={};for(var b in c){var a=Fx.CSS.parse(this.element,b,c[b]);f[b]=a.from;d[b]=a.to;this.css[b]=a.css}return this.parent(f,d)},increase:function(){for(var a in this.now){this.element.setStyle(a,this.css[a].getValue(this.now[a],this.options.unit,a))}}});Element.extend({effects:function(a){return new Fx.Styles(this,a)}});Fx.Elements=Fx.Base.extend({initialize:function(b,a){this.elements=$$(b);this.parent(a)},setNow:function(){for(var c in this.from){var g=this.from[c],f=this.to[c],b=this.css[c],a=this.now[c]={};for(var d in g){a[d]=b[d].getNow(g[d],f[d],this)}}},set:function(h){var b={};this.css={};for(var d in h){var g=h[d],c=this.css[d]={},a=b[d]={};for(var f in g){c[f]=Fx.CSS.select(f,g[f]);a[f]=c[f].parse(g[f])}}return this.parent(b)},start:function(d){if(this.timer&&this.options.wait){return this}this.now={};this.css={};var k={},l={};for(var f in d){var h=d[f],a=k[f]={},j=l[f]={},c=this.css[f]={};for(var b in h){var g=Fx.CSS.parse(this.elements[f],b,h[b]);a[b]=g.from;j[b]=g.to;c[b]=g.css}}return this.parent(k,l)},increase:function(){for(var c in this.now){var a=this.now[c],b=this.css[c];for(var d in a){this.elements[c].setStyle(d,b[d].getValue(a[d],this.options.unit,d))}}}});Fx.Scroll=Fx.Base.extend({options:{overflown:[],offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.now=[];this.element=$(b);this.bound={stop:this.stop.bind(this,false)};this.parent(a);if(this.options.wheelStops){this.addEvent("onStart",function(){document.addEvent("mousewheel",this.bound.stop)}.bind(this));this.addEvent("onComplete",function(){document.removeEvent("mousewheel",this.bound.stop)}.bind(this))}},setNow:function(){for(var a=0;a<2;a++){this.now[a]=this.compute(this.from[a],this.to[a])}},scrollTo:function(b,g){if(this.timer&&this.options.wait){return this}var d=this.element.getSize();var c={x:b,y:g};for(var f in d.size){var a=d.scrollSize[f]-d.size[f];if($chk(c[f])){c[f]=($type(c[f])=="number")?c[f].limit(0,a):a}else{c[f]=d.scroll[f]}c[f]+=this.options.offset[f]}return this.start([d.scroll.x,d.scroll.y],[c.x,c.y])},toTop:function(){return this.scrollTo(false,0)},toBottom:function(){return this.scrollTo(false,"full")},toLeft:function(){return this.scrollTo(0,false)},toRight:function(){return this.scrollTo("full",false)},toElement:function(b){var a=this.element.getPosition(this.options.overflown);var c=$(b).getPosition(this.options.overflown);return this.scrollTo(c.x-a.x,c.y-a.y)},increase:function(){this.element.scrollTo(this.now[0],this.now[1])}});Fx.Slide=Fx.Base.extend({options:{mode:"vertical"},initialize:function(b,a){this.element=$(b);this.wrapper=new Element("div",{styles:$extend(this.element.getStyles("margin"),{overflow:"hidden"})}).injectAfter(this.element).adopt(this.element);this.element.setStyle("margin",0);this.setOptions(a);this.now=[];this.parent(this.options);this.open=true;this.addEvent("onComplete",function(){this.open=(this.now[0]===0)});if(window.webkit419){this.addEvent("onComplete",function(){if(this.open){this.element.remove().inject(this.wrapper)}})}},setNow:function(){for(var a=0;a<2;a++){this.now[a]=this.compute(this.from[a],this.to[a])}},vertical:function(){this.margin="margin-top";this.layout="height";this.offset=this.element.offsetHeight},horizontal:function(){this.margin="margin-left";this.layout="width";this.offset=this.element.offsetWidth},slideIn:function(a){this[a||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[0,this.offset])},slideOut:function(a){this[a||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[-this.offset,0])},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0])},show:function(a){this[a||this.options.mode]();this.open=true;return this.set([0,this.offset])},toggle:function(a){if(this.wrapper.offsetHeight==0||this.wrapper.offsetWidth==0){return this.slideIn(a)}return this.slideOut(a)},increase:function(){this.element.setStyle(this.margin,this.now[0]+this.options.unit);this.wrapper.setStyle(this.layout,this.now[1]+this.options.unit)}});Fx.Transition=function(b,a){a=a||[];if($type(a)!="array"){a=[a]}return $extend(b,{easeIn:function(c){return b(c,a)},easeOut:function(c){return 1-b(1-c,a)},easeInOut:function(c){return(c<=0.5)?b(2*c,a)/2:(2-b(2*(1-c),a))/2}})};Fx.Transitions=new Abstract({linear:function(a){return a}});Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);Fx.Transitions.compat(b)}};Fx.Transitions.compat=function(a){["In","Out","InOut"].each(function(b){Fx.Transitions[a.toLowerCase()+b]=Fx.Transitions[a]["ease"+b]})};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a[0]||6)},Expo:function(a){return Math.pow(2,8*(a-1))},Circ:function(a){return 1-Math.sin(Math.acos(a))},Sine:function(a){return 1-Math.sin((1-a)*Math.PI/2)},Back:function(b,a){a=a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a)},Bounce:function(g){var f;for(var d=0,c=1;1;d+=c,c/=2){if(g>=(7-4*d)/11){f=-Math.pow((11-6*d-11*g)/4,2)+c*c;break}}return f},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a[0]||1)/3)}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,[a+2])});Fx.Transitions.compat(b)});var Drag={};Drag.Base=new Class({options:{handle:false,unit:"px",onStart:Class.empty,onBeforeStart:Class.empty,onComplete:Class.empty,onSnap:Class.empty,onDrag:Class.empty,limit:false,modifiers:{x:"left",y:"top"},grid:false,snap:6},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.handle=$(this.options.handle)||this.element;this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.bound={start:this.start.bindWithEvent(this),check:this.check.bindWithEvent(this),drag:this.drag.bindWithEvent(this),stop:this.stop.bind(this)};this.attach();if(this.options.initialize){this.options.initialize.call(this)}},attach:function(){this.handle.addEvent("mousedown",this.bound.start);return this},detach:function(){this.handle.removeEvent("mousedown",this.bound.start);return this},start:function(c){this.fireEvent("onBeforeStart",this.element);this.mouse.start=c.page;var a=this.options.limit;this.limit={x:[],y:[]};for(var d in this.options.modifiers){if(!this.options.modifiers[d]){continue}this.value.now[d]=this.element.getStyle(this.options.modifiers[d]).toInt();this.mouse.pos[d]=c.page[d]-this.value.now[d];if(a&&a[d]){for(var b=0;b<2;b++){if($chk(a[d][b])){this.limit[d][b]=($type(a[d][b])=="function")?a[d][b]():a[d][b]}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid}}document.addListener("mousemove",this.bound.check);document.addListener("mouseup",this.bound.stop);this.fireEvent("onStart",this.element);c.stop()},check:function(a){var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));if(b>this.options.snap){document.removeListener("mousemove",this.bound.check);document.addListener("mousemove",this.bound.drag);this.drag(a);this.fireEvent("onSnap",this.element)}a.stop()},drag:function(a){this.out=false;this.mouse.now=a.page;for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1];this.out=true}else{if($chk(this.limit[b][0])&&(this.value.now[b]<this.limit[b][0])){this.value.now[b]=this.limit[b][0];this.out=true}}}if(this.options.grid[b]){this.value.now[b]-=(this.value.now[b]%this.options.grid[b])}this.element.setStyle(this.options.modifiers[b],this.value.now[b]+this.options.unit)}this.fireEvent("onDrag",this.element);a.stop()},stop:function(){document.removeListener("mousemove",this.bound.check);document.removeListener("mousemove",this.bound.drag);document.removeListener("mouseup",this.bound.stop);this.fireEvent("onComplete",this.element)}});Drag.Base.implement(new Events,new Options);Element.extend({makeResizable:function(a){return new Drag.Base(this,$merge({modifiers:{x:"width",y:"height"}},a))}});Drag.Move=Drag.Base.extend({options:{droppables:[],container:false,overflown:[]},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.droppables=$$(this.options.droppables);this.container=$(this.options.container);this.position={element:this.element.getStyle("position"),container:false};if(this.container){this.position.container=this.container.getStyle("position")}if(!["relative","absolute","fixed"].contains(this.position.element)){this.position.element="absolute"}var d=this.element.getStyle("top").toInt();var c=this.element.getStyle("left").toInt();if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){d=$chk(d)?d:this.element.getTop(this.options.overflown);c=$chk(c)?c:this.element.getLeft(this.options.overflown)}else{d=$chk(d)?d:0;c=$chk(c)?c:0}this.element.setStyles({top:d,left:c,position:this.position.element});this.parent(this.element)},start:function(c){this.overed=null;if(this.container){var a=this.container.getCoordinates();var b=this.element.getCoordinates();if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){this.options.limit={x:[a.left,a.right-b.width],y:[a.top,a.bottom-b.height]}}else{this.options.limit={y:[0,a.height-b.height],x:[0,a.width-b.width]}}}this.parent(c)},drag:function(a){this.parent(a);var b=this.out?false:this.droppables.filter(this.checkAgainst,this).getLast();if(this.overed!=b){if(this.overed){this.overed.fireEvent("leave",[this.element,this])}this.overed=b?b.fireEvent("over",[this.element,this]):null}return this},checkAgainst:function(b){b=b.getCoordinates(this.options.overflown);var a=this.mouse.now;return(a.x>b.left&&a.x<b.right&&a.y<b.bottom&&a.y>b.top)},stop:function(){if(this.overed&&!this.out){this.overed.fireEvent("drop",[this.element,this])}else{this.element.fireEvent("emptydrop",this)}this.parent();return this}});Element.extend({makeDraggable:function(a){return new Drag.Move(this,a)}});var XHR=new Class({options:{method:"post",async:true,onRequest:Class.empty,onSuccess:Class.empty,onFailure:Class.empty,urlEncoded:true,encoding:"utf-8",autoCancel:false,headers:{}},setTransport:function(){this.transport=(window.XMLHttpRequest)?new XMLHttpRequest():(window.ie?new ActiveXObject("Microsoft.XMLHTTP"):false);return this},initialize:function(a){this.setTransport().setOptions(a);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers={};if(this.options.urlEncoded&&this.options.method=="post"){var b=(this.options.encoding)?"; charset="+this.options.encoding:"";this.setHeader("Content-type","application/x-www-form-urlencoded"+b)}if(this.options.initialize){this.options.initialize.call(this)}},onStateChange:function(){if(this.transport.readyState!=4||!this.running){return}this.running=false;var a=0;try{a=this.transport.status}catch(b){}if(this.options.isSuccess.call(this,a)){this.onSuccess()}else{this.onFailure()}this.transport.onreadystatechange=Class.empty},isSuccess:function(a){return((a>=200)&&(a<300))},onSuccess:function(){this.response={text:this.transport.responseText,xml:this.transport.responseXML};this.fireEvent("onSuccess",[this.response.text,this.response.xml]);this.callChain()},onFailure:function(){this.fireEvent("onFailure",this.transport)},setHeader:function(a,b){this.headers[a]=b;return this},send:function(a,c){if(this.options.autoCancel){this.cancel()}else{if(this.running){return this}}this.running=true;if(c&&this.options.method=="get"){a=a+(a.contains("?")?"&":"?")+c;c=null}this.transport.open(this.options.method.toUpperCase(),a,this.options.async);this.transport.onreadystatechange=this.onStateChange.bind(this);if((this.options.method=="post")&&this.transport.overrideMimeType){this.setHeader("Connection","close")}$extend(this.headers,this.options.headers);for(var b in this.headers){try{this.transport.setRequestHeader(b,this.headers[b])}catch(d){}}this.fireEvent("onRequest");this.transport.send($pick(c,null));return this},cancel:function(){if(!this.running){return this}this.running=false;this.transport.abort();this.transport.onreadystatechange=Class.empty;this.setTransport();this.fireEvent("onCancel");return this}});XHR.implement(new Chain,new Events,new Options);var Ajax=XHR.extend({options:{data:null,update:null,onComplete:Class.empty,evalScripts:false,evalResponse:false},initialize:function(b,a){this.addEvent("onSuccess",this.onComplete);this.setOptions(a);this.options.data=this.options.data||this.options.postBody;if(!["post","get"].contains(this.options.method)){this._method="_method="+this.options.method;this.options.method="post"}this.parent();this.setHeader("X-Requested-With","XMLHttpRequest");this.setHeader("Accept","text/javascript, text/html, application/xml, text/xml, */*");this.url=b},onComplete:function(){if(this.options.update){$(this.options.update).empty().setHTML(this.response.text)}if(this.options.evalScripts||this.options.evalResponse){this.evalScripts()}this.fireEvent("onComplete",[this.response.text,this.response.xml],20)},request:function(a){a=a||this.options.data;switch($type(a)){case"element":a=$(a).toQueryString();break;case"object":a=Object.toQueryString(a)}if(this._method){a=(a)?[this._method,a].join("&"):this._method}return this.send(this.url,a)},evalScripts:function(){var b,a;if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){a=this.response.text}else{a=[];var c=/<script[^>]*>([\s\S]*?)<\/script>/gi;while((b=c.exec(this.response.text))){a.push(b[1])}a=a.join("\n")}if(a){(window.execScript)?window.execScript(a):window.setTimeout(a,0)}},getHeader:function(a){try{return this.transport.getResponseHeader(a)}catch(b){}return null}});Object.toQueryString=function(b){var c=[];for(var a in b){c.push(encodeURIComponent(a)+"="+encodeURIComponent(b[a]))}return c.join("&")};Element.extend({send:function(a){return new Ajax(this.getProperty("action"),$merge({data:this.toQueryString()},a,{method:"post"})).request()}});var Cookie=new Abstract({options:{domain:false,path:false,duration:false,secure:false},set:function(c,d,b){b=$merge(this.options,b);d=encodeURIComponent(d);if(b.domain){d+="; domain="+b.domain}if(b.path){d+="; path="+b.path}if(b.duration){var a=new Date();a.setTime(a.getTime()+b.duration*24*60*60*1000);d+="; expires="+a.toGMTString()}if(b.secure){d+="; secure"}document.cookie=c+"="+d;return $extend(b,{key:c,value:d})},get:function(a){var b=document.cookie.match("(?:^|;)\\s*"+a.escapeRegExp()+"=([^;]*)");return b?decodeURIComponent(b[1]):false},remove:function(b,a){if($type(b)=="object"){this.set(b.key,"",$merge(b,{duration:-1}))}else{this.set(b,"",$merge(a,{duration:-1}))}}});var Json={toString:function(c){switch($type(c)){case"string":return'"'+c.replace(/(["\\])/g,"\\$1")+'"';case"array":return"["+c.map(Json.toString).join(",")+"]";case"object":var a=[];for(var b in c){a.push(Json.toString(b)+":"+Json.toString(c[b]))}return"{"+a.join(",")+"}";case"number":if(isFinite(c)){break}case false:return"null"}return String(c)},evaluate:function(str,secure){return(($type(str)!="string")||(secure&&!str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/)))?null:eval("("+str+")")}};Json.Remote=XHR.extend({initialize:function(b,a){this.url=b;this.addEvent("onSuccess",this.onComplete);this.parent(a);this.setHeader("X-Request","JSON")},send:function(a){return this.parent(this.url,"json="+Json.toString(a))},onComplete:function(){this.fireEvent("onComplete",[Json.evaluate(this.response.text,this.options.secure)])}});var Asset=new Abstract({javascript:function(c,b){b=$merge({onload:Class.empty},b);var a=new Element("script",{src:c}).addEvents({load:b.onload,readystatechange:function(){if(this.readyState=="complete"){this.fireEvent("load")}}});delete b.onload;return a.setProperties(b).inject(document.head)},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head)},image:function(c,b){b=$merge({onload:Class.empty,onabort:Class.empty,onerror:Class.empty},b);var d=new Image();d.src=c;var a=new Element("img",{src:c});["load","abort","error"].each(function(f){var g=b["on"+f];delete b["on"+f];a.addEvent(f,function(){this.removeEvent(f,arguments.callee);g.call(this)})});if(d.width&&d.height){a.fireEvent("load",a,1)}return a.setProperties(b)},images:function(d,c){c=$merge({onComplete:Class.empty,onProgress:Class.empty},c);if(!d.push){d=[d]}var a=[];var b=0;d.each(function(g){var f=new Asset.image(g,{onload:function(){c.onProgress.call(this,b);b++;if(b==d.length){c.onComplete()}}});a.push(f)});return new Elements(a)}});var Hash=new Class({length:0,initialize:function(a){this.obj=a||{};this.setLength()},get:function(a){return(this.hasKey(a))?this.obj[a]:null},hasKey:function(a){return(a in this.obj)},set:function(a,b){if(!this.hasKey(a)){this.length++}this.obj[a]=b;return this},setLength:function(){this.length=0;for(var a in this.obj){this.length++}return this},remove:function(a){if(this.hasKey(a)){delete this.obj[a];this.length--}return this},each:function(a,b){$each(this.obj,a,b)},extend:function(a){$extend(this.obj,a);return this.setLength()},merge:function(){this.obj=$merge.apply(null,[this.obj].extend(arguments));return this.setLength()},empty:function(){this.obj={};this.length=0;return this},keys:function(){var a=[];for(var b in this.obj){a.push(b)}return a},values:function(){var a=[];for(var b in this.obj){a.push(this.obj[b])}return a}});function $H(a){return new Hash(a)}Hash.Cookie=Hash.extend({initialize:function(b,a){this.name=b;this.options=$extend({autoSave:true},a||{});this.load()},save:function(){if(this.length==0){Cookie.remove(this.name,this.options);return true}var a=Json.toString(this.obj);if(a.length>4096){return false}Cookie.set(this.name,a,this.options);return true},load:function(){this.obj=Json.evaluate(Cookie.get(this.name),true)||{};this.setLength()}});Hash.Cookie.Methods={};["extend","set","merge","empty","remove"].each(function(a){Hash.Cookie.Methods[a]=function(){Hash.prototype[a].apply(this,arguments);if(this.options.autoSave){this.save()}return this}});Hash.Cookie.implement(Hash.Cookie.Methods);var Color=new Class({initialize:function(b,d){d=d||(b.push?"rgb":"hex");var c,a;switch(d){case"rgb":c=b;a=c.rgbToHsb();break;case"hsb":c=b.hsbToRgb();a=b;break;default:c=b.hexToRgb(true);a=c.rgbToHsb()}c.hsb=a;c.hex=c.rgbToHex();return $extend(c,Color.prototype)},mix:function(){var a=$A(arguments);var c=($type(a[a.length-1])=="number")?a.pop():50;var b=this.copy();a.each(function(d){d=new Color(d);for(var f=0;f<3;f++){b[f]=Math.round((b[f]/100*(100-c))+(d[f]/100*c))}});return new Color(b,"rgb")},invert:function(){return new Color(this.map(function(a){return 255-a}))},setHue:function(a){return new Color([a,this.hsb[1],this.hsb[2]],"hsb")},setSaturation:function(a){return new Color([this.hsb[0],a,this.hsb[2]],"hsb")},setBrightness:function(a){return new Color([this.hsb[0],this.hsb[1],a],"hsb")}});function $RGB(d,c,a){return new Color([d,c,a],"rgb")}function $HSB(d,c,a){return new Color([d,c,a],"hsb")}Array.extend({rgbToHsb:function(){var b=this[0],c=this[1],k=this[2];var h,g,i;var j=Math.max(b,c,k),f=Math.min(b,c,k);var l=j-f;i=j/255;g=(j!=0)?l/j:0;if(g==0){h=0}else{var d=(j-b)/l;var a=(j-c)/l;var m=(j-k)/l;if(b==j){h=m-a}else{if(c==j){h=2+d-m}else{h=4+a-d}}h/=6;if(h<0){h++}}return[Math.round(h*360),Math.round(g*100),Math.round(i*100)]},hsbToRgb:function(){var c=Math.round(this[2]/100*255);if(this[1]==0){return[c,c,c]}else{var a=this[0]%360;var g=a%60;var h=Math.round((this[2]*(100-this[1]))/10000*255);var d=Math.round((this[2]*(6000-this[1]*g))/600000*255);var b=Math.round((this[2]*(6000-this[1]*(60-g)))/600000*255);switch(Math.floor(a/60)){case 0:return[c,b,h];case 1:return[d,c,h];case 2:return[h,c,b];case 3:return[h,d,c];case 4:return[b,h,c];case 5:return[c,h,d]}}return false}});var Scroller=new Class({options:{area:20,velocity:1,onChange:function(a,b){this.element.scrollTo(a,b)}},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.mousemover=([window,document].contains(b))?$(document.body):this.element},start:function(){this.coord=this.getCoords.bindWithEvent(this);this.mousemover.addListener("mousemove",this.coord)},stop:function(){this.mousemover.removeListener("mousemove",this.coord);this.timer=$clear(this.timer)},getCoords:function(a){this.page=(this.element==window)?a.client:a.page;if(!this.timer){this.timer=this.scroll.periodical(50,this)}},scroll:function(){var a=this.element.getSize();var d=this.element.getPosition();var c={x:0,y:0};for(var b in this.page){if(this.page[b]<(this.options.area+d[b])&&a.scroll[b]!=0){c[b]=(this.page[b]-this.options.area-d[b])*this.options.velocity}else{if(this.page[b]+this.options.area>(a.size[b]+d[b])&&a.scroll[b]+a.size[b]!=a.scrollSize[b]){c[b]=(this.page[b]-a.size[b]+this.options.area-d[b])*this.options.velocity}}}if(c.y||c.x){this.fireEvent("onChange",[a.scroll.x+c.x,a.scroll.y+c.y])}}});Scroller.implement(new Events,new Options);var Slider=new Class({options:{onChange:Class.empty,onComplete:Class.empty,onTick:function(a){this.knob.setStyle(this.p,a)},mode:"horizontal",steps:100,offset:0},initialize:function(d,a,b){this.element=$(d);this.knob=$(a);this.setOptions(b);this.previousChange=-1;this.previousEnd=-1;this.step=-1;this.element.addEvent("mousedown",this.clickedElement.bindWithEvent(this));var c,g;switch(this.options.mode){case"horizontal":this.z="x";this.p="left";c={x:"left",y:false};g="offsetWidth";break;case"vertical":this.z="y";this.p="top";c={x:false,y:"top"};g="offsetHeight"}this.max=this.element[g]-this.knob[g]+(this.options.offset*2);this.half=this.knob[g]/2;this.getPos=this.element["get"+this.p.capitalize()].bind(this.element);this.knob.setStyle("position","relative").setStyle(this.p,-this.options.offset);var f={};f[this.z]=[-this.options.offset,this.max-this.options.offset];this.drag=new Drag.Base(this.knob,{limit:f,modifiers:c,snap:0,onStart:function(){this.draggedKnob()}.bind(this),onDrag:function(){this.draggedKnob()}.bind(this),onComplete:function(){this.draggedKnob();this.end()}.bind(this)});if(this.options.initialize){this.options.initialize.call(this)}},set:function(a){this.step=a.limit(0,this.options.steps);this.checkStep();this.end();this.fireEvent("onTick",this.toPosition(this.step));return this},clickedElement:function(b){var a=b.page[this.z]-this.getPos()-this.half;a=a.limit(-this.options.offset,this.max-this.options.offset);this.step=this.toStep(a);this.checkStep();this.end();this.fireEvent("onTick",a)},draggedKnob:function(){this.step=this.toStep(this.drag.value.now[this.z]);this.checkStep()},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;this.fireEvent("onChange",this.step)}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("onComplete",this.step+"")}},toStep:function(a){return Math.round((a+this.options.offset)/this.max*this.options.steps)},toPosition:function(a){return this.max*a/this.options.steps}});Slider.implement(new Events);Slider.implement(new Options);var SmoothScroll=Fx.Scroll.extend({initialize:function(b){this.parent(window,b);this.links=(this.options.links)?$$(this.options.links):$$(document.links);var a=window.location.href.match(/^[^#]*/)[0]+"#";this.links.each(function(d){if(d.href.indexOf(a)!=0){return}var c=d.href.substr(a.length);if(c&&$(c)){this.useLink(d,c)}},this);if(!window.webkit419){this.addEvent("onComplete",function(){window.location.hash=this.anchor})}},useLink:function(b,a){b.addEvent("click",function(c){this.anchor=a;this.toElement(a);c.stop()}.bindWithEvent(this))}});var Sortables=new Class({options:{handles:false,onStart:Class.empty,onComplete:Class.empty,ghost:true,snap:3,onDragStart:function(a,b){b.setStyle("opacity",0.7);a.setStyle("opacity",0.7)},onDragComplete:function(a,b){a.setStyle("opacity",1);b.remove();this.trash.remove()}},initialize:function(d,b){this.setOptions(b);this.list=$(d);this.elements=this.list.getChildren();this.handles=(this.options.handles)?$$(this.options.handles):this.elements;this.bound={start:[],moveGhost:this.moveGhost.bindWithEvent(this)};for(var c=0,a=this.handles.length;c<a;c++){this.bound.start[c]=this.start.bindWithEvent(this,this.elements[c])}this.attach();if(this.options.initialize){this.options.initialize.call(this)}this.bound.move=this.move.bindWithEvent(this);this.bound.end=this.end.bind(this)},attach:function(){this.handles.each(function(b,a){b.addEvent("mousedown",this.bound.start[a])},this)},detach:function(){this.handles.each(function(b,a){b.removeEvent("mousedown",this.bound.start[a])},this)},start:function(c,b){this.active=b;this.coordinates=this.list.getCoordinates();if(this.options.ghost){var a=b.getPosition();this.offset=c.page.y-a.y;this.trash=new Element("div").inject(document.body);this.ghost=b.clone().inject(this.trash).setStyles({position:"absolute",left:a.x,top:c.page.y-this.offset});document.addListener("mousemove",this.bound.moveGhost);this.fireEvent("onDragStart",[b,this.ghost])}document.addListener("mousemove",this.bound.move);document.addListener("mouseup",this.bound.end);this.fireEvent("onStart",b);c.stop()},moveGhost:function(a){var b=a.page.y-this.offset;b=b.limit(this.coordinates.top,this.coordinates.bottom-this.ghost.offsetHeight);this.ghost.setStyle("top",b);a.stop()},move:function(f){var b=f.page.y;this.previous=this.previous||b;var a=((this.previous-b)>0);var d=this.active.getPrevious();var c=this.active.getNext();if(d&&a&&b<d.getCoordinates().bottom){this.active.injectBefore(d)}if(c&&!a&&b>c.getCoordinates().top){this.active.injectAfter(c)}this.previous=b},serialize:function(a){return this.list.getChildren().map(a||function(b){return this.elements.indexOf(b)},this)},end:function(){this.previous=null;document.removeListener("mousemove",this.bound.move);document.removeListener("mouseup",this.bound.end);if(this.options.ghost){document.removeListener("mousemove",this.bound.moveGhost);this.fireEvent("onDragComplete",[this.active,this.ghost])}this.fireEvent("onComplete",this.active)}});Sortables.implement(new Events,new Options);var Tips=new Class({options:{onShow:function(a){a.setStyle("visibility","visible")},onHide:function(a){a.setStyle("visibility","hidden")},maxTitleChars:30,showDelay:100,hideDelay:100,className:"tool",offsets:{x:16,y:16},fixed:false},initialize:function(b,a){this.setOptions(a);this.toolTip=new Element("div",{"class":this.options.className+"-tip",styles:{position:"absolute",top:"0",left:"0",visibility:"hidden"}}).inject(document.body);this.wrapper=new Element("div").inject(this.toolTip);$$(b).each(this.build,this);if(this.options.initialize){this.options.initialize.call(this)}},build:function(b){b.$tmp.myTitle=(b.href&&b.getTag()=="a")?b.href.replace("http://",""):(b.rel||false);if(b.title){var c=b.title.split("::");if(c.length>1){b.$tmp.myTitle=c[0].trim();b.$tmp.myText=c[1].trim()}else{b.$tmp.myText=b.title}b.removeAttribute("title")}else{b.$tmp.myText=false}if(b.$tmp.myTitle&&b.$tmp.myTitle.length>this.options.maxTitleChars){b.$tmp.myTitle=b.$tmp.myTitle.substr(0,this.options.maxTitleChars-1)+"&hellip;"}b.addEvent("mouseenter",function(d){this.start(b);if(!this.options.fixed){this.locate(d)}else{this.position(b)}}.bind(this));if(!this.options.fixed){b.addEvent("mousemove",this.locate.bindWithEvent(this))}var a=this.end.bind(this);b.addEvent("mouseleave",a);b.addEvent("trash",a)},start:function(a){this.wrapper.empty();if(a.$tmp.myTitle){this.title=new Element("span").inject(new Element("div",{"class":this.options.className+"-title"}).inject(this.wrapper)).setHTML(a.$tmp.myTitle)}if(a.$tmp.myText){this.text=new Element("span").inject(new Element("div",{"class":this.options.className+"-text"}).inject(this.wrapper)).setHTML(a.$tmp.myText)}$clear(this.timer);this.timer=this.show.delay(this.options.showDelay,this)},end:function(a){$clear(this.timer);this.timer=this.hide.delay(this.options.hideDelay,this)},position:function(a){var b=a.getPosition();this.toolTip.setStyles({left:b.x+this.options.offsets.x,top:b.y+this.options.offsets.y})},locate:function(b){var d={x:window.getWidth(),y:window.getHeight()};var a={x:window.getScrollLeft(),y:window.getScrollTop()};var c={x:this.toolTip.offsetWidth,y:this.toolTip.offsetHeight};var h={x:"left",y:"top"};for(var f in h){var g=b.page[f]+this.options.offsets[f];if((g+c[f]-a[f])>d[f]){g=b.page[f]-this.options.offsets[f]-c[f]}this.toolTip.setStyle(h[f],g)}},show:function(){if(this.options.timeout){this.timer=this.hide.delay(this.options.timeout,this)}this.fireEvent("onShow",[this.toolTip])},hide:function(){this.fireEvent("onHide",[this.toolTip])}});Tips.implement(new Events,new Options);var Group=new Class({initialize:function(){this.instances=$A(arguments);this.events={};this.checker={}},addEvent:function(b,a){this.checker[b]=this.checker[b]||{};this.events[b]=this.events[b]||[];if(this.events[b].contains(a)){return false}else{this.events[b].push(a)}this.instances.each(function(c,d){c.addEvent(b,this.check.bind(this,[b,c,d]))},this);return this},check:function(c,a,b){this.checker[c][b]=true;var d=this.instances.every(function(g,f){return this.checker[c][f]||false},this);if(!d){return}this.checker[c]={};this.events[c].each(function(f){f.call(this,this.instances,a)},this)}});var Accordion=Fx.Elements.extend({options:{onActive:Class.empty,onBackground:Class.empty,display:0,show:false,height:true,width:false,opacity:true,fixedHeight:false,fixedWidth:false,wait:false,alwaysHide:false},initialize:function(){var c,f,g,b;$each(arguments,function(k,j){switch($type(k)){case"object":c=k;break;case"element":b=$(k);break;default:var h=$$(k);if(!f){f=h}else{g=h}}});this.togglers=f||[];this.elements=g||[];this.container=$(b);this.setOptions(c);this.previous=-1;if(this.options.alwaysHide){this.options.wait=true}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show}if(this.options.start){this.options.display=false;this.options.show=false}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity"}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth"}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight"}for(var d=0,a=this.togglers.length;d<a;d++){this.addSection(this.togglers[d],this.elements[d])}this.elements.each(function(j,h){if(this.options.show===h){this.fireEvent("onActive",[this.togglers[h],j])}else{for(var k in this.effects){j.setStyle(k,0)}}},this);this.parent(this.elements);if($chk(this.options.display)){this.display(this.options.display)}},addSection:function(f,c,h){f=$(f);c=$(c);var g=this.togglers.contains(f);var b=this.togglers.length;this.togglers.include(f);this.elements.include(c);if(b&&(!g||h)){h=$pick(h,b-1);f.injectBefore(this.togglers[h]);c.injectAfter(f)}else{if(this.container&&!g){f.inject(this.container);c.inject(this.container)}}var a=this.togglers.indexOf(f);f.addEvent("click",this.display.bind(this,a));if(this.options.height){c.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"})}if(this.options.width){c.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"})}c.fullOpacity=1;if(this.options.fixedWidth){c.fullWidth=this.options.fixedWidth}if(this.options.fixedHeight){c.fullHeight=this.options.fixedHeight}c.setStyle("overflow","hidden");if(!g){for(var d in this.effects){c.setStyle(d,0)}}return this},display:function(a){a=($type(a)=="element")?this.elements.indexOf(a):a;if((this.timer&&this.options.wait)||(a===this.previous&&!this.options.alwaysHide)){return this}this.previous=a;var b={};this.elements.each(function(f,d){b[d]={};var c=(d!=a)||(this.options.alwaysHide&&(f.offsetHeight>0));this.fireEvent(c?"onBackground":"onActive",[this.togglers[d],f]);for(var g in this.effects){b[d][g]=c?0:f[this.effects[g]]}},this);return this.start(b)},showThisHideOpen:function(a){return this.display(a)}});Fx.Accordion=Accordion;
window.addEvent('domready', function()
{
if (navigator.userAgent.indexOf('Mac') != -1)
{
$$('body')[0].addClass('Plateform-Mac');
}
else if (navigator.userAgent.indexOf('Win') != -1)
{
$$('body')[0].addClass('Plateform-Windows');
}
});/**
* This is a small fix to correct the png transparency problem under IE under version 7
*/
window.addEvent('load', function(e) {
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
if ((version >= 5.5) && (version < 7) && (document.body.filters)) {
for(var i=0; i<document.images.length; i++) {
var img = document.images[i];
var imgName = img.src.toUpperCase();
if ((imgName.substring(imgName.length-3, imgName.length) == "PNG" || imgName.indexOf('FILETYPE=PNG') != -1) && (img.height && img.width)) {
var imgID = (img.id) ? "id='" + img.id + "' " : "";
var imgClass = (img.className) ? "class='" + img.className + "' " : "";
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
var imgStyle = "display:inline-block;" + img.style.cssText;
if (img.align == "left") imgStyle = "float:left;" + imgStyle;
if (img.align == "right") imgStyle = "float:right;" + imgStyle;
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
var strNewHTML = "<span " + imgID + imgClass + imgTitle
+ " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>";
img.outerHTML = strNewHTML;
i = i-1;
}
}
}
});
var PrintingWindow = new Class({
options: {
container: document.getElement('body'),
containerClass : 'Synergee-Web-Page-Component-PrintingWindow',
outputId: 'printingWindowFrame',
width : 750,
height : 370,
button : null
},
initialize: function(options) {
this.setOptions(options);
this.output =  new Element('iframe').injectInside(document.getElement('body'));
this.output.setStyle('display','none');
this.output.setAttribute('id', this.options.outputId);
if(this.options.button)this.options.button.addEvent('click', this.displayPrintWindow.bind(this));
},
displayPrintWindow : function(){
Lightbox.show('{hiddenId|' + this.output.id + '}', '', 'width=' + this.options.width + ', height=' + this.options.height);
if (/msie/i.test(navigator.userAgent)) {
// IE
// seems to be a bug in IE that makes contentWindow raise an error in some cases
try {
var w = this.output.contentWindow;
} catch(ex) {
}
var d = w ? w.document : null;
} else {
try {
var d = this.output.contentDocument;
}
catch (ex) {
}	// in case of cross domain scripting
var w = d ? d.defaultView : null;
}
if (d) {
try {
var tempContainer = new Element('div');
var child = this.options.container.clone();
child.injectInside(tempContainer);
child.getElements('script').each(function(item, index){
item.innerHTML = '';
}.bind(this));
d.open();
d.write('<html><head/><body >'+ tempContainer.innerHTML +'</body></html>');
d.close();
var body = d.getElementsByTagName("body")[0];
body.style.textAlign = 'left';
body.setAttribute('class', this.options.containerClass);
//                    if (this.options.button && this.options.button.id && d.getElementById(this.options.button.id)) {
//                        d.getElementById(this.options.button.id).removeChild(d.getElementById(this.options.button.id).childNodes[0]);
//                    }
var styleSheets = document.getElementsByTagName("LINK");
var head = d.getElementsByTagName("HEAD")[0];
if (!head) {
head = d.createElement("HEAD");
d.getElementsByTagName("HTML")[0].insertBefore(head, d.getElementsByTagName("BODY")[0]);
}
for (var i = 0; i < styleSheets.length; i++) {
if (styleSheets[i].getAttribute("rel") == 'stylesheet') {
var linkElement = d.createElement('LINK');
linkElement.setAttribute('href', styleSheets[i].getAttribute("href"));
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
head.appendChild(linkElement);
}
}
w.focus();
w.print();
} catch (ex) {
}
}
}
});
PrintingWindow.implement(new Events);
PrintingWindow.implement(new Options);
var ResultHelper = Events.extend( {
initialize: function (resultsPerPage, countResults) {
this.resultsPerPage = resultsPerPage;
this.countResults = countResults;
if (this.resultsPerPage == 0)
this.resultsPerPage = 1;
this.countPages = Math.ceil(this.countResults / this.resultsPerPage);
this.currentPage = 0;
},
getCountPages : function () {
return this.countPages;
},
getCurrentPage : function () {
return this.currentPage;
},
injectNavBar : function(toInjectNavBarClass, tagName, navClassBaseName, separator) {
var s = "";
for (var i=0; i<this.countPages; i++) {
var className = navClassBaseName + i;
s += "<" + (tagName == 'button' ? tagName + ' type="button"' : tagName) + " class='" + className + "'>" + (i+1) + "</" + tagName + ">";
if (i != this.countPages - 1) {
s += separator;
}
}
$$('.'+toInjectNavBarClass).setHTML(s);
},
nextPage : function () {
if (this.currentPage < this.countPages - 1) {
this.fireEvent('onPageChangeBefore');
this.currentPage++;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == this.countPages - 1) {
this.fireEvent('onPageChangeUpperLimit');
}
}
},
previousPage : function () {
if (this.currentPage > 0) {
this.fireEvent('onPageChangeBefore');
this.currentPage--;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == 0) {
this.fireEvent('onPageChangeLowerLimit');
}
}
},
selectPage : function (page) {
if (page >=0 && page < this.countPages) {
this.fireEvent('onPageChangeBefore');
this.currentPage = page;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == 0) {
this.fireEvent('onPageChangeLowerLimit');
}
if (this.currentPage == this.countPages - 1) {
this.fireEvent('onPageChangeUpperLimit');
}
}
},
firstPage : function () {
this.selectPage(0);
},
lastPage : function () {
this.selectPage(this.countPages - 1);
}
});
/****************************************************************
*                                                              *
*  curvyCorners                                                *
*  ------------                                                *
*                                                              *
*  This script generates rounded corners for your divs.        *
*                                                              *
*  Version 1.2.9                                               *
*  Copyright (c) 2006 Cameron Cooke                            *
*  By: Cameron Cooke and Tim Hutchison.                        *
*                                                              *
*                                                              *
*  Website: http://www.curvycorners.net                        *
*  Email:   info@totalinfinity.com                             *
*  Forum:   http://www.curvycorners.net/forum/                 *
*                                                              *
*                                                              *
*  This library is free software; you can redistribute         *
*  it and/or modify it under the terms of the GNU              *
*  Lesser General Public License as published by the           *
*  Free Software Foundation; either version 2.1 of the         *
*  License, or (at your option) any later version.             *
*                                                              *
*  This library is distributed in the hope that it will        *
*  be useful, but WITHOUT ANY WARRANTY; without even the       *
*  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
*  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
*  License for more details.                                   *
*                                                              *
*  You should have received a copy of the GNU Lesser           *
*  General Public License along with this library;             *
*  Inc., 59 Temple Place, Suite 330, Boston,                   *
*  MA 02111-1307 USA                                           *
*                                                              *
****************************************************************/
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
else
{ var startIndex = 1; var boxCol = arguments;}
var curvyCornersCol = new Array(); if(arguments[0].validTags)
var validElements = arguments[0].validTags; else
var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
}
this.objects = curvyCornersCol; this.applyCornersToAll = function()
{ for(var x = 0, k = this.objects.length; x < k; x++)
{ this.objects[x].applyCorners();}
}
}
function curvyObject()
{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderBottomWidth", "border-bottom-width"); var borderColour = get_style(this.box, "borderBottomColor", "border-bottom-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingBottom", "padding-bottom"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
this.box.innerHTML = ""; this.applyCorners = function()
{ for(var t = 0; t < 2; t++)
{ switch(t)
{ case 0:
if(this.settings.tl || this.settings.tr)
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
break; case 1:
if(this.settings.bl || this.settings.br)
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
break;}
}
if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
{ if(i > -1 < 4)
{ var cc = corners[i]; if(!this.settings[cc])
{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
newCorner.style.backgroundColor = this.boxColour; else
newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
{ case "tl":
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
}
}
else
{ if(this.masterCorners[this.settings[cc].radius])
{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
else
{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
{ if((intx +1) >= borderRadius)
var y1 = -1; else
var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
{ if((intx) >= borderRadius)
var y2 = -1; else
var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
var y3 = -1; else
var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
if((intx) >= j)
var y4 = -1; else
var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
{ for(var inty = (y1 + 1); inty < y2; inty++)
{ if(this.settings.antiAlias)
{ if(this.backgroundImage != "")
{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
else
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
}
else
{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
}
}
if(this.settings.antiAlias)
{ if(y3 >= y2)
{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
}
else
{ if(y3 >= y1)
{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
}
var outsideColour = this.borderColour;}
else
{ var outsideColour = this.boxColour; var y3 = y1;}
if(this.settings.antiAlias)
{ for(var inty = (y3 + 1); inty < y4; inty++)
{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
}
}
this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
if(cc != "br")
{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
switch(cc)
{ case "tr":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
}
}
}
if(newCorner)
{ switch(cc)
{ case "tl":
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
}
}
}
var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
{ if(z == "t" || z == "b")
{ if(radiusDiff[z])
{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
{ case "tl":
newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
}
var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
{ case "t":
if(this.topContainer)
{ if(this.settings.tl.radius && this.settings.tr.radius)
{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
break; case "b":
if(this.bottomContainer)
{ if(this.settings.bl.radius && this.settings.br.radius)
{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
}
break;}
}
}
if(this.settings.autoPad == true && this.boxPadding > 0)
{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
}
this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
else
{ pixel.style.backgroundColor = colour;}
if (transAmount != 100)
setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
}
function insertAfter(parent, node, referenceNode)
{ parent.insertBefore(node, referenceNode.nextSibling);}
function BlendColour(Col1, Col2, Col1Fraction)
{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
function IntToHex(strNum)
{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
function MakeHex(x)
{ if((x >= 0) && (x <= 9))
{ return x;}
else
{ switch(x)
{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
}
}
function pixelFraction(x, y, r)
{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
switch (whatsides)
{ case "LeftRight":
pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
pixelfraction = 1;}
return pixelfraction;}
function rgb2Hex(rgbColour)
{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
return hexColour;}
function rgb2Array(rgbColour)
{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
function setOpacity(obj, opacity)
{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
else if(typeof(obj.style.opacity) != "undefined")
{ obj.style.opacity = opacity/100;}
else if(typeof(obj.style.MozOpacity) != "undefined")
{ obj.style.MozOpacity = opacity/100;}
else if(typeof(obj.style.filter) != "undefined")
{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
else if(typeof(obj.style.KHTMLOpacity) != "undefined")
{ obj.style.KHTMLOpacity = opacity/100;}
}
function inArray(array, value)
{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
return false;}
function inArrayKey(array, value)
{ for(key in array){ if(key === value) return true;}
return false;}
function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
else { elm['on' + evType] = fn;}
}
function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
}
function format_colour(colour)
{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
{ if(colour.substr(0, 3) == "rgb")
{ returnColour = rgb2Hex(colour);}
else if(colour.length == 4)
{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
else
{ returnColour = colour;}
}
return returnColour;}
function get_style(obj, property, propertyNS)
{ try
{ if(obj.currentStyle)
{ var returnVal = eval("obj.currentStyle." + property);}
else
{ if(isSafari && obj.style.display == "none")
{ obj.style.display = ""; var wasHidden = true;}
var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
{ obj.style.display = "none";}
}
}
catch(e)
{ }
return returnVal;}
function getElementsByClass(searchClass, node, tag)
{ var classElements = new Array(); if(node == null)
node = document; if(tag == null)
tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
{ if(pattern.test(els[i].className))
{ classElements[j] = els[i]; j++;}
}
return classElements;}
function newCurvyError(errorMessage)
{ return new Error("curvyCorners Error:\n" + errorMessage)
}
/*
Slimbox (Extended Version 1.3.1, 2007-02-21)
by Yukio Arita (http://homepage.mac.com/yukikun/software/slimbox_ex/)
- 	Support to show external content using iframe.
- 	Support to set content size. You can add width/height parameters
in rev attribute of the anchor url.
ex1) <a href="image.jpg" rev="width=50%, height=50%" rel="lightbox">
<img src="image_thumb.jpg" alt="image"></a>
ex2) <a href="text.html" rev="width=500, height=300" rel="lightbox">
some text here</a>
- 	Some rendering problem with IE6 is fixed. Now you can use Slimbox in
valid XHTML document with XML prolog.
- Of course, license is same as original.
Based on:
Slimbox v1.3 - The ultimate lightweight Lightbox clone
by Christophe Beyls (http://www.digitalia.be) - MIT-style license.
Inspired by the original Lightbox v2 by Lokesh Dhakar.
*/
var Lightbox = {
init: function(options) {
this.options = Object.extend({
resizeDuration: 400,
resizeTransition: Fx.Transitions.sineInOut,
initialWidth: 250,
initialHeight: 250,
animateCaption: true,
defaultIframeWidth : 500,
defaultIframeHeight: 300
}, options || {});
// IE 6 - XML prolog problem
if (window.ie6 && document.compatMode == "BackCompat") {
this.options.animateCaption = false;
}
this.anchors = [];
$each(document.links, function(el) {
if (el.rel && el.rel.test(/^lightbox/i)) {
el.onclick = this.click.pass(el, this);
this.anchors.push(el);
}
}, this);
this.eventKeyDown = this.keyboardListener.bindAsEventListener(this);
this.eventPosition = this.position.bind(this);
this.overlay = new Element('div').setProperty('id', 'lbOverlay').injectInside(document.body);
this.center = new Element('div').setProperty('id', 'lbCenter').setStyles({width: this.options.initialWidth + 'px', height: this.options.initialHeight + 'px', marginLeft: '-' + (this.options.initialWidth / 2) + 'px', display: 'none'}).injectInside(document.body);
this.canvas = new Element('div').setProperty('id', 'lbCanvas').injectInside(this.center);
this.prevLink = new Element('a').setProperties({id: 'lbPrevLink', href: '#'}).setStyle('display', 'none').injectInside(this.canvas);
this.nextLink = this.prevLink.clone().setProperty('id', 'lbNextLink').injectInside(this.canvas);
this.prevLink.onclick = this.previous.bind(this);
this.nextLink.onclick = this.next.bind(this);
this.bottomContainer = new Element('div').setProperty('id', 'lbBottomContainer').setStyle('display', 'none').injectInside(document.body);
this.bottom = new Element('div').setProperty('id', 'lbBottom').injectInside(this.bottomContainer);
new Element('a').setProperties({id: 'lbCloseLink', href: '#'}).injectInside(this.bottom).onclick = this.overlay.onclick = this.close.bind(this);
this.caption = new Element('div').setProperty('id', 'lbCaption').injectInside(this.bottom);
this.number = new Element('div').setProperty('id', 'lbNumber').injectInside(this.bottom);
new Element('div').setStyle('clear', 'both').injectInside(this.bottom);
/* Build effects */
var nextEffect = this.nextEffect.bind(this);
this.fx = {
overlay: this.overlay.effect('opacity', {duration: 500}).hide(),
resizeCenter: this.center.effects({duration: this.options.resizeDuration, transition: this.options.resizeTransition, onComplete: nextEffect}),
image: this.canvas.effect('opacity', {duration: 500, onComplete: nextEffect}),
bottom: this.bottomContainer.effect('height', {duration: 400, onComplete: nextEffect})
};
this.preloadPrev = new Image();
this.preloadNext = new Image();
},
click: function(link) {
if (link.rel.length == 8) return this.show(link.href, link.title, link.rev);
var j, itemNumber, items = [];
this.anchors.each(function(el) {
if (el.rel == link.rel) {
for (j = 0; j < items.length; j++) if (items[j][0] == el.href && items[j][2] == el.rev) break;
if (j == items.length) {
items.push([el.href, el.title, el.rev]);
if (el.href == link.href && el.rev == link.rev) itemNumber = j;
}
}
}, this);
return this.open(items, itemNumber);
},
show: function(url, title, rev) {
return this.open([[url, title, rev]], 0);
},
open: function(items, itemNumber) {
this.items = items;
this.position();
this.setup(true);
var wh = (window.getHeight() == 0) ? window.getScrollHeight() : window.getHeight();
var st = document.body.scrollTop || document.documentElement.scrollTop;
var rev = this.items[0][2];
var height = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), 600);
this.top = st + ((wh - (height)) / 2) - 30;
this.center.setStyles({top: this.top + 'px', display: ''});
this.fx.overlay.start(0.8);
return this.changeItem(itemNumber);
},
position: function() {
//IE6 - XML prolog problem.
var ww = (window.getWidth() == 0) ? window.getScrollWidth() - 22 : window.getWidth();
var wh = (window.getHeight() == 0) ? window.getScrollHeight() : window.getHeight();
var st = document.body.scrollTop || document.documentElement.scrollTop;
this.overlay.setStyles({top: st + 'px', height: wh + 'px', width:ww + 'px'});
},
setup: function(open) {
var elements = $A(document.getElementsByTagName('object'));
if (window.ie) elements.extend(document.getElementsByTagName('select'));
elements.each(function(el) {
el.style.visibility = open ? 'hidden' : '';
});
var fn = open ? 'addEvent' : 'removeEvent';
window[fn]('scroll', this.eventPosition)[fn]('resize', this.eventPosition);
document[fn]('keydown', this.eventKeyDown);
this.step = 0;
},
keyboardListener: function(event) {
switch (event.keyCode) {
case 27: case 88: case 67: this.close(); break;
case 37: case 80: this.previous(); break;
case 39: case 78: this.next();
}
},
previous: function() {
return this.changeItem(this.activeItem - 1);
},
next: function() {
return this.changeItem(this.activeItem + 1);
},
changeItem: function(itemNumber) {
if (this.step || (itemNumber < 0) || (itemNumber >= this.items.length)) return false;
this.step = 1;
this.activeItem = itemNumber;
this.bottomContainer.style.display = this.prevLink.style.display = this.nextLink.style.display = 'none';
this.fx.image.hide();
this.center.className = 'lbLoading';
// discard previous content by clicking
this.removeCurrentItem();
// check item type
var url = this.items[this.activeItem][0];
var rev = this.items[this.activeItem][2];
var re_imageURL = /\.(jpe?g|png|gif|bmp)/i;
var re_flashURL = /\.(swf)/i;
var re_youtubeURL = /http\:\/\/(?:www\.){0,1}youtube\.com\/watch\?v=(.*)?/i;
var re_dailymotionURL = /^http\:\/\/(?:www\.){0,1}dailymotion\.com\/video\/(.*?)\_/i;
var re_streamURL = /stream\.(php)/i;
var re_externalStreamURL = /^http\:\/\/(.*).(mp4|flv)/i;
var re_downloadURL = /download\.php\?ressource=(.*)\&filename=(.*)/i;
var re_hiddenDivURL = /\{hiddenId\|(\w+)\}/i;
var matches = null;
if (url.match(re_imageURL)) {
this.preload = new Image();	// JavaScript native Object
this.preload.datatype = 'image';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+%?)", "i"), -1); //-1 if use original size.
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+%?)", "i"), -1);
this.preload.onload = this.nextEffect.bind(this);
this.preload.src = url;
} else if (url.match(re_flashURL)) {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'flash';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), 425);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), 355);
this.preload.src = url;
this.nextEffect(); //asynchronous loading
} else if (url.match(re_streamURL)) {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'stream';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), 425);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), 355);
this.preload.src = url;
this.nextEffect(); //asynchronous loading
} else if (matches = url.match(re_downloadURL)) {
this.preload = new Object();	// JavaScript native Object
if (matches[2].match(/\.flv/) || matches[2].match(/\.mp4/)) {
this.preload.src = 'stream.php?media=' + matches[2];
this.preload.datatype = 'stream';
} else {
this.preload.src = 'ressource.php?media=' + matches[2];
this.preload.datatype = 'iframe';
}
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), 425);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), 355);
this.nextEffect(); //asynchronous loading
} else if (matches = url.match(re_youtubeURL)) {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'youtube';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), this.options.defaultIframeWidth);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), this.options.defaultIframeHeight);
this.preload.src = matches[1];
this.nextEffect(); //asynchronous loading
} else if (matches = url.match(re_dailymotionURL)) {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'dailymotion';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), this.options.defaultIframeWidth);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), this.options.defaultIframeHeight);
this.preload.src = matches[1];
this.nextEffect();
} else if (matches = url.match(re_hiddenDivURL)) {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'hidden';
this.preload.src = matches[1];
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), this.options.defaultIframeWidth);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), this.options.defaultIframeHeight);
this.nextEffect(); //asynchronous loading
}else if(matches = url.match(re_externalStreamURL)){
this.preload = new Object();	// JavaScript native Object
this.preload.src = url;
this.preload.datatype = 'stream';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), 425);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), 355);
this.nextEffect(); //asynchronous loading
} else {
this.preload = new Object();	// JavaScript native Object
this.preload.datatype = 'iframe';
this.preload.w = this.matchOrDefault(rev, new RegExp("width=(\\d+)", "i"), this.options.defaultIframeWidth);
this.preload.h = this.matchOrDefault(rev, new RegExp("height=(\\d+)", "i"), this.options.defaultIframeHeight);
this.preload.src = url;
this.nextEffect(); //asynchronous loading
}
return false;
},
nextEffect: function() {
switch (this.step++) {
case 1:
this.center.className = '';
var playerContainer;
// create HTML element
if (this.preload.datatype == 'image') {
var ws = (this.preload.w == -1) ? this.preload.width.toString() : this.preload.w.toString();
var hs = (this.preload.h == -1) ? this.preload.height.toString() : this.preload.h.toString();
this.p_width = ( q = ws.match(/(\d+)%/) ) ? q[1] * this.preload.width * 0.01 : ws;
this.p_height = ( q = hs.match(/(\d+)%/) ) ? q[1] * this.preload.height * 0.01 : hs;
new Element('img').setProperties({id: 'lbImage', src:this.preload.src, width:this.p_width, height:this.p_height}).injectInside(this.canvas);
this.nextLink.style.right = '';
} else if (this.preload.datatype == 'youtube') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
playerContainer =  new Element('div').setProperties({id:'lbYoutube'}).injectInside(this.canvas);
new Element('div').setProperties({id:'lbYoutubePlayer'}).injectInside(playerContainer);
swfobject.embedSWF('http://www.youtube.com/v/' + this.preload.src + '&rel=0&autoplay=1&enablejsapi=1&playerapiid=lbYoutube', "lbYoutubePlayer", this.p_width, this.p_height, "8.0.0", "Themes/Common/Components/Video/Flash/expressInstall.swf", '', '', '');
} else if (this.preload.datatype == 'dailymotion') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
playerContainer =  new Element('div').setProperties({id:'lbDailymotion'}).injectInside(this.canvas);
new Element('div').setProperties({id:'lbDailymotionPlayer'}).injectInside(playerContainer);
swfobject.embedSWF('http://www.dailymotion.com/swf/' + this.preload.src + '&v3=1&related=0&autoplay=1', "lbDailymotionPlayer", this.p_width, this.p_height, "8.0.0", "Themes/Common/Components/Video/Flash/expressInstall.swf", '', '', '');
} else if (this.preload.datatype == 'stream') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
var flashvars = {
"type":"flv",
"displayheight":this.p_height,
"file":this.preload.src,
"enablejs":"true",
"overstretch":"true"
};
var params = {
"wMode":"transparent"
};
playerContainer =  new Element('div').setProperties({id:'lbStream'}).injectInside(this.canvas);
new Element('div').setProperties({id:'lbStreamPlayer'}).injectInside(playerContainer);
swfobject.embedSWF(window.getCurrentPageLocation() + 'Themes/Default/Components/Video/Flash/mediaplayer.swf', "lbStreamPlayer", this.p_width, this.p_height, "8.0.0", "Themes/Common/Components/Video/Flash/expressInstall.swf", flashvars, params, '');
} else if (this.preload.datatype == 'flash') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
playerContainer =  new Element('div').setProperties({id:'lbFlash'}).injectInside(this.canvas);
new Element('div').setProperties({id:'lbFlashPlayer'}).injectInside(playerContainer);
swfobject.embedSWF(this.preload.src, "lbFlashPlayer", this.p_width, this.p_height, "8.0.0", "Themes/Common/Components/Video/Flash/expressInstall.swf", '', '', '');
} else if (this.preload.datatype == 'googleMap') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
// Safari would not update iframe content that has static id.
this.iframeId = "mapContainer";
new Element('iframe').setProperties({id: this.iframeId, width: this.p_width, height: this.p_height, frameBorder:0, scrolling:'auto', src:this.preload.src + '&output=embed&s=AARTsJrrJfAezwFwvFA6u8OWSecjpwNIVw'}).injectInside(this.canvas);
this.nextLinkscr.style.right = '25px';
} else if (this.preload.datatype == 'hidden') {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
this.iframeId = this.preload.src;
$(this.iframeId).setStyles({left:'0px',top:'0px',height:this.p_height,width:this.p_width,display:'block'});
$(this.preload.src).setProperties({width: this.p_width, height: this.p_height, frameBorder:0, scrolling:'auto'}).injectInside(this.canvas);
this.nextLink.style.right = '25px';
} else {
this.p_width = this.preload.w;
this.p_height = this.preload.h;
// Safari would not update iframe content that has static id.
this.iframeId = "lbFrame_" + new Date().getTime();
try {
new Element('iframe').setProperties({id: this.iframeId, width: this.p_width, height: this.p_height, frameBorder:0, scrolling:'auto', src:this.preload.src}).injectInside(this.canvas);
} catch (ex) {
}
this.nextLink.style.right = '25px';
}
this.canvas.style.width = this.bottom.style.width = this.p_width + 'px';
this.canvas.style.height = this.prevLink.style.height = this.nextLink.style.height = this.p_height + 'px';
this.caption.setHTML(this.items[this.activeItem][1] || '');
this.number.setHTML((this.items.length == 1) ? '' : 'Page ' + (this.activeItem + 1) + ' of ' + this.items.length);
if (this.activeItem) this.preloadPrev.src = this.items[this.activeItem - 1][0];
if (this.activeItem != (this.items.length - 1)) this.preloadNext.src = this.items[this.activeItem + 1][0];
if (this.center.clientHeight != this.canvas.offsetHeight) {
var oh = (this.p_height == this.canvas.clientHeight) ? this.canvas.offsetHeight : eval(this.p_height) + 18; // fix for ie
this.fx.resizeCenter.start({height: oh});
break;
}
this.step++;
case 2:
if (this.center.clientWidth != this.canvas.offsetWidth) {
var ow = (this.p_width == this.canvas.clientWidth) ? this.canvas.offsetWidth : eval(this.p_width) + 18; // fix for ie
this.fx.resizeCenter.start({width: ow, marginLeft: -ow / 2});
break;
}
this.step++;
case 3:
this.bottomContainer.setStyles({top: (this.top + this.center.clientHeight) + 'px', height:'0px', marginLeft: this.center.style.marginLeft, width:this.center.style.width, display: ''});
this.fx.image.start(1);
break;
case 4:
if (this.options.animateCaption) {
// This is not smooth animation in IE 6 with XML prolog.
// If your site is XHTML strict with XML prolog, disable this option.
this.fx.bottom.start(0, this.bottom.offsetHeight + 10);
break;
}
this.bottomContainer.style.height = (this.bottom.offsetHeight + 10) + 'px';
case 5:
if (this.activeItem) {
this.prevLink.style.display = '';
}
if (this.activeItem != (this.items.length - 1)) {
this.nextLink.style.display = '';
}
// we try to start video players
if (this.preload.datatype == 'stream') {
try {
$("lbStreamPlayer").sendEvent('playpause');
} catch(ex) {
}
} else if (this.preload.datatype == 'youtube') {
try {
//                        $("lbYoutube").playVideo();
} catch(ex) {
}
}
window.fireEvent('slimboxready');
this.step = 0;
}
},
close: function() {
if (this.step < 0) return;
this.step = -1;
this.removeCurrentItem();	// discard content
for (var f in this.fx) this.fx[f].stop();
this.center.style.display = this.bottomContainer.style.display = 'none';
this.center.style.width = this.options.initialWidth + 'px';
this.center.style.height = this.options.initialHeight + 'px';
this.center.style.marginLeft = '-' + (this.options.initialWidth / 2) + 'px';
this.fx.overlay.chain(this.setup.pass(false, this)).start(0);
return false;
},
removeCurrentItem: function() {
if (this.preload) {
try {
if (this.preload.datatype == 'image') {
$('lbImage').remove();
this.preload.onload = Class.empty;
//                this.preload = null;
} else if (this.preload.datatype == 'youtube') {
$('lbYoutubePlayer').parentNode.removeChild($('lbYoutubePlayer'));
//                this.preload = null;
} else if (this.preload.datatype == 'dailymotion') {
$('lbDailymotionPlayer').parentNode.removeChild($('lbDailymotionPlayer'));
//                this.preload = null;
} else if (this.preload.datatype == 'flash') {
$('lbFlashPlayer').parentNode.removeChild($('lbFlashPlayer'));
} else if (this.preload.datatype == 'stream') {
$('lbStreamPlayer').parentNode.removeChild($('lbStreamPlayer'));
} else if (this.preload.datatype == 'googleMap') {
$(this.iframeId).remove();
} else if (this.preload.datatype == 'hidden') {
$(this.iframeId).setStyle('display', 'none');
} else {
$(this.iframeId).remove();
}
this.preload = null;
} catch (ex) {}
}
},
matchOrDefault: function(str, re, val) {
if (!str) {
return val;
}
var hasQuery = str.match(re);
return hasQuery ? hasQuery[1] : val;
}
};
window.addEvent('domready', Lightbox.init.bind(Lightbox));
if(window.ie)
window.addEvent("load",Lightbox.init.bind(Lightbox));/*	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
}
}}
}();// Calendar: a Javascript class for Mootools that adds accessible and unobtrusive date pickers to your form elements <http://electricprism.com/aeron/calendar>
// Calendar RC4, Copyright (c) 2007 Aeron Glemann <http://electricprism.com/aeron>, MIT Style License.
var Calendar = new Class({
options: {
blocked: [], // blocked dates
classes: [], // ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite']
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // days of the week starting at sunday
direction: 0, // -1 past, 0 past + future, 1 future
draggable: true,
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
navigation: 1, // 0 = no nav; 1 = single nav for month; 2 = dual nav for month and year
offset: 0, // first day of the week: 0 = sunday, 1 = monday, etc..
onHideStart: Class.empty,
onHideComplete: Class.empty,
onShowStart: Class.empty,
onShowComplete: Class.empty,
maxYear : 2999,
pad: 1, // padding between multiple calendars
tweak: {x: 0, y: 0} // tweak calendar positioning
},
// initialize: calendar constructor
// @param obj (obj) a js object containing the form elements and format strings { id: 'format', id: 'format' etc }
// @param props (obj) optional properties
initialize: function(obj, options) {
// basic error checking
if (!obj) { return false; }
this.setOptions(options);
// create our classes array
var keys = ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite'];
var values = keys.map(function(key, i) {
if (this.options.classes[i]) {
if (this.options.classes[i].length) { key = this.options.classes[i]; }
}
return key;
}, this);
this.classes = values.associate(keys);
// create cal element with css styles required for proper cal functioning
this.calendar = new Element('div', {
'styles': { left: '-1000px', opacity: 0, position: 'absolute', top: '-1000px', zIndex: 1000 }
}).addClass(this.classes.calendar).injectInside(document.body);
// iex 6 needs a transparent iframe underneath the calendar in order to not allow select elements to render through
if (window.ie6) {
this.iframe = new Element('iframe', {
'styles': { left: '-1000px', position: 'absolute', top: '-1000px', zIndex: 999 }
}).injectInside(document.body);
this.iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
}
// initialize fade method
this.fx = this.calendar.effect('opacity', {
onStart: function() {
if (this.calendar.getStyle('opacity') == 0) { // show
if (window.ie6) { this.iframe.setStyle('display', 'block'); }
this.calendar.setStyle('display', 'block');
this.fireEvent('onShowStart', this.element);
}
else { // hide
this.fireEvent('onHideStart', this.element);
}
}.bind(this),
onComplete: function() {
if (this.calendar.getStyle('opacity') == 0) { // hidden
this.calendar.setStyle('display', 'none');
if (window.ie6) { this.iframe.setStyle('display', 'none'); }
this.fireEvent('onHideComplete', this.element);
}
else { // shown
this.fireEvent('onShowComplete', this.element);
}
}.bind(this)
});
// initialize drag method
if (window.Drag && this.options.draggable) {
this.drag = new Drag.Move(this.calendar, {
onDrag: function() {
if (window.ie6) { this.iframe.setStyles({ left: this.calendar.style.left, top: this.calendar.style.top }); }
}.bind(this)
});
}
// create calendars array
this.calendars = [];
this._id = 0;
var d = new Date(); // today
d.setDate(d.getDate() + this.options.direction.toInt()); // correct today for directional offset
for (var i in obj) {
var cal = {
button: new Element('button').setProperties({'type': 'button'}),
el: $(i),
els: [],
id: this._id++,
month: d.getMonth(),
visible: false,
year: d.getFullYear()
};
// fix for bad element (naughty, naughty element!)
if (!this.element(i, obj[i], cal)) { continue; }
cal.el.addClass(this.classes.calendar);
// create cal button
cal.button.addClass(this.classes.calendar).addEvent('click', function(cal) { this.toggle(cal); }.pass(cal, this)).injectAfter(cal.el);
// read in default value
cal.val = this.read(cal);
$extend(cal, this.bounds(cal)); // abs bounds of calendar
$extend(cal, this.values(cal)); // valid days, months, years
if(cal.val)
this.rebuild(cal);
this.calendars.push(cal); // add to cals array
}
},
addElement: function(obj){
var d = new Date(); // today
d.setDate(d.getDate() + this.options.direction.toInt()); // correct today for directional offset
for (var i in obj) {
var cal = {
button: new Element('button').setProperties({'type': 'button'}),
el: $(i),
els: [],
id: this._id++,
month: d.getMonth(),
visible: false,
year: d.getFullYear()
};
// fix for bad element (naughty, naughty element!)
if (!this.element(i, obj[i], cal)) { continue; }
cal.el.addClass(this.classes.calendar);
// create cal button
cal.button.addClass(this.classes.calendar).addEvent('click', function(cal) { this.toggle(cal); }.pass(cal, this)).injectAfter(cal.el);
// read in default value
//	cal.val = this.read(cal);
$extend(cal, this.bounds(cal)); // abs bounds of calendar
$extend(cal, this.values(cal)); // valid days, months, years
//this.rebuild(cal);
this.calendars.push(cal); // add to cals array
}
},
// blocked: returns an array of blocked days for the month / year
// @param cal (obj)
// @returns blocked days (array)
blocked: function(cal) {
var blocked = [];
var offset = new Date(cal.year, cal.month, 1).getDay(); // day of the week (offset)
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
this.options.blocked.each(function(date){
var values = date.split(' ');
// preparation
for (var i = 0; i <= 3; i++){
if (!values[i]){ values[i] = (i == 3) ? '' : '*'; } // make sure blocked date contains values for at least d, m and y
values[i] = values[i].contains(',') ? values[i].split(',') : new Array(values[i]); // split multiple values
var count = values[i].length - 1;
for (var j = count; j >= 0; j--){
if (values[i][j].contains('-')){ // a range
var val = values[i][j].split('-');
for (var k = val[0]; k <= val[1]; k++){
if (!values[i].contains(k)){ values[i].push(k + ''); }
}
values[i].splice(j, 1);
}
}
}
// execution
if (values[2].contains(cal.year + '') || values[2].contains('*')){
if (values[1].contains(cal.month + 1 + '') || values[1].contains('*')){
values[0].each(function(val){ // if blocked value indicates this month / year
if (val > 0){ blocked.push(val.toInt()); } // add date to blocked array
});
if (values[3]){ // optional value for day of week
for (var i = 0; i < last; i++){
var day = (i + offset) % 7;
if (values[3].contains(day + '')){
blocked.push(i + 1); // add every date that corresponds to the blocked day of the week to the blocked array
}
}
}
}
}
}, this);
return blocked;
},
// bounds: returns the start / end bounds of the calendar
// @param cal (obj)
// @returns obj
bounds: function(cal) {
// 1. first we assume the calendar has no bounds (or a thousand years in either direction)
// by default the calendar will accept a millennium in either direction
var start = new Date(1000, 0, 1); // jan 1, 1000
var end = new Date(2999, 11, 31); // dec 31, 2999
// 2. but if the cal is one directional we adjust accordingly
var date = new Date().getDate() + this.options.direction.toInt();
if (this.options.direction > 0) {
start = new Date();
start.setDate(date + this.options.pad * cal.id);
}
if (this.options.direction < 0) {
end = new Date();
end.setDate(date - this.options.pad * (this.calendars.length - cal.id - 1));
}
// 3. then we can further filter the limits by using the pre-existing values in the selects
cal.els.each(function(el) {
if (el.getTag() == 'select') {
if (el.format.test('(y|Y)')) { // search for a year select
var years = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
}, this);
years.sort(this.sort);
if (years[0] > start.getFullYear()) {
d = new Date(years[0], start.getMonth() + 1, 0); // last day of new month
if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
start.setYear(years[0]);
}
if (years.getLast() < end.getFullYear()) {
d = new Date(years.getLast(), end.getMonth() + 1, 0); // last day of new month
if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
end.setYear(years.getLast());
}
}
if (el.format.test('(F|m|M|n)')) { // search for a month select
var months_start = [];
var months_end = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if ($type(values[0]) != 'number' || values[0] == years[0]) { // if it's a year / month combo for curr year, or simply a month select
if (!months_start.contains(values[1])) { months_start.push(values[1]); } // add to months array
}
if ($type(values[0]) != 'number' || values[0] == years.getLast()) { // if it's a year / month combo for curr year, or simply a month select
if (!months_end.contains(values[1])) { months_end.push(values[1]); } // add to months array
}
}, this);
months_start.sort(this.sort);
months_end.sort(this.sort);
if (months_start[0] > start.getMonth()) {
d = new Date(start.getFullYear(), months_start[0] + 1, 0); // last day of new month
if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
start.setMonth(months_start[0]);
}
if (months_end.getLast() < end.getMonth()) {
d = new Date(start.getFullYear(), months_end.getLast() + 1, 0); // last day of new month
if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
end.setMonth(months_end.getLast());
}
}
}
}, this);
return { 'start': start, 'end': end };
},
// caption: returns the caption element with header and navigation
// @param cal (obj)
// @returns caption (element)
caption: function(cal) {
// start by assuming navigation is allowed
var navigation = {
prev: { 'month': true, 'year': true },
next: { 'month': true, 'year': true }
};
// if we're in an out of bounds year
if (cal.year == cal.start.getFullYear()) {
navigation.prev.year = false;
if (cal.month == cal.start.getMonth() && this.options.navigation == 1) {
navigation.prev.month = false;
}
}
if (cal.year == cal.end.getFullYear()) {
navigation.next.year = false;
if (cal.month == cal.end.getMonth() && this.options.navigation == 1) {
navigation.next.month = false;
}
}
// special case of improved navigation but months array with only 1 month we can disable all month navigation
if ($type(cal.months) == 'array') {
if (cal.months.length == 1 && this.options.navigation == 2) {
navigation.prev.month = navigation.next.month = false;
}
}
var caption = new Element('caption');
//		var prev = new Element('a').addClass(this.classes.prev).appendText('\x3c'); // <
//		var next = new Element('a').addClass(this.classes.next).appendText('\x3e'); // >
var prev = new Element('a').addClass(this.classes.prev).setHTML('&nbsp;&nbsp;&nbsp;&nbsp;'); // <
var next = new Element('a').addClass(this.classes.next).setHTML('&nbsp;&nbsp;&nbsp;&nbsp;'); // >
if (this.options.navigation == 2) {
var month = new Element('span').addClass(this.classes.month).injectInside(caption);
if (navigation.prev.month) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(month); }
var monthSpan = new Element('span').setHTML(this.options.months[cal.month]);
monthSpan.setStyle('cursor','pointer');
monthSpan.addEvent('mouseenter', function(e){
monthSpan.setStyle('text-decoration', 'underline');
});
monthSpan.addEvent('mouseleave', function(e){
monthSpan.setStyle('text-decoration', 'none');
});
// create a list of month select menu
var monthsList = new Element('select', {'style': 'width:60px; font-size:11px;'});
for (var i = 0; i < this.options.months.length; i++) {
var option = new Element('option', {'style': 'font-size:11px;','value':i}).setHTML(this.options.months[i]);
if(cal.month == i){
option.setAttribute('selected', 'selected');
}
option.injectInside(monthsList);
}
monthsList.addEvent('change', function(e){
this.navigate(cal, 'm', monthsList.value-cal.month);
}.bind(this));
monthSpan.addEvent('click', function(e){
monthSpan.removeEvents('click');
monthSpan.empty();
monthsList.injectInside(monthSpan);
}.bind(this));
month.adopt(monthSpan);
if (navigation.next.month) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(month); }
var year = new Element('span').addClass(this.classes.year).injectInside(caption);
if (navigation.prev.year) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', -1); }.pass(cal, this)).injectInside(year); }
var yearSpan = new Element('span').appendText(cal.year);
yearSpan.setStyle('cursor','pointer');
yearSpan.addEvent('mouseenter', function(e){
yearSpan.setStyle('text-decoration', 'underline');
});
yearSpan.addEvent('mouseleave', function(e){
yearSpan.setStyle('text-decoration', 'none');
});
// create a list of years select menu
var yearsList = new Element('select', {'style': 'font-size:11px;'});
var currentYear = new Date().getFullYear();
for (var i = currentYear - 100; i < currentYear+1; i++) {
var option = new Element('option', {'style': 'font-size:11px;','value':i}).appendText(i);
if(cal.year == i){
option.setAttribute('selected', 'selected');
}
option.injectInside(yearsList);
}
yearsList.addEvent('change', function(e){
this.navigate(cal, 'y', yearsList.value-cal.year);
}.bind(this));
yearSpan.addEvent('click', function(e){
yearSpan.removeEvents('click');
yearSpan.empty();
yearsList.injectInside(yearSpan);
}.bind(this));
year.adopt(yearSpan);
if (navigation.next.year) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', 1); }.pass(cal, this)).injectInside(year); }
}
else { // 1 or 0
if (navigation.prev.month && this.options.navigation) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(caption); }
caption.adopt(new Element('span').addClass(this.classes.month).appendText(this.options.months[cal.month]));
caption.adopt(new Element('span').addClass(this.classes.year).appendText(cal.year));
if (navigation.next.month && this.options.navigation) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(caption); }
}
return caption;
},
// changed: run when a select value is changed
// @param cal (obj)
changed: function(cal) {
cal.val = this.read(cal); // update calendar val from inputs
$extend(cal, this.values(cal)); // update bounds - based on curr month
this.rebuild(cal); // rebuild days select
if (!cal.val) { return; } // in case the same date was clicked the cal has no set date we should exit
if (cal.val.getDate() < cal.days[0]) { cal.val.setDate(cal.days[0]); }
if (cal.val.getDate() > cal.days.getLast()) { cal.val.setDate(cal.days.getLast()); }
cal.els.each(function(el) {	// then we can set the value to the field
el.value = this.format(cal.val, el.format);
}, this);
this.check(cal); // checks other cals
this.calendars.each(function(kal) { // update cal graphic if visible
if (kal.visible) { this.display(kal); }
}, this);
},
// check: checks other calendars to make sure no overlapping values
// @param cal (obj)
check: function(cal) {
/** this.calendars.each(function(kal, i) {
if (kal.val) { // if calendar has value set
var change = false;
if (i < cal.id) { // preceding calendar
var bound = new Date(Date.parse(cal.val));
bound.setDate(bound.getDate() - (this.options.pad * (cal.id - i)));
if (bound < kal.val) { change = true; }
}
if (i > cal.id) { // following calendar
var bound = new Date(Date.parse(cal.val));
bound.setDate(bound.getDate() + (this.options.pad * (i - cal.id)));
if (bound > kal.val) { change = true; }
}
if (change) {
if (kal.start > bound) { bound = kal.start; }
if (kal.end < bound) { bound = kal.end; }
kal.month = bound.getMonth();
kal.year = bound.getFullYear();
$extend(kal, this.values(kal));
// TODO - IN THE CASE OF SELECT MOVE TO NEAREST VALID VALUE
// IN THE CASE OF INPUT DISABLE
// if new date is not valid better unset cal value
// otherwise it would mean incrementally checking to find the nearest valid date which could be months / years away
kal.val = kal.days.contains(bound.getDate()) ? bound : null;
this.write(kal);
if (kal.visible) { this.display(kal); } // update cal graphic if visible
}
}
else {
kal.month = cal.month;
kal.year = cal.year;
}
}, this); **/
},
// clicked: run when a valid day is clicked in the calendar
// @param cal (obj)
clicked: function(td, day, cal) {
cal.val = (this.value(cal) == day) ? null : new Date(cal.year, cal.month, day); // set new value - if same then disable
this.write(cal);
// ok - in the special case that it's all selects and there's always a date no matter what (at least as far as the form is concerned)
// we can't let the calendar undo a date selection - it's just not possible!!
if (!cal.val) { cal.val = this.read(cal); }
if (cal.val) {
this.check(cal); // checks other cals
this.toggle(cal); // hide cal
}
else { // remove active class and replace with valid
td.addClass(this.classes.valid);
td.removeClass(this.classes.active);
}
},
// display: create calendar element
// @param cal (obj)
display: function(cal) {
// 1. header and navigation
this.calendar.empty(); // init div
this.calendar.className = this.classes.calendar + ' ' + this.options.months[cal.month].toLowerCase();
var div = new Element('div').injectInside(this.calendar); // a wrapper div to help correct browser css problems with the caption element
var table = new Element('table').injectInside(div).adopt(this.caption(cal));
// 2. day names
var thead = new Element('thead').injectInside(table);
var tr = new Element('tr').injectInside(thead);
for (var i = 0; i <= 6; i++) {
var th = this.options.days[(i + this.options.offset) % 7];
tr.adopt(new Element('th', { 'title': th }).appendText(th.substr(0, 1)));
}
// 3. day numbers
var tbody = new Element('tbody').injectInside(table);
var tr = new Element('tr').injectInside(tbody);
var d = new Date(cal.year, cal.month, 1);
var offset = ((d.getDay() - this.options.offset) + 7) % 7; // day of the week (offset)
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
var prev = new Date(cal.year, cal.month, 0).getDate(); // last day of previous month
var active = this.value(cal); // active date (if set and within curr month)
var valid = cal.days; // valid days for curr month
var inactive = []; // active dates set by other calendars
var hilited = [];
/**	this.calendars.each(function(kal, i) {
if (kal != cal && kal.val) {
if (cal.year == kal.val.getFullYear() && cal.month == kal.val.getMonth()) { inactive.push(kal.val.getDate()); }
if (cal.val) {
for (var day = 1; day <= last; day++) {
d.setDate(day);
if ((i < cal.id && d > kal.val && d < cal.val) || (i > cal.id && d > cal.val && d < kal.val)) {
if (!hilited.contains(day)) { hilited.push(day); }
}
}
}
}
}, this);**/
var d = new Date();
var today = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); // today obv
for (var i = 1; i < 43; i++) { // 1 to 42 (6 x 7 or 6 weeks)
if ((i - 1) % 7 == 0) { tr = new Element('tr').injectInside(tbody); } // each week is it's own table row
var td = new Element('td').injectInside(tr);
var day = i - offset;
var date = new Date(cal.year, cal.month, day);
var cls = '';
if (day === active) { cls = this.classes.active; } // active
else if (inactive.contains(day)) { cls = this.classes.inactive; } // inactive
else if (valid.contains(day)) { cls = this.classes.valid; } // valid
else if (day >= 1 && day <= last) { cls = this.classes.invalid; } // invalid
if (date.getTime() == today) { cls = cls + ' ' + this.classes.today; } // adds class for today
if (hilited.contains(day)) { cls = cls + ' ' + this.classes.hilite; } // adds class if hilited
td.addClass(cls);
if (valid.contains(day)) { // if it's a valid - clickable - day we add interaction
td.setProperty('title', this.format(date, 'D M jS Y'));
td.addEvents({
'click': function(td, day, cal) {
this.clicked(td, day, cal);
}.pass([td, day, cal], this),
'mouseover': function(td, cls) {
td.addClass(cls);
}.pass([td, this.classes.hover]),
'mouseout': function(td, cls) {
td.removeClass(cls);
}.pass([td, this.classes.hover])
});
}
// pad calendar with last days of prev month and first days of next month
if (day < 1) { day = prev + day; }
else if (day > last) { day = day - last; }
td.appendText(day);
}
},
// element: helper function
// @param el (string) element id
// @param f (string) format string
// @param cal (obj)
element: function(el, f, cal) {
if ($type(f) == 'object') { // in the case of multiple inputs per calendar
for (var i in f) {
if (!this.element(i, f[i], cal)) { return false; }
}
return true;
}
el = $(el);
if (!el) { return false; }
el.format = f;
if (el.getTag() == 'select') { // select elements allow the user to manually set the date via select option
el.addEvent('change', function(cal) { this.changed(cal); }.pass(cal, this));
}
else { // input (type text) elements restrict the user to only setting the date via the calendar
el.readOnly = true;
el.addEvent('focus', function(cal) { this.toggle(cal); }.pass(cal, this));
}
cal.els.push(el);
return true;
},
// format: formats a date object according to passed in instructions
// @param date (obj)
// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
// @returns string
format: function(date, format) {
var str = '';
if (date) {
var j = date.getDate(); // 1 - 31
var w = date.getDay(); // 0 - 6
var l = this.options.days[w]; // Sunday - Saturday
var n = date.getMonth() + 1; // 1 - 12
var f = this.options.months[n - 1]; // January - December
var y = date.getFullYear() + ''; // 19xx - 20xx
for (var i = 0, len = format.length; i < len; i++) {
var cha = format.charAt(i); // format char
switch(cha) {
// year cases
case 'y': // xx - xx
y = y.substr(2);
case 'Y': // 19xx - 20xx
str += y;
break;
// month cases
case 'm': // 01 - 12
if (n < 10) { n = '0' + n; }
case 'n': // 1 - 12
str += n;
break;
case 'M': // Jan - Dec
f = f.substr(0, 3);
case 'F': // January - December
str += f;
break;
// day cases
case 'd': // 01 - 31
if (j < 10) { j = '0' + j; }
case 'j': // 1 - 31
str += j;
break;
case 'D': // Sun - Sat
l = l.substr(0, 3);
case 'l': // Sunday - Saturday
str += l;
break;
case 'N': // 1 - 7
w += 1;
case 'w': // 0 - 6
str += w;
break;
case 'S': // st, nd, rd or th (works well with j)
if (j % 10 == 1 && j != '11') { str += 'st'; }
else if (j % 10 == 2 && j != '12') { str += 'nd'; }
else if (j % 10 == 3 && j != '13') { str += 'rd'; }
else { str += 'th'; }
break;
default:
str += cha;
}
}
}
return str; //  return format with values replaced
},
// navigate: calendar navigation
// @param cal (obj)
// @param type (str) m or y for month or year
// @param n (int) + or - for next or prev
navigate: function(cal, type, n) {
switch (type) {
case 'm': // month
if ($type(cal.months) == 'array') {
var i = cal.months.indexOf(cal.month) + n; // index of current month
if (i < 0 || i == cal.months.length) { // out of range
if (this.options.navigation == 1) { // if type 1 nav we'll need to increment the year
this.navigate(cal, 'y', n);
}
i = (i < 0) ? cal.months.length - 1 : 0;
}
cal.month = cal.months[i];
}
else {
var i = cal.month + n;
if (i < 0 || i == 12) {
if (this.options.navigation == 1) {
this.navigate(cal, 'y', n);
}
i = (i < 0) ? 11 : 0;
}
cal.month = i;
}
break;
case 'y': // year
if ($type(cal.years) == 'array') {
var i = cal.years.indexOf(cal.year) + n;
cal.year = cal.years[i];
}
else {
cal.year += n;
}
break;
}
$extend(cal, this.values(cal));
if ($type(cal.months) == 'array') { // if the calendar has a months select
var i = cal.months.indexOf(cal.month); // and make sure the curr months exists for the new year
if (i < 0) { cal.month = cal.months[0]; } // otherwise we'll reset the month
}
this.display(cal);
},
// read: compiles cal value based on array of inputs passed in
// @param cal (obj)
// @returns date (obj) or (null)
read: function(cal) {
var arr = [null, null, null];
cal.els.each(function(el) {
// returns an array which may contain empty values
var values = this.unformat(el.value, el.format);
values.each(function(val, i) {
if ($type(val) == 'number') { arr[i] = val; }
});
}, this);
// we can update the cals month and year values
if ($type(arr[0]) == 'number') { cal.year = arr[0]; }
if ($type(arr[1]) == 'number') { cal.month = arr[1]; }
var val = null;
if (arr.every(function(i) { return $type(i) == 'number'; })) { // if valid date
var last = new Date(arr[0], arr[1] + 1, 0).getDate(); // last day of month
if (arr[2] > last) { arr[2] = last; } // make sure we stay within the month (ex in case default day of select is 31 and month is feb)
val = new Date(arr[0], arr[1], arr[2]);
}
return (cal.val == val) ? null : val; // if new date matches old return null (same date clicked twice = disable)
},
// rebuild: rebuilds days + months selects
// @param cal (obj)
rebuild: function(cal) {
cal.els.each(function(el) {
/*
if (el.getTag() == 'select' && el.format.test('^(F|m|M|n)$')) { // special case for months-only select
if (!cal.options) { cal.options = el.clone(); } // clone a copy of months select
var val = (cal.val) ? cal.val.getMonth() : el.value.toInt();
el.empty(); // initialize select
cal.months.each(function(month) {
// create an option element
var option = new Element('option', {
'selected': (val == month),
'value': this.format(new Date(1, month, 1), el.format);
}).appendText(day).injectInside(el);
}, this);
}
*/
if (el.getTag() == 'select' && el.format.test('^(d|j)$')) { // special case for days-only select
var d = this.value(cal);
if (!d) { d = el.value.toInt(); } // if the calendar doesn't have a set value, try to use value from select
el.empty(); // initialize select
var emptyOption = new Element('option', {
'selected':'true',
'value': '0'
}).injectInside(el);
cal.days.each(function(day) {
// create an option element
var option = new Element('option', {
'selected': (d == day),
'value': ((el.format == 'd' && day < 10) ? '0' + day : day)
}).appendText(day).injectInside(el);
}, this);
}
}, this);
},
// sort: helper function for numerical sorting
sort: function(a, b) {
return a - b;
},
// toggle: show / hide calendar
// @param cal (obj)
toggle: function(cal) {
document.removeEvent('mousedown', this.fn); // always remove the current mousedown script first
if (cal.visible) { // simply hide curr cal
cal.visible = false;
cal.button.removeClass(this.classes.active); // active
this.fx.start(1, 0);
}
else { // otherwise show (may have to hide others)
// hide cal on out-of-bounds click
this.fn = function(e, cal) {
var e = new Event(e);
var el = e.target;
var stop = false;
while (el != document.body && el.nodeType == 1) {
if (el == this.calendar) { stop = true; }
this.calendars.each(function(kal) {
if (kal.button == el || kal.els.contains(el)) { stop = true; }
});
if (stop) {
e.stop();
return false;
}
else { el = el.parentNode; }
}
this.toggle(cal);
}.create({ 'arguments': cal, 'bind': this, 'event': true });
document.addEvent('mousedown', this.fn);
this.calendars.each(function(kal) {
if (kal == cal) {
kal.visible = true;
kal.button.addClass(this.classes.active); // css c-icon-active
}
else {
kal.visible = false;
kal.button.removeClass(this.classes.active); // css c-icon-active
}
}, this);
var size = window.getSize().scrollSize;
var coord = cal.button.getCoordinates();
var x = coord.right + this.options.tweak.x;
var y = coord.top + this.options.tweak.y;
// make sure the calendar doesn't open off screen
if (!this.calendar.coord) { this.calendar.coord = this.calendar.getCoordinates(); }
if (x + this.calendar.coord.width > size.x) { x -= (x + this.calendar.coord.width - size.x); }
if (y + this.calendar.coord.height > size.y) { y -= (y + this.calendar.coord.height - size.y); }
this.calendar.setStyles({ left: x + 'px', top: y + 'px' });
if (window.ie6) {
this.iframe.setStyles({ height: this.calendar.coord.height + 'px', left: x + 'px', top: y + 'px', width: this.calendar.coord.width + 'px' });
}
this.display(cal);
this.fx.start(0, 1);
}
},
// unformat: takes a value from an input and parses the d, m and y elements
// @param val (string)
// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
// @returns array
unformat: function(val, f) {
f = f.escapeRegExp();
var re = {
d: '([0-9]{2})',
j: '([0-9]{1,2})',
D: '(' + this.options.days.map(function(day) { return day.substr(0, 3); }).join('|') + ')',
l: '(' + this.options.days.join('|') + ')',
S: '(st|nd|rd|th)',
F: '(' + this.options.months.join('|') + ')',
m: '([0-9]{2})',
M: '(' + this.options.months.map(function(month) { return month.substr(0, 3); }).join('|') + ')',
n: '([0-9]{1,2})',
Y: '([0-9]{4})',
y: '([0-9]{2})'
};
var arr = []; // array of indexes
var g = '';
// convert our format string to regexp
for (var i = 0; i < f.length; i++) {
var c = f.charAt(i);
if (re[c]) {
arr.push(c);
g += re[c];
}
else {
g += c;
}
}
// match against date
var matches = val.match('^' + g + '$');
var dates = new Array(3);
if (matches) {
matches = matches.slice(1); // remove first match which is the date
arr.each(function(c, i) {
i = matches[i];
switch(c) {
// year cases
case 'y':
i = '19' + i; // 2 digit year assumes 19th century (same as JS)
case 'Y':
dates[0] = i.toInt();
break;
// month cases
case 'F':
i = i.substr(0, 3);
case 'M':
i = this.options.months.map(function(month) { return month.substr(0, 3); }).indexOf(i) + 1;
case 'm':
case 'n':
dates[1] = i.toInt() - 1;
break;
// day cases
case 'd':
case 'j':
dates[2] = i.toInt();
break;
}
}, this);
}
return dates;
},
// value: returns day value of calendar if set
// @param cal (obj)
// @returns day (int) or null
value: function(cal) {
var day = null;
if (cal.val) {
if (cal.year == cal.val.getFullYear() && cal.month == cal.val.getMonth()) { day = cal.val.getDate(); }
}
return day;
},
// values: returns the years, months (for curr year) and days (for curr month and year) for the calendar
// @param cal (obj)
// @returns obj
values: function(cal) {
var years, months, days;
cal.els.each(function(el) {
if (el.getTag() == 'select') {
if (el.format.test('(y|Y)')) { // search for a year select
years = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
}, this);
years.sort(this.sort);
}
if (el.format.test('(F|m|M|n)')) { // search for a month select
months = []; // 0 - 11 should be
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if ($type(values[0]) != 'number' || values[0] == cal.year) { // if it's a year / month combo for curr year, or simply a month select
if (!months.contains(values[1])) { months.push(values[1]); } // add to months array
}
}, this);
months.sort(this.sort);
}
if (el.format.test('(d|j)') && !el.format.test('^(d|j)$')) { // search for a day select, but NOT a days only select
days = []; // 1 - 31
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
// in the special case of days we dont want the value if its a days only select
// otherwise that will screw up the options rebuilding
// we will take the values if they are exact dates though
if (values[0] == cal.year && values[1] == cal.month) {
if (!days.contains(values[2])) { days.push(values[2]); } // add to days array
}
}, this);
}
}
}, this);
// we start with what would be the first and last days were there no restrictions
var first = 1;
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of the month
// if we're in an out of bounds year
if (cal.year == cal.start.getFullYear()) {
// in the special case of improved navigation but no months array, we'll need to construct one
if (months == null && this.options.navigation == 2) {
months = [];
for (var i = 0; i < 12; i ++) {
if (i >= cal.start.getMonth()) { months.push(i); }
}
}
// if we're in an out of bounds month
if (cal.month == cal.start.getMonth()) {
first = cal.start.getDate(); // first day equals day of bound
}
}
if (cal.year == cal.end.getFullYear()) {
// in the special case of improved navigation but no months array, we'll need to construct one
if (months == null && this.options.navigation == 2) {
months = [];
for (var i = 0; i < 12; i ++) {
if (i <= cal.end.getMonth()) { months.push(i); }
}
}
if (cal.month == cal.end.getMonth()) {
last = cal.end.getDate(); // last day equals day of bound
}
}
// let's get our invalid days
var blocked = this.blocked(cal);
// finally we can prepare all the valid days in a neat little array
if ($type(days) == 'array') { // somewhere there was a days select
days = days.filter(function(day) {
if (day >= first && day <= last && !blocked.contains(day)) { return day; }
});
}
else { // no days select we'll need to construct a valid days array
days = [];
for (var i = first; i <= last; i++) {
if (!blocked.contains(i)) { days.push(i); }
}
}
days.sort(this.sort); // sorting our days will give us first and last of month
return { 'days': days, 'months': months, 'years': years };
},
// write: sets calendars value to form elements
// @param cal (obj)
write: function(cal) {
this.rebuild(cal);	 // in the case of options, we'll need to make sure we have the correct number of days available
cal.els.each(function(el) {	// then we can set the value to the field
el.value = this.format(cal.val, el.format);
}, this);
}
});
Calendar.implement(new Events, new Options);/**
*  Create a drop-down menu for navigation
*
*/
var DropDownMenu = Options.extend({
options: {
onComplete: Class.empty,
onStart: Class.empty,
delay:500
},
initialize: function(el, options) {
this.el = $(el);
this.setOptions(options);
var elementToHide;
this.el.getElements('li').each(function(li, index) {
if(li.getElements('a')[0])li.getElements('a')[0].removeAttribute('title');
if(li.getElements('ul').length){
li.addClass('HasChild');
}
li.menu = this;
li.addEvent('mouseenter', function() {
this.addClass('iehover');
$clear(this._myTimer);
if(elementToHide && !this.getElements('ul').contains(elementToHide)){
elementToHide.removeClass('ulhover');
}
elementToHide = null;
if(this.getElements('ul')[0]) {
this.getElements('ul')[0].addClass('ulhover');
}
});
li.addEvent('mouseleave', function() {
this.removeClass('iehover');
if(this.getElements('ul')[0]) {
elementToHide = this.getElements('ul')[0];
this._myTimer = this.getElements('ul')[0].removeClass.delay(this.menu.options.delay ,this.getElements('ul')[0], 'ulhover');
}
});
}.bind(this));
},
hide : function(){
this.el.getElements('ul').each(function(item,index){
item.removeClass('ulhover');
});
}
});
var SynergeeNews = new Class({
initialize: function(el, elementClass, timer, className, navContainer) {
this.el = el;
this.elementClass = elementClass;
this._timer = timer;
this._className = ' ';
if(className){
this._className += className;
}
if(navContainer){
this._navContainer = navContainer;
}else {
this._navContainer = this.el.getParent();
}
this.items = this.el.getElements(this.elementClass);
// create the nav div
var nav = new Element('ul', {'class': 'Synergee-Web-Page-TextTicker-Nav-Container' + this._className});
this.navButtons = new Array();
for (var i = 0; i < this.items.length; i++) {
this.navButtons[i] = new Element('li', {'class': 'Synergee-Web-Page-TextTicker-NavButton' + this._className});
this.navButtons[i].position = i;
nav.appendChild(this.navButtons[i]);
this.navButtons[i].addEvent('click', function(event) {
event = new Event(event);
this.goto(event.target.position);
}.bind(this));
}
this._navContainer.appendChild(nav);
if (this.items.length) {
var w = 0;
this.items.each(function(item, index) {
w += item.getSize().size.x;
item.addEvent('mouseenter', function() {
$clear(this.delayedFunction);
}.bind(this));
item.addEvent('mouseleave', function() {
$clear(this.delayedFunction);
this.delayedFunction = this.next.bind(this).delay(this._timer);
}.bind(this));
}.bind(this));
this.el.setStyles({
position: 'absolute',
top: 0,
left: 0/*,
width: w*/
});
this.fx = new Fx.Styles(this.el, {duration:800, transition: Fx.Transitions.Quint.easeInOut,
onStart: function(){
var i = (this.current == 0) ? this.items.length : this.current;
this.navButtons[this.current].addClass('Active');
for (var j = 0; j < this.navButtons.length; j ++) {
if (j != this.current)this.navButtons[j].removeClass('Active');
}
this.el.fireEvent('onstart', this.items[this.current]);
}.bind(this),
onCancel :function() {
this.el.fireEvent('oncancel', this.items[this.current]);
},
onComplete:function() {
this.el.fireEvent('itemchanged', this.items[this.current]);
}.bind(this)});
this.current = this.items.length;
this.next();
}
},
next : function() {
this.current++;
if (this.current >= this.items.length) this.current = 0;
this.fx.stop();
this.fx.start({
top: -this.items[this.current].offsetTop,
left: -this.items[this.current].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this._timer );
},
goto : function(to) {
$clear(this.delayedFunction);
this.current = to;
this.fx.start({
top: -this.items[to].offsetTop,
left: -this.items[to].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this._timer);
}
});var TextSplitter = new Class({
initialize: function(component, splitterElements, titleElement) {
if (component.getElement) {
this.el = component.getElement('div');
var elements = new Array();
if(!(splitterElements instanceof Array)){
splitterElements = new Array(splitterElements);
}
for(var i = 0; i < splitterElements.length; i++){
elements = this.el.getElement(splitterElements[i]);
if(elements)break;
}
// retrieve the blocks
if (elements) {
var children = this.el.childNodes;
this.blocks = new Array();
this.titles = new Array();
this.blocks.push(new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content"}));
for (var i = 0; i < children.length; i++) {
if ($type(children[i]) == 'element' && splitterElements.contains(children[i].tagName.toLowerCase())) {
this.blocks.push(new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content"}));
} else if (this.blocks.length) {
if ($type(children[i]) == 'element') {
this.blocks[this.blocks.length - 1].appendChild(children[i]);
} else {
this.blocks[this.blocks.length - 1].appendChild(children[i]);
}
i--;
}
}
this.el.empty();
if (titleElement) {
for (var i = 0; i < this.blocks.length; i++) {
if (this.blocks[i].getElement(titleElement)) {
this.titles[i] = this.blocks[i].getElement(titleElement);
this.titles[i].addClass('Synergee-Web-Page-TextSplitter-Title');
} else {
this.titles[i] = new Element(titleElement, {'class': 'Synergee-Web-Page-TextSplitter-Title'});
this.titles[i].setHTML('"' + titleElement + '" title missing');
}
}
if (this.titles.length) {
this.titles[this.titles.length - 1].addClass('Synergee-Web-Page-TextSplitter-Title-Last');
}
this.titlesContainer = new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Title-Container"});
this.el.appendChild(this.titlesContainer);
}
this.contentsContainer = new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content-Container"});
this.el.appendChild(this.contentsContainer);
for (var i = 0; i < this.titles.length; i ++) {
this.titlesContainer.appendChild(this.titles[i]);
}
for (var i = 0; i < this.blocks.length; i ++) {
this.contentsContainer.appendChild(this.blocks[i]);
}
}
}
},
getContentContainer : function() {
return this.contentsContainer;
},
getTitleContainer :  function() {
if(this.titlesContainer)return this.titlesContainer;
return null;
},
getTitles : function() {
return this.titles;
},
getContents : function(){
return this.blocks;
}
});var SynergeeTips = Tips.extend({
options: {
onShow: function(tip){
tip.setStyle('visibility', 'visible');
},
onHide: function(tip){
tip.setStyle('visibility', 'hidden');
},
maxTitleChars: 30,
showDelay: 100,
hideDelay: 100,
className: 'tool',
offsets: {'x': 16, 'y': 16},
fixed: false,
maxHeight : 0,
closeButton : false,
eventType : 'click'
},
build: function(el){
el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
if (el.title){
var dual = el.title.split('::');
if (dual.length > 1) {
el.$tmp.myTitle = dual[0].trim();
el.$tmp.myText = dual[1].trim();
} else {
el.$tmp.myText = el.title;
}
el.removeAttribute('title');
} else {
el.$tmp.myText = false;
}
if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
el.addEvent(this.options.eventType, function(event){
this.start(el);
if (this.options.maxHeight) {
if(this.text && this.options.maxHeight < this.text.getParent().getCoordinates().height){
this.text.getParent().setStyle('max-height', this.options.maxHeight);
this.text.getParent().setStyle('overflowY', 'scroll');
}
}
if (!this.options.fixed) this.locate(event);
else this.position(el);
}.bind(this));
if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
var end = this.end.bind(this);
el.addEvent('mouseleave', end);
el.addEvent('trash', end);
this.toolTip.addEvent('mouseleave', end);
this.toolTip.addEvent('mouseenter', function(event){
$clear(this.timer);
}.bind(this));
},
start: function(el){
this.wrapper.empty();
if (el.$tmp.myTitle){
this.title = new Element('span').inject(
new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)
).setHTML(el.$tmp.myTitle);
if(this.options.closeButton){
this.closeButton = new Element('div',{'class':this.options.className + '-Close'});
var end = this.hide.bind(this);
this.closeButton.injectInside(this.title.getParent());
this.closeButton.addEvent('click',end);
}
}
if (el.$tmp.myText){
this.text = new Element('div').inject(
new Element('div', {'class': this.options.className + '-text Synergee-Web-Page-Component-Text'}).inject(this.wrapper)
).setHTML(el.$tmp.myText);
}
$clear(this.timer);
this.timer = this.show.delay(this.options.showDelay, this);
}
});
/**
* The synergee form javascript code.
* This file contains all the necessary code used by the form widget.
*
* Copyright (c) 2007 Pyrameed all right reserved (http://www.pyrameed.com)
*/
/**
* The field validator.
* This class is used to validate a form field
*/
var SynergeeFieldValidator = new Class({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return true;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
throw Error('The method "getValidatorName" has to be defined for the field validator classes.');
}
});
/**
* The not empty field validator
*/
var SynergeeFieldValidatorNotEmpty = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return (field.tagName.toLowerCase() == 'div' || field.getValue() != '');
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorNotEmpty';
}
});
/**
* The email field validator
*/
var SynergeeFieldValidatorEmail = SynergeeFieldValidator.extend({
_emailRegex : new RegExp("^([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._emailRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorEmail';
}
});
/**
* The list field validator
*/
var SynergeeFieldValidatorList = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
var inputElements = field.getElementsByTagName('input');
for (var i = 0; i < inputElements.length; i++) {
if (inputElements[i].checked) {
return true;
}
}
return false;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorList';
}
});
/**
* The alpha field validator
*/
var SynergeeFieldValidatorAlpha = SynergeeFieldValidator.extend({
_alphaRegex : new RegExp("^([a-zA-Z])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._alphaRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorAlpha';
}
});
/**
* The numeric field validator
*/
var SynergeeFieldValidatorNum = SynergeeFieldValidator.extend({
_numRegex : new RegExp("^([0-9])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._numRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorNum';
}
});
/**
* The alphanumeric field validator
*/
var SynergeeFieldValidatorAlnum = SynergeeFieldValidator.extend({
_alnumRegex : new RegExp("^([a-zA-Z0-9])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._alnumRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorAlnum';
}
});
/**
* The date field validator
*/
var SynergeeFieldValidatorDate = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return (field.tagName.toLowerCase() == 'div' || field.getValue() != '');
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorDate';
}
});
/**
* The Birthdate field validator
*/
var SynergeeFieldValidatorBirthdate = SynergeeFieldValidator.extend({
initialize : function(minDate, maxDate, format) {
if(minDate){
this._minDate = (new Date()).fromIso(minDate);
}   else{
this._minDate = null;
}
if(maxDate){
this._maxDate = (new Date()).fromIso(maxDate);
}   else{
this._maxDate = null;
}
if(format) this._format = format;
},
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
// always return true, the backend check the right dates
////
//        var fieldValue = field.getValue();
//        if(fieldValue != '' && (new Date()).fromIso(fieldValue)){
//            fieldValue = (new Date()).fromIso(fieldValue);
//            if(this._maxDate && this._maxDate.getTime() < fieldValue){
//                return false;
//
//            }
//            if(this._minDate && this._minDate.getTime() > fieldValue){
//                return false;
//            }
//        }
return true;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorBirthdate';
}
});
/**
* The Birthdate field validator
*/
var SynergeeFieldValidatorLevel = SynergeeFieldValidator.extend({
initialize : function(minimumLevel, maximumLevel) {
if(minimumLevel){
this._minimumLevel = minimumLevel;
}   else{
this._minimumLevel = 1;
}
if(maximumLevel){
this._maximumLevel = maximumLevel;
}   else{
this._maximumLevel = 7;
}
},
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
var selIndex = field.selectedIndex;
var comboValue = field.options[selIndex].value;
if(comboValue){
if(comboValue >= this._minimumLevel && comboValue <= this._maximumLevel){
return true;
}
return false;
}
return true;
},
/**
* Return the validator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorLevel';
}
});
/**
* The form validator.
* This class is used to validate the fields of a specific form
*/
var SynergeeFormValidator = new Class({
_formElement : null,
_onComplete : null,
_fields : [],
_submitButton : null,
/**
* The constructor
*
* @param Element formElement The form element
* @param function onComplete The function called once the form has been submitted (this function is called by the ajax component)
*/
initialize: function(formElement, onComplete) {
this._fields = [];
this._formElement = formElement;
this._scroller = new Fx.Scroll(window, {offset: {'x': 0, 'y': -50}});
if (typeof(onComplete) == 'function') {
this._onComplete = onComplete;
} else {
this._onComplete = eval(onComplete);
}
this._formElement.addEvent('submit', function(e) {
new Event(e).stop();
});
// The error message functions are added to the form
this._formElement._errorMessage = new Fx.Slide(this._formElement.getElementsByTagName('div')[0]);
this._formElement.getElementsByTagName('div')[0].setStyle('clear', 'both');
this._formElement._errorMessage.hide();
this._formElement.displayErrorMessage = function() {
if (this._errorMessage) {
this._errorMessage.stop();
this._errorMessage.slideIn();
}
};
this._formElement.hideErrorMessage = function() {
if (this._errorMessage) {
this._errorMessage.stop();
this._errorMessage.slideOut();
}
};
},
/**
* This method is called when the response of the form has been received.
* The goal of this method is to analyse the response and if some fields were
* invalid the error message is displayed again.
* If no invalidate fields are returned, the user defined function (set on the onComplete
* attribute of the form tag) is called with the response as parameter.
*
* @param string response The response returned by the server
*/
onComplete : function(response) {
// The submit button is ungrayed
if (this._submitButton) {
this._submitButton.removeClass('WaitingButton');
this._submitButton.removeProperty('disabled');
}
// We check if the invalidateFields is empty or not
try {
var response = Json.evaluate(response);
if (response.invalidFields && response.invalidFields.length) {
try {
if ($(response.invalidFields[0])) {
$(response.invalidFields[0]).focus();
} else {
$('id_' + response.invalidFields[0]).focus();
}
}catch(ex){
// if the element is not focusable (it's hidden or something)
}
response.invalidFields.each(function(fieldName) {
if ($(fieldName)) {
$(fieldName).displayErrorMessage();
} else {
$('id_' + fieldName).displayErrorMessage();
}
});
try {
if(response.invalidFields[0]){
if ($(response.invalidFields[0])) {
if($(response.invalidFields[0]).getStyle('display') == 'none'){
var element = $(response.invalidFields[0]).getParent();
}else {
var element = $(response.invalidFields[0]);
}
this._scroller.toElement(element);
} else {
if($('id_' + response.invalidFields[0]).getStyle('display') == 'none'){
var element = $('id_' + response.invalidFields[0]).getParent();
}else {
var element = $('id_' + response.invalidFields[0]);
}
this._scroller.toElement(element);
}
}
}catch (ex){}
this._formElement.fireEvent('invalidfield');
} else if (response.isValid) {
// The user defined on complete method is called with the response as parameter
this._onComplete(response.response);
} else {
// The request wasn't valid, then a global message has to be send
this._formElement.displayErrorMessage();
}
} catch(ex) {
// The response is not a valid JSON encoded one
this._formElement.displayErrorMessage();
this._formElement.fireEvent('invalidfield');
}
},
/**
* Validate the fields of the form
*
* @param boolean ajaxCall True if an ajax call has to be done
*/
validate : function(ajaxCall) {
// The submit button is grayed
if (this._submitButton) {
this._submitButton.addClass('WaitingButton');
this._submitButton.setProperty('disabled', 'disabled');
}
// The error message of the form is hidden
this._formElement.hideErrorMessage();
var valid = true;
var invalidFields = new Array();
for (var i = 0; i < this._fields.length; i++) {
for (var j = 0; j < this._fields[i].getValidators().length; j++) {
if (!this._fields[i].getValidators()[j].isValid(this._fields[i])) {
invalidFields.push(this._fields[i]);
}
}
}
// The valid fields error message are hidden
for (var i = 0; i < this._fields.length; i++) {
if (!invalidFields.contains(this._fields[i])) {
this._fields[i].hideErrorMessage();
}
}
// The invalidate fields error message are displayed
if (invalidFields.length) {
invalidFields[0].focus();
// The page is scrolled to the first error message
this._scroller.toElement(invalidFields[0]);
for (var i = 0; i < invalidFields.length; i++) {
invalidFields[i].displayErrorMessage();
}
// The submit button is ungrayed
if (this._submitButton) {
this._submitButton.removeClass('WaitingButton');
this._submitButton.removeProperty('disabled');
}
return false;
} else {
if (ajaxCall) {
// The right page location is set to the action attribute of the form
this._formElement.setProperty('action', window.getCurrentPageUrl());
// The componentName and componentId fields are populated
if (!this._formElement.getChildren().contains($('id_componentName'))) {
if ($('id_componentName')) {
$('id_componentName').remove();
}
(new Element('input').setProperties({name:'componentName',id:'id_componentName',type:'hidden'})).injectBefore(this._formElement.getChildren()[0]);
}
$('id_componentName').setProperty('value', this._formElement.getComponentName());
if (!this._formElement.getChildren().contains($('id_componentId'))) {
if ($('id_componentId')) {
$('id_componentId').remove();
}
(new Element('input').setProperties({name:'componentId',id:'id_componentId',type:'hidden'})).injectBefore(this._formElement.getChildren()[1]);
}
$('id_componentId').setProperty('value', this._formElement.getComponentId());
// The validationInformation field is populated with all the validation information
if (!this._formElement.getChildren().contains($('id_validationInformation'))) {
if ($('id_validationInformation')) {
$('id_validationInformation').remove();
}
(new Element('input').setProperties({name:'validationInformation',id:'id_validationInformation',type:'hidden'})).injectBefore(this._formElement.getChildren()[2]);
}
$('id_validationInformation').setProperty('value', this.getValidationInformation());
// All the fields are ok, then the form is sent
this._formElement.fireEvent('ajaxcall');
this._formElement.send({onComplete:this.onComplete.bind(this)});
return false;
} else {
return true;
}
}
},
createTips : function(field) {
},
/**
* Add a field to the validator
*
* @param Element field The field to validate
* @optionalParam string[] validators The list of validators to apply to the field
*/
addField : function(field, validators) {
var validatorObjects = [];
if (validators && validators.length) {
for (var i = 0; i < validators.length; i++) {
validatorObjects.push(validators[i]);
}
if (field.getStyle('position') == "absolute") {
if (field.parentNode.getElementsByTagName('div').length) {
field._errorImage = field.getParent().getElementsByTagName('div')[0];
field._errorMessage = new Tips(field._errorImage);
}
} else {
if (field.parentNode.getElementsByTagName('div').length) {
if (field.parentNode.getElementsByTagName('div').length) {
// The error fx object is created
field._errorMessage = new Fx.Slide(field.parentNode.getElementsByTagName('div')[0]);
field.getParent().getElementsByTagName('div')[0].addClass('Synergee-Web-Page-Form-FieldErrorMessage-Container');
field._errorMessage.hide();
}
}
}
}
field._validators = validatorObjects;
field.getValidators = function() {
return this._validators;
};
field.displayErrorMessage = function() {
if (this._errorMessage) {
if (this.getStyle('position') == "absolute") {
this._errorImage.setStyle('display', 'block');
} else {
this.getParent().addClass('InvalidField')
this._errorMessage.stop();
//                    this.setStyle('margin-top', '2px');
this._errorMessage.slideIn();
}
}
};
field.hideErrorMessage = function() {
if (this._errorMessage) {
if (this.getStyle('position') == "absolute") {
this._errorImage.setStyle('display', 'none');
} else {
this.getParent().removeClass('InvalidField')
this._errorMessage.stop();
//                    this.setStyle('margin-top', '0px');
this._errorMessage.slideOut();
}
}
};
this._fields.push(field);
// A check to determine if this is the submit button
if (field && field.getProperty('type') && field.getProperty('type').toLowerCase() == 'submit') {
this._submitButton = field;
}
},
/**
* Return the validation information encoded in JSON.
* This is a hash table that have the field name as key and a coma separated validator name as values.
*
* @return string
*/
getValidationInformation : function() {
var validationInformation = {};
this._fields.each(function(field) {
var validators = new Array();
field.getValidators().each(function(validator) {
validators.push(validator.getValidatorName());
});
validationInformation[field.getProperty('name')] = validators.join(',');
});
return Json.toString(validationInformation);
}
});
/**
* The synergee general javascript code.
* This file contains all the necessary code used by the form widget.
*
* Copyright (c) 2007 Pyrameed all right reserved (http://www.pyrameed.com)
*/
/**
* Add two usefull method to the Element objects in order to determine
* its synergee web page parent component name and id.
* Those informations are usefull when dealing with AJAX requests.
*/
Element.extend({
/**
* Return the first synergee web page component name
*
* @return string The first synergee web page component name
*/
getComponentName : function() {
var currentElement = this;
while(!(currentElement.className && currentElement.className.test('Synergee-Web-Page-Component-(.*)-Container', 'i'))) {
currentElement = currentElement.getParent();
}
var regex = new RegExp('Synergee-Web-Page-Component-(.*)-Container', 'i');
var values = regex.exec(currentElement.className);
if (values && values.length == 2) {
return values[1];
} else {
return null;
}
},
/**
* Return the first synergee web page component id
*
* @return string The first synergee web page component id
*/
getComponentId : function() {
var currentElement = this;
while(!(currentElement.className && currentElement.className.test('Synergee-Web-Page-Component-(.*)-Container', 'i'))) {
currentElement = currentElement.getParent();
}
var regex = new RegExp('Synergee-Web-Page-Component-(.*)-Container', 'i');
var values = regex.exec(currentElement.className);
if (values && values.length == 2) {
return currentElement.getParent().id;
} else {
return null;
}
}
});
/**
* The getUrl method is added to the window object in order to be able to get the current page url easily
*/
window.extend({
/**
* Bookmark the current web page
*
* @param string title The page title
* @param string url The web page url
*/
bookmark : function(title, url) {
if (document.all) {
window.external.AddFavorite(url, title);
} else if (window.sidebar) {
window.sidebar.addPanel(title, url, "");
}
},
/**
* Return the current web page url
*
* @return string The current web page url
*/
getCurrentPageUrl : function() {
if (window.location.href.indexOf('?') != -1) {
return window.location.href.substr(0, window.location.href.indexOf('?'));
}
return window.location.href;
},
/**
* Return the current JSON url.
* This url is used by all the JSON invokations
*
* @param Element element The component element
* @return string The current JSON url
*/
getCurrentJsonUrl : function(element) {
var htmlElement = $E('html');
var windowUrl = window.getCurrentPageUrl();
//        if(windowUrl.indexOf('#')){
//            windowUrl = windowUrl.slice(0, windowUrl.indexOf('#'));
//        }
if (htmlElement.getAttribute('designmode') == 'on') {
var webPageId = /webPageId=([0-9]*)/.exec(window.location.href);
return windowUrl + '?webPageId=' + webPageId[1] + '&componentName=' + element.getComponentName() + '&componentId=' + element.getComponentId();
} else {
return windowUrl + '?componentName=' + element.getComponentName() + '&componentId=' + element.getComponentId();
}
},
/**
* Return the currrent page location (the url without the page name)
*
* @return string The current page location
*/
getCurrentPageLocation : function() {
return window.getCurrentPageUrl().substr(0, window.getCurrentPageUrl().lastIndexOf('/')) + '/';
}
});
/**
* Docucment is extended to add the isInDesignMode method.
*/
document.extend({
/**
* This method return true when the page is displayed in the designer
* @return boolean True if the page is displayed in the designer
*/
isInDesignMode : function() {
var htmlElement = $E('html');
return (htmlElement.getAttribute('designmode') == 'on');
}
});
/**
* Decode the html entities
*
* @param String sa
* @return String
*/
function decodeHtmlEntities(sa) {
var ta=document.createElement("textarea");
ta.innerHTML=sa.replace(/</g,"&lt;").replace(/>/g,"&gt;");
return ta.value;
};
/**
* Pad a number regarding the number passed to the pad. By default 2
* @param number valueToPad The value to pad
* @param number pad The pad value
* @return string the padded number
*/
Number.padTo = function(valueToPad, pad) {
pad = pad ? pad : 2;
pad = Math.pow(10, pad-1);
return (valueToPad < pad) ? ("0" + valueToPad) : valueToPad;
};
/**
* Populate the date from an iso formatted string that represent a date
*
* @param string The iso formatted date
*/
Date.prototype.fromIso = function(isoFormattedDate) {
var dateTimeRegex = new RegExp('^([0-9]{4})-([0-9]{2})-([0-9]{2})[T ]([0-9]{2}):([0-9]{2}):([0-9]{2})(([+-])([0-9]{2})(:([0-9]{2}))?)?$');
var dateRegex = new RegExp('^([0-9]{4})-([0-9]{2})-([0-9]{2})$');
var timeRegex = new RegExp('^([0-9]{2}):([0-9]{2}):([0-9]{2})$');
if (dateTimeRegex.test(isoFormattedDate)) {
var values = dateTimeRegex.exec(isoFormattedDate);
var tmpDate = new Date(values[1], values[2] - 1, values[3], values[4], values[5], values[6]);
this.setTime(tmpDate.getTime());
//this.setTime(Date.parse(values[1] + ' ' + values[2] + ' ' + values[3] + ' ' + values[4] + ':' + values[5] + ':' + values[6]));
// The time zone is calculated
if(values[9]){
var timeZoneOffset = -1 * (values[9]*60 + (values[11]?values[11]*1:0)) * (values[8]=='-'?-1:1);
var currentTimeZoneOffset = this.getTimezoneOffset();
this.setTime(this.getTime() + (timeZoneOffset - currentTimeZoneOffset) * 60000);
}
} else if (dateRegex.test(isoFormattedDate)) {
var values = dateRegex.exec(isoFormattedDate);
var tmpDate = new Date(values[1], values[2] - 1, values[3]);
this.setTime(tmpDate.getTime());
//this.setTime(Date.parse(values[1] + ' ' + values[2] + ' ' + values[3]));
} else if (timeRegex.test(isoFormattedDate)) {
var values = timeRegex.exec(isoFormattedDate);
this.setHours(values[1]);
this.setMinutes(values[2]);
this.setSeconds(values[3]);
}
return this;
};
/**
* Return the iso formatted representation of the date
*
* @return string The iso formatted date
*/
Date.prototype.toIso = function() {
var formattedDate = this.getFullYear() + '-' + Number.padTo(this.getMonth()+1) + '-' + Number.padTo(this.getDate());
formattedDate = formattedDate + 'T' + Number.padTo(this.getHours()) + ':' + Number.padTo(this.getMinutes()) + ':' + Number.padTo(this.getSeconds());
return formattedDate;
};
/**
* Return formatted date
*
* @param string format The date output format
* @optionalparam string[] months The translated months
* @return string The formatted date
*/
Date.prototype.format = function(format, months) {
// The date is formatted
format = format.replace('dddd','dd');
format = format.replace('ddd', 'dd');
format = format.replace('dd', Number.padTo(this.getDate()));
format = format.replace('d', this.getDate());
format = format.replace('yyyy', this.getFullYear());
format = format.replace('yy', (new String(this.getFullYear())).substr(2,2));
format = format.replace('y', (new String(this.getFullYear())).substr(2,2));
// The time is formatted
format = format.replace('HH', Number.padTo(this.getHours()));
format = format.replace('H', this.getHours());
format = format.replace('mm', Number.padTo(this.getMinutes()));
format = format.replace('m', this.getMinutes());
format = format.replace('ss', Number.padTo(this.getSeconds()));
format = format.replace('s', this.getSeconds());
if(format.indexOf('MMMM') != -1 && months && months.length && months[this.getMonth()]){
format = format.replace('MMMM', months[this.getMonth()]);
}else{
format = format.replace('MMMM','MM');
format = format.replace('MMM', 'MM');
format = format.replace('MM', Number.padTo(this.getMonth()+1));
format = format.replace('M', this.getMonth()+1);
}
format = format.replace(/['"]/g,'');
return format;
};
/**
* Returns the week number for this date.
* @return int the week number
*/
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((((this - onejan) / 86400000) + onejan.getDay())/7);
};
var Ticker = new Class({
setOptions: function(options) {
this.options = Object.extend({
speed: 1000,
delay: 5000,
onComplete: Class.empty,
onStart: Class.empty
}, options || {});
},
initialize: function(el,options){
this.setOptions(options);
this.el = $(el).getElement('div');
if (this.el.getElement('hr')) {
var children = this.el.childNodes;
var news = new Array();
news.push(new Element('div'));
for (var i = 0; i < children.length; i++) {
if ($type(children[i]) == 'element' && children[i].tagName.toLowerCase() == 'hr') {
news.push(new Element('div'));
} else if (news.length) {
if ($type(children[i]) == 'element') {
news[news.length - 1].appendChild(children[i]);
} else {
news[news.length - 1].appendChild(children[i]);
}
i--;
}
}
this.el.empty();
for(var i = 0; i < news.length; i ++){
this.el.appendChild(news[i]);
}
this.items = this.el.getElements('div');
if (this.items.length) {
var w = 0;
this.items.each(function(item, index) {
w += item.getSize().size.x;
item.addEvent('mouseenter', function(){
$clear(this.delayedFunction);
}.bind(this));
item.addEvent('mouseleave', function(){
this.next();
}.bind(this));
}.bind(this));
this.el.setStyles({
position: 'absolute',
top: 0,
left: 0,
width: w
});
this.periodical =
this.fx = new Fx.Styles(this.el, {duration:this.options.speed,onComplete:function() {
var i = (this.current == 0) ? this.items.length : this.current;
this.items[i - 1].injectInside(this.el);
this.el.setStyle('left', 0);
}.bind(this)});
this.current = this.items.length;
this.next();
}
}
},
next: function() {
this.current++;
if (this.current >= this.items.length) this.current = 0;
this.fx.start({
top: this.items[this.current].offsetTop,
left: -this.items[this.current].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this.options.delay);
}
});/**
*  Create a waiting panel object
*
*/
var WaitingPanel = Events.extend({
initialize: function(el) {
if($(el).waitingPanel){
return $(el).waitingPanel;
}
this.el = $(el);
this.el.waitingPanel = this;
},
buildObjects : function() {
// the waiting panel layer and fx style are created
this._waitingPanelLayer = new Element('div', {'class': 'WaitingPanel-AjaxLoading','id':'waitingPanel'});
this._waitingFxStyle = new Fx.Style(this._waitingPanelLayer, 'opacity', {duration:100});
this._waitingPanelLayer.injectAfter(document.getElementsByTagName('div')[0]);
this._waitingPanelLayer.setStyle('position', 'absolute');
this._waitingPanelLayer.setStyles({
opacity : 0
});
this._waitingImageLayer = new Element('div', {'class': 'WaitingPanel-AjaxLoadingImage','id':'waitingPanel'});
this._waitingImageFxStyle = new Fx.Style(this._waitingImageLayer, 'opacity', {duration:100});
this._waitingImageLayer.injectAfter(this._waitingPanelLayer);
this._waitingImageLayer.setStyle('position', 'absolute');
this._waitingImageLayer.setStyles({
opacity : 0
});
},
/**
*  Display a waiting panel layer over the element
*/
display : function() {
if (!this._waitingPanelLayer) {
this.buildObjects();
}
// refresh the height of the waiting panel layer
var coordinates = this.el.getCoordinates();
this._waitingPanelLayer.elementTo = this.el;
this._waitingPanelLayer.setStyles({
height : (coordinates.height + 2),
width : (coordinates.width + 2),
left : (coordinates.left - 2),
top : (coordinates.top - 2)
});
this._waitingImageLayer.setStyles({
height : (coordinates.height + 2),
width : (coordinates.width + 2),
left : (coordinates.left - 2),
top : (coordinates.top - 2)
});
this._waitingFxStyle.start(0, 0.5);
this._waitingImageFxStyle.start(0, 1);
},
/**
* Hide the waiting panel
*/
hide : function() {
if (this._waitingPanelLayer.getStyle('opacity') != 0) {
this._waitingFxStyle.start(0.5, 0);
this._waitingImageFxStyle.start(1, 0);
}
}
});/**
*  Create a message panel object
*
*/
var WindowMessagePanel = Events.extend({
initialize: function(el) {
if ($(el).messagePanel) {
return $(el).messagePanel;
}
this.el = $(el);
this.el.messagePanel = this;
},
/**
* Display a given message
* @param string message The message
* @param integer autoClose The autoclose timer in milliseconds
*/
displayMessage : function(message, title ,autoClose) {
$clear(this.autoClose);
if (!this._messageContainer) {
this._container = new Element('div',{'class': 'Component-MessagePanel'});
this._messageContainer = new Element('div', {'class': 'Component-MessagePanel-Content'});
this._messageTitle = new Element('div', {'class': 'Component-MessagePanel-Title'});
this._messageContainerClose = new Element('div', {'class': 'Component-MessagePanel-Close'});
this._messageContainerClose.addEvent('click', this.hideMessage.bind(this));
this._messageContainerClose.setHTML('x');
this._messageTitle.setHTML(title);
this._messageContainerFx = new Fx.Style(this._container, 'opacity', {duration:300});
this._container.injectInside(this.el);
this._messageTitle.injectInside(this._container);
this._messageContainer.injectInside(this._container);
this._messageContainerClose.injectInside(this._container);
this._container.setStyle('position', 'absolute');
this._container.setOpacity(0);
}
this._messageContainer.setHTML(message);
// the waiting panel layer and fx style are created
var containerCoord = this.el.getCoordinates();
this._messageContainerFx.stop();
this._container.setStyles({
'top': (this.el.getCoordinates().height - this._container.getCoordinates().height ) / 2,
'left': (containerCoord.width - 300) / 2,
'width':300,
'min-height':20,
'z-index':10000
});
this._messageContainerFx.start(0, 1);
if (autoClose) {
this.autoClose =  this.hideMessage.delay(autoClose, this);
}
},
getContent : function(){
return this._messageContainer;
},
hideMessage : function() {
$clear(this.autoClose);
this._messageContainerFx.stop();
this._messageContainerFx.start(1, 0);
}
});
window.addEvent('domready', function()
{
if(!document.isInDesignMode() && $('social-links'))
{
$('social-links').getElements('a').each(function(item, index)
{
item.imgSRC = item.getElement('img').getAttribute('src');
item.imgSRCHover = item.imgSRC.replace('grayscaleFilter=1', 'grayscaleFilter=0').replace(/(gausianBlurFilter|selectiveBlurFilter|brightnessFilter|contrastFilter)=(\d+)/g, '$1=0');
item.addEvent('mouseenter', function(evt)
{
item.getElement('img').setAttribute('src', item.imgSRCHover);
});
item.addEvent('mouseleave', function(evt)
{
item.getElement('img').setAttribute('src', item.imgSRC);
});
});
$('copyright').getElements('a').each(function(item, index)
{
item.imgSRC = item.getElement('img').getAttribute('src');
item.imgSRCHover = item.imgSRC.replace('grayscaleFilter=1', 'grayscaleFilter=0').replace(/(gausianBlurFilter|selectiveBlurFilter|brightnessFilter|contrastFilter)=(\d+)/g, '$1=0');
item.addEvent('mouseenter', function(evt)
{
item.getElement('img').setAttribute('src', item.imgSRCHover);
});
item.addEvent('mouseleave', function(evt)
{
item.getElement('img').setAttribute('src', item.imgSRC);
});
});
}
if($('advanced-search-container'))
{
sliderSearch = new Fx.Style('advanced-search-container','height', { duration: 500 });
searchVisible = false;
$('advanced-search-container').setStyle('visibility', 'visible');
if($$('body')[0].hasClass('homepage'))
{
$('search-link').addClass('active');
searchVisible = true;
}
else
{
sliderSearch.set(0);
}
}
if($('search-link'))
{
$('search-link').addEvent('click', function(evt)
{
if(searchVisible == false)
{
$('search-link').addClass('active');
sliderSearch.start(0, 356);
searchVisible = true;
}
else
{
$('search-link').removeClass('active');
sliderSearch.start(356, 0);
searchVisible = false;
}
var e = new Event(evt);
e.stop();
});
}
if ($('junior_btn') && $('adulte_btn') && $('pro_btn') && $('prof_btn') && !window.ie6)
{
createActions('junior_btn');
createActions('adulte_btn');
createActions('pro_btn');
createActions('prof_btn');
}
function createActions(el)
{
var startHeight = 32;
var endHeight = 173;
var encartFx = new Fx.Style($(el).getElement('.encart_content'), 'height', { duration: 700, transition: Fx.Transitions.Quint.easeInOut });
$(el).addEvent('mouseenter', function(event)
{
$clear(encartFx.delay);
var e = new Event(event);
encartFx.delay = encartFx.start.delay(500, encartFx, [startHeight, endHeight]);
e.stop();
}.bind(this));
$(el).addEvent('mouseleave', function(event)
{
$clear(encartFx.delay);
var thisHeight = $(el).getElement('.encart_content').getCoordinates().height;
var e = new Event(event);
encartFx.stop();
encartFx.start(thisHeight, startHeight);
e.stop();
}.bind(this));
}
if ($("quote") && !document.isInDesignMode())
{
var contentQuote = $("quote").innerHTML.split(" ").join("").replace("\n", "");
if ('<divclass="Synergee-Web-Page-Component-Text-Container"></div>' == contentQuote || '<divclass="Synergee-Web-Page-Component-Text-Container"/>' == contentQuote)
{
$("quote_container").setStyle("display", "none");
}
}
if ($("news_txt") && !document.isInDesignMode())
{
var contentNews = $("news_txt").innerHTML.split(" ").join("").replace("\n", "");
if ('<divclass="Synergee-Web-Page-Component-Text-Container"></div>' == contentNews || '<divclass="Synergee-Web-Page-Component-Text-Container"/>' == contentNews)
{
$("news_container").setStyle("display", "none");
}
}
if ($("videos_txt") && !document.isInDesignMode())
{
var contentNews = $("videos_txt").innerHTML.split(" ").join("").replace("\n", "");
if ('<divclass="Synergee-Web-Page-Component-Text-Container"></div>' == contentNews || '<divclass="Synergee-Web-Page-Component-Text-Container"/>' == contentNews)
{
$("videos_container").setStyle("display", "none");
}
}
if ($("category-contener"))
{
var liste = $("category-contener").getElement("ul");
if (!liste || liste.getElements("li").length == 0)
{
//            $("category-contener").setStyle("display", "none");
}
}
$$("#schoolsList ul li.thumbnail .ItemDetails").each(function(item, index)
{
var paddingTop = item.getStyle("padding-top").replace("px", "");
var h3MarginBottom = item.getElement("h3").getStyle("margin-bottom").replace("px", "");
var bottom = - (item.offsetHeight - paddingTop - item.getElement("h3").offsetHeight - h3MarginBottom);
item.setStyle("bottom", bottom + "px");
});
if($("main_content_search_container"))
{
$("main_content_search_container").appearStart = function()
{
$("main_content_search_container").setStyle("display", "block");
$("closeButtonSearch").addEvent('click', function(event)
{
var e = new Event(event);
$("main_content_search_container").hideStart();
e.stop();
});
}
$("main_content_search_container").hideStart = function()
{
$("main_content_search_container").setStyle("display", "none");
$('main_content_search').setHTML("");
}
}
if (!document.isInDesignMode() && !$$("body.internalWindow").length && $("brochure-link"))
{
var link = $("brochure-link").getElement("a");
if (link)
{
var linkUrl = link.getAttribute("href");
$("brochure-img").addEvent("click", function(event)
{
var e = new Event(event);
location.replace(linkUrl.toString());
e.stop();
});
}
}
if ($("quickLinks-contener") && document.isInDesignMode())
{
if ($("schoolDetailSlideShow"))
{
$("schoolDetailSlideShow").setStyle("min-width", "30px");
$("schoolDetailVideo").setStyle("min-width", "30px");
}
if ($("citySlideShow"))
{
$("citySlideShow").setStyle("min-width", "30px");
$("cityVideo").setStyle("min-width", "30px");
}
if ($("countrySlideShow"))
{
$("countrySlideShow").setStyle("min-width", "30px");
$("contentVideo").setStyle("min-width", "30px");
}
}
if ($("temp-warning"))
{
if (document.isInDesignMode())
{
$("temp-warning").setStyle("display", "block");
$("temp-warning").setStyle("left", "300px");
}
else
{
var contentWarning = $("temp-warning").getElement(".Synergee-Web-Page-Component-Text-Container").innerHTML.clean();
if ('' != contentWarning)
{
$("temp-warning").setStyle("display", "block");
$("temp-warning-close").addEvent("click", function(event)
{
$("temp-warning").remove();
});
}
}
}
checkSize();
});
var timer;
window.addEvent('resize', function(){
$clear(timer);
timer = (function(){
checkSize()
}).delay(50);
}.bind(this));
function checkSize()
{
if($('pagePeelcornerSmall') && $('pagePeelcornerBig'))
{
var windowSize = window.getSize();
if(windowSize.size.x < 1124)
{
$('pagePeelcornerSmall').setStyle('display', 'none');
$('pagePeelcornerBig').setStyle('display', 'none');
}
else
{
$('pagePeelcornerSmall').setStyle('display', 'block');
$('pagePeelcornerBig').setStyle('display', 'block');
}
}
}var MyCartLink = new Class({
initialize: function(text, schoolNumber) {
this._text = text;
this._schoolNumber = schoolNumber.toInt();
var xhr = new XHR();
xhr.addEvent('onSuccess', function(quotesNumber) {
this.changeValue(quotesNumber, true);
}.bind(this));
var url = window.getCurrentJsonUrl($('myCartLink'));
if(url.indexOf('.html') == -1){
var newUrl = url.substr(0, url.indexOf('?')) + 'shoppingcart.html' + url.substr(url.indexOf('?'));
url = newUrl;
}
xhr.send(url, '');
this._tips = new Tips($('myCartLink'), {
initialize:function() {
this.fx = new Fx.Style(this.toolTip, 'opacity', {duration: 500, wait: false}).set(0);
},
onShow: function(toolTip) {
this.fx.start(1);
},
onHide: function(toolTip) {
$clear(this.timer);
this.fx.start(0);
},
maxTitleChars: 80,
hideDelay : 7000,
className: 'linkToolTip Tool'
});
$('myCartLink').removeEvents('mouseenter');
$('myCartLink').removeEvents('mousemove');
this._tips.toolTip.addEvent('click', function() {
this.hide();
}.bind(this._tips));
document.addEvent('cartChanged', function(quotes) {
this.changeValue(quotes);
}.bind(this));
},
changeValue : function(value, noEffect) {
if(value == '0'){
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].addClass('Synergee-Web-Page-Component-MyCartLink-Container-UnActive');
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].addClass('UnActive');
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].addEvent('click', function(e){
var event = new Event(e);
event.stop();
});
} else {
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].removeClass('Synergee-Web-Page-Component-MyCartLink-Container-UnActive');
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].removeClass('UnActive');
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].removeEvents('click');
}
if (noEffect) {
this._schoolNumber = value;
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].getElement('a').setHTML(this._text.replace("%0", '<span>' + value + "</span>"));
} else {
if (this._schoolNumber <= value) {
this._tips.start($('myCartLink'));
this._tips.toolTip.setStyle('position', 'absolute');
this._tips.toolTip.setStyle('top', '');
this._tips.position($('myQuoteLink'));
if(this._tips.toolTip.getCoordinates().top < window.pageYOffset){
this._tips.toolTip.setStyle('position', 'fixed');
this._tips.toolTip.setStyle('top', '0');
}
this._tips.show.delay(1000, this._tips);
this._tips.end();
}
this._schoolNumber = value;
$$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].getElement('a').setHTML(this._text.replace("%0", '<span>' + value + "</span>"));
this._numberNode = $$('.Synergee-Web-Page-Component-MyCartLink-Container')[0].getElement('a').getElement('span');
var quoteNumberFx = new Fx.Styles(this._numberNode, {duration:2000, transition: Fx.Transitions.Elastic.easeOut});
var quoteNumberFx2 = new Fx.Styles(this._numberNode, {duration:2000, transition: Fx.Transitions.Elastic.easeOut});
var quoteNumberFx3 = new Fx.Styles(this._numberNode, {duration:500 });
this._numberNode.setStyles({'margin-left':4,'margin-right': 4, 'font-size':25 + 'px'});
quoteNumberFx.start({'margin-left': 0});
quoteNumberFx2.start({'margin-right': 0,'font-size':13 + 'px'});
//            quoteNumberFx3.start.delay(3000, quoteNumberFx3, {'color':'#1A5F8F'});
}
document.fireEvent('cartUpdated', value);
}
});var MyQuotesLink = new Class({
initialize: function(text, quoteNumber) {
this._text = text;
this._quoteNumber = quoteNumber.toInt();
var xhrQuote = new XHR();
xhrQuote.addEvent('onSuccess', function(quotesNumber) {
this.changeValue(quotesNumber, true);
}.bind(this));
var url = window.getCurrentJsonUrl($('myQuoteLink'));
if(url.indexOf('.html') == -1){
var newUrl = url.substr(0, url.indexOf('?')) + 'shoppingcart.html' + url.substr(url.indexOf('?'));
url = newUrl;
}
xhrQuote.send(url, '');
this._tips = new Tips($('myQuoteLink'), {
initialize:function() {
this.fx = new Fx.Style(this.toolTip, 'opacity', {duration: 500, wait: false}).set(0);
},
onShow: function(toolTip) {
this.fx.start(1);
},
onHide: function(toolTip) {
$clear(this.timer);
this.fx.start(0);
},
maxTitleChars: 80,
hideDelay : 7000,
className : 'linkToolTip Tool'
});
$('myQuoteLink').removeEvents('mouseenter');
$('myQuoteLink').removeEvents('mousemove');
this._tips.toolTip.addEvent('click', function() {
this.hide();
}.bind(this._tips));
document.addEvent('quoteChanged', function(quotes) {
this.changeValue(quotes);
}.bind(this));
},
changeValue : function(value, noEffect) {
if(value == '0'){
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].addClass('Synergee-Web-Page-Component-MyQuotesLink-Container-UnActive');
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].addClass('UnActive');
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].addEvent('click', function(e){
var event = new Event(e);
event.stop();
});
} else {
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].removeClass('Synergee-Web-Page-Component-MyQuotesLink-Container-UnActive');
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].removeClass('UnActive');
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].removeEvents('click');
}
if (noEffect) {
this._schoolNumber = value;
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].getElement('a').setHTML(this._text.replace("%0", '<span>' + value + "</span>"));
} else {
if (this._quoteNumber < value && !this._quoteNumber) {
this._tips.start($('myQuoteLink'));
this._tips.toolTip.setStyle('position', 'absolute');
this._tips.toolTip.setStyle('top', '');
this._tips.position($('myQuoteLink'));
if(this._tips.toolTip.getCoordinates().top < window.pageYOffset){
this._tips.toolTip.setStyle('position', 'fixed');
this._tips.toolTip.setStyle('top', '0');
}
this._tips.show.delay(1000, this._tips);
this._tips.end();
}
this._quoteNumber = value;
$$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].getElement('a').setHTML(this._text.replace("%0", '<span>' + value + "</span>"));
this._numberNode = $$('.Synergee-Web-Page-Component-MyQuotesLink-Container')[0].getElement('a').getElement('span');
var quoteNumberFx = new Fx.Styles(this._numberNode, {duration:4000, transition: Fx.Transitions.Elastic.easeOut});
var quoteNumberFx2 = new Fx.Styles(this._numberNode, {duration:4000, transition: Fx.Transitions.Elastic.easeOut});
var quoteNumberFx3 = new Fx.Styles(this._numberNode, {duration:500 });
this._numberNode.setStyles({'margin-left':4,'margin-right': 4, 'font-size':25 + 'px'});
quoteNumberFx.start({'margin-left': 0});
quoteNumberFx2.start({'margin-right': 0,'font-size':13 + 'px'});
//            quoteNumberFx3.start.delay(3000, quoteNumberFx3, {'color':'#1A5F8F'});
}
document.fireEvent('quoteUpdated', value);
}
});var WebsiteSelector = Options.extend({
initialize: function(componentId) {
this._componentId = componentId;
this._websiteList = $(this._componentId + '_siteSelectorLanguageListId');
this._height = this._websiteList.getCoordinates().height - this._websiteList.getStyle('padding-top').toInt() - this._websiteList.getStyle('padding-bottom').toInt();
if (!document.isInDesignMode())
{
this._fxTime = 300;
this.listFx = new Fx.Style($(this._componentId + '_siteSelectorLanguageListId'), 'height', {wait:false, duration:this._fxTime});
$(this._componentId + '_siteSelectorId').addEvent('mouseover', this.displaySiteSelector.bind(this));
$(this._componentId + '_siteSelectorId').addEvent('mouseout', this.hideSiteSelector.bind(this));
this.listFx.set(0);
this._websiteList.setStyle('visibility', 'visible');
}
},
hideSiteSelector : function(e) {
this.listFx.stop();
this.listFx.start(this._height, 0);
},
/**
* Set the height
*/
setHeight : function(height) {
this._height = height;
},
displaySiteSelector : function(e) {
this.listFx.stop();
var height = (this._height < this._websiteList.getCoordinates().height) ? this._height : this._websiteList.getCoordinates().height;
this.listFx.start(height, this._height);
}
});var QuickSearch = Events.extend({
initialize : function(resultContainer, containerType) {
if (containerType) {
this._resultContainer =  $(resultContainer);
}
else {
if($$('.'+resultContainer) && $$('.'+resultContainer).length){
this._resultContainer = $$('.'+resultContainer)[0];
}
}
if (this._resultContainer) {
var defaultValue = $('idQuickSearchTextField').getProperty('value');
function onQuickSearchTextFieldClick() {
if($('idQuickSearchTextField').getProperty('value') == defaultValue)
$('idQuickSearchTextField').setProperty('value', '');
};
function onQuickSearchTextFieldClickOut() {
if($('idQuickSearchTextField').getProperty('value') == '')
$('idQuickSearchTextField').setProperty('value', defaultValue);
};
$('idQuickSearchTextField').addEvent('focus', onQuickSearchTextFieldClick);
$('idQuickSearchTextField').addEvent('blur', onQuickSearchTextFieldClickOut);
$('idQuickSearchTextField').addClass('QuickSearchText');
this._waitingPanel = new WaitingPanel(this._resultContainer);
$('id_QuickSearchForm').addEvent('submit', function(){
this._waitingPanel.display();
}.bind(this));
}
},
highlight : function (oElements, sSearch) {
if (sSearch) {
var searchParts = sSearch.split(' ');
if (oElements && oElements.length) {
for (var i = 0; i < oElements.length; i++) {
for (var j = 0; j < searchParts.length; j++) {
oElements[i].setHTML(oElements[i].innerHTML.replace(new RegExp('(' + searchParts[j] + ')', 'ig'), '<span class="highlighted">$1</span>'));
}
}
}
}
},
handleResponse : function (response) {
if(this._resultContainer){
var recherche = $("idQuickSearchTextField").value;
this._resultContainer.setHTML(response);
$('closeButtonSearch').addEvent('click', function(event)
{
$$('.Synergee-Web-Page-Component-QuickSearch-Results-Content')[0].remove();
});
this.highlight(this._resultContainer.getElements(".Synergee-Web-Page-Component-QuickSearch-Results-Page-Title a"), recherche);
this.highlight(this._resultContainer.getElements(".Synergee-Web-Page-Component-QuickSearch-Results-Page-Description"), recherche);
this.highlight(this._resultContainer.getElements(".Synergee-Web-Page-Component-QuickSearch-Results-Page-Url a"), recherche);
this._waitingPanel.hide();
var nbResults = $$('.Synergee-Web-Page-Component-QuickSearch-Item').length;
if (nbResults > 10 && nbResults <= 100) {
var resultsHelper = new ResultHelper(10, nbResults);
resultsHelper.injectNavBar('Synergee-Web-Page-Component-QuickSearch-NavigationBars', 'button', 'QuickSearchNav', '');
$$('.QuickSearchNavNext').addEvent('click', function (e) {
resultsHelper.nextPage();
if (e.target) e.target.blur();
else e.srcElement.blur();
});
$$('.QuickSearchNavPrevious').addEvent('click', function (e) {
resultsHelper.previousPage();
if (e.target) e.target.blur();
else e.srcElement.blur();
});
resultsHelper.addEvent('onPageChangeBefore', function () {
$$('.Synergee-Web-Page-Component-QuickSearch-Page' + resultsHelper.getCurrentPage()).setStyle('display','none');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).removeClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Selected');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).addClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Default');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).removeClass('QuickSearchNavButtonSelectedColor');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).addClass('QuickSearchNavButtonDefaultColor');
$$('.QuickSearchNavNext').removeClass('QuickSearchNavButtonSelectedColor');
});
resultsHelper.addEvent('onPageChangeAfter', function () {
$$('.Synergee-Web-Page-Component-QuickSearch-Page' + resultsHelper.getCurrentPage()).setStyle('display','block');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).removeClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Default');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).addClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Selected');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).removeClass('QuickSearchNavButtonDefaultColor');
$$('.QuickSearchNav' + resultsHelper.getCurrentPage()).addClass('QuickSearchNavButtonSelectedColor');
$$('.QuickSearchNavPrevious').removeClass('QuickSearchNavButtonSelectedColor');
});
resultsHelper.addEvent('onPageChangeLowerLimit', function () {
$$('.QuickSearchNavPrevious').addClass('QuickSearchNavButtonSelectedColor');
});
resultsHelper.addEvent('onPageChangeUpperLimit', function () {
$$('.QuickSearchNavNext').addClass('QuickSearchNavButtonSelectedColor');
});
for (var i=0; i < resultsHelper.getCountPages(); i++) {
$$('.QuickSearchNav'+i).each(function (e) { e.pageNumber = i; });
$$('.QuickSearchNav'+i).addClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Default');
$$('.QuickSearchNav'+i).addClass('QuickSearchNavButtonDefaultColor');
$$('.QuickSearchNav'+i).addEvent('click', function (e) {
if (e.target) {
resultsHelper.selectPage(e.target.pageNumber);
e.target.blur();
}
else {
resultsHelper.selectPage(e.srcElement.pageNumber);
e.srcElement.blur();
}
});
}
$$('.QuickSearchNav0').removeClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Default');
$$('.QuickSearchNav0').removeClass('QuickSearchNavButtonDefaultColor');
$$('.QuickSearchNav0').addClass('Synergee-Web-Page-Component-QuickSearch-NavigationBars-Selected');
$$('.QuickSearchNav0').addClass('QuickSearchNavButtonSelectedColor');
$$('.QuickSearchNavPrevious').addClass('QuickSearchNavButtonSelectedColor');
}
}
}
});
window.addEvent('domready', function()
{
var heightOnChange = false;
var resizer = null;
var mainStartHeight = 0;
var heightWay = -1;
function resetHeightChecher()
{
heightOnChange = false;
}
function checkHeight(way)
{
heightWay = way;
heightOnChange = true;
resizeMain();
}
function resizeMain()
{
var rightH = $('main-right').getCoordinates().height;
var leftH = $('main').getCoordinates().height;
if (heightOnChange)
{
if (rightH > mainStartHeight)
{
$('main').setStyle("height", rightH + "px");
}
resizer = setTimeout(resizeMain, 50);
}
else
{
if (0 == heightWay)
{
$('main').setStyle("height", "auto");
}
heightWay = -1;
clearTimeout(resizer);
}
}
if ($('ExtendedMenuSlider'))
{
// Some useful functions
$('mainMenu').getDepth = function(element)
{
var depth = 0;
if ($('ExtendedMenuSlider').hasChild(element))
{
var parentEl = element;
while (parentEl != $('ExtendedMenuSlider'))
{
parentEl = parentEl.getParent();
if (parentEl.getTag() == 'ul')depth++;
}
}
return depth;
};
$('mainMenu').toRoot = function()
{
$('ExtendedMenuSlider').fx.start($('ExtendedMenuSlider').getStyle('margin-left'), 0);
};
$('mainMenu').onMouseLeave = function(event)
{
var hideMenu = true;
var waitingDelay = effectWaitingOut;
if (event)
{
event = new Event(event);
if (event.type == 'click' && event.target)
{
var target = event.target;
while (target != null)
{
if (target.getAttribute('id') == 'main-menu-contener')
{
target = null;
hideMenu = false;
}
else
{
target = target.parentNode != document ? target.parentNode : null;
}
}
waitingDelay = 0;
}
}
if (hideMenu)
{
if (window.ie6)
{
checkHeight(0);
}
$clear(menuFx.delay);
if(waitingDelay == 0)menuFx.stop();
var e = new Event(event);
if ($('mainMenu').offsetHeight >= startHeight)
{
menuFx.delay = menuFx.start.delay(waitingDelay, menuFx, [$('mainMenu').offsetHeight, startHeight]);
}
}
};
// The initialisation
$('main-right').setStyle('min-height', '0');
var rightSize = $('main-right').getCoordinates().height;
var menuSize = $('mainMenu').getCoordinates().height;
var mainSize = $('main').getCoordinates().height;
if ($('fullWidth'))
{
mainSize = $('fullWidth').getCoordinates().top - $('main').getCoordinates().top;
}
$('main-right').setStyle('min-height', '');
var margin = 15;
var effectDuration = 700;
var effectWaitingOut = 8000;
var effectWaitingOver = 500;
var rightBlank = (mainSize - rightSize) > 0 ? (mainSize - rightSize) : 0;
rightSize = mainSize > rightSize ? mainSize - margin : rightSize - margin;
$('main-right').setStyle('min-height', rightSize);
var startHeight = rightBlank + menuSize;
startHeight -= (startHeight % 20);
$('mainMenu').setStyle("display", "block");
var menuFx = new Fx.Style($('mainMenu'), 'height', { duration: effectDuration, transition: Fx.Transitions.Quint.easeInOut, onComplete: resetHeightChecher });
$('main-menu-contener').addEvent('mouseenter', function(event)
{
if (window.ie6)
{
checkHeight(1);
}
$clear(menuFx.delay);
menuFx.stop();
var e = new Event(event);
if ($('mainMenu').currentUl)
{
menuFx.delay = menuFx.start.delay(effectWaitingOver, menuFx, [$('mainMenu').currentUl.offsetHeight, menuFx.offset]);
}
e.stop();
}.bind(this));
$('main-menu-contener').addEvent('mouseleave', $('mainMenu').onMouseLeave.bind(this));
$$('body')[0].addEvent('click', $('mainMenu').onMouseLeave.bind(this));
if($('ExtendedMenuSlider'))
{
$('mainMenu').currentUl = $E('ul', $('mainMenu'));
$('ExtendedMenuSlider').fx = new Fx.Style($('ExtendedMenuSlider'), 'margin-left', {duration:500});
$('ExtendedMenuSlider').getElements('ul').setStyle('display', 'none');
$('ExtendedMenuSlider').getElements('span').each(function(item, index)
{
if (item.getParent().getElement('ul'))
{
item.addEvent('mouseenter', function()
{
item.addClass('hover');
});
item.addEvent('mouseleave', function()
{
item.removeClass('hover');
});
item.addEvent('click', function(event)
{
// if the user click on the link, the animation is stopped
if (event)
{
event = new Event(event);
if (event.target && event.target.getTag && event.target.getTag() == 'a')
{
item.removeEvents('mouseleave');
item.addClass('hover');
return;
}else{
// for ie
if (event.target && event.target.tagName.toLowerCase() == 'a'){
item.removeEvents('mouseleave');
item.addClass('hover');
return;
}
}
}
item.getParent().getParent().getElements('ul').setStyle('display', 'none');
var childUL = item.getParent().getElement('ul');
childUL.setStyle('display', '');
// check if the parents are not hidden
if ($('ExtendedMenuSlider').hasChild(item))
{
var parentEl = item;
while (parentEl != $('ExtendedMenuSlider'))
{
parentEl = parentEl.getParent();
if (parentEl.getTag() == 'ul')parentEl.setStyle('display', '');
}
}
// set the height
menuFx.stop();
var height = childUL.getCoordinates().height;
menuFx.start($('mainMenu').getStyle('height'), height);
// slide to the right item
$('ExtendedMenuSlider').fx.start($('ExtendedMenuSlider').getStyle('margin-left'), - ($('mainMenu').getDepth(item) * 294));
$('mainMenu').currentUl = item.getParent().getElement('ul');
});
}
else if (item.hasClass('BackLink'))
{
item.addEvent('click', function()
{
menuFx.stop();
var parent = item.getParent().getParent().getParent().getParent();
var height = parent.getCoordinates().height;
menuFx.start($('mainMenu').getStyle('height'), height);
$('ExtendedMenuSlider').fx.start($('ExtendedMenuSlider').getStyle('margin-left'), -( ($('mainMenu').getDepth(parent)) * 294));
$('mainMenu').currentUl = parent;
});
}
});
}
if ($$('.CurrentPage') && $$('.CurrentPage').length)
{
if ($$('.CurrentPage')[0].getElements('li').length)
{
$$('.CurrentPage')[0].getElement('span').fireEvent('click');
}
else
{
if($$('.CurrentPage')[0].getParent().getAttribute('id') != 'Root')
{
$$('.CurrentPage')[0].getParent().getParent().getElement('span').fireEvent('click');
}else{
$('mainMenu').currentUl = $('ExtendedMenuSlider');
}
}
menuFx.stop();
menuFx.set(startHeight);
}
else
{
if ($('ExtendedMenuSlider'))
{
var parent = $('ExtendedMenuSlider');
var height = parent.getCoordinates().height;
menuFx.set(height);
$('ExtendedMenuSlider').fx.set(0);
$('mainMenu').currentUl = parent;
if(height > startHeight){
menuFx.stop();
menuFx.set(startHeight);
}
}
}
}
}.bind(this));
var SchoolSearch = new Class({
initialize: function(resultContainer, moreOptionsButton, lessOptionsButton, resetButton) {
this.resultContainer = resultContainer;
this.moreOptionsButton = moreOptionsButton;
this.lessOptionsButton = lessOptionsButton;
this.resetButton = resetButton;
// hide the advanced search when page is loaded
// the advanced search slider
var slider = new Fx.Slide($('detailedSearchTableId'));
// hide the advanced search when page is loaded
var advancedMode = false;
slider.hide();
this.lessOptionsButton.setStyle('display', 'none');
// back up the original comboboxes in order to reset them later
var getOptions = function (combo) {
var temp = new Array();
for (var i = 1; i < combo.options.length; i++) {
temp.push({value:combo.options[i].text, id:combo.options[i].value});
}
return temp;
};
this.languageElements = getOptions($('id_form.languageCombobox'));
this.countryElements = getOptions($('id_form.countryCombobox'));
this.cityElements = getOptions($('id_form.cityCombobox'));
this.schoolGroupElements = getOptions($('id_form.schoolGroupCombobox'));
this.schoolProgramElements = getOptions($('id_form.programCombobox'));
this.schoolLevelElements = getOptions($('id_form.levelCombobox'));
this.schoolClimateElements = getOptions($('id_form.climateCombobox'));
this.schoolCourseElements = getOptions($('id_form.courseCombobox'));
this.schoolAccommodationElements = getOptions($('id_form.accommodationCombobox'));
this.schoolPopulationElements = getOptions($('id_form.populationCombobox'));
this.schoolNearTheSeaElements = getOptions($('id_form.nearTheSeaCombobox'));
// reset the combobox values
this.resetButton.addEvent('click', function () {
this.resetComboboxes();
}.bind(this));
// on user click, switch between simple and advanced search
$('detailedSearchButtonId').addEvent('click', function (e) {
slider.toggle();
advancedMode = !advancedMode;
this.lessOptionsButton.setStyle('display', advancedMode ? 'inline' : 'none');
this.moreOptionsButton.setStyle('display', advancedMode ? 'none' : 'inline');
}.bind(this));
// The waiting panel is created
var waitingPanel = new WaitingPanel(this.resultContainer);
// we listen for any change in the form
var formElements = $('schoolSearchFormId').getElements('select').concat($('schoolSearchFormId').getElements('input[id^=id_form]'));
formElements.each(function(formElement) {
formElement.addEvent('change', function (e) {
try {
e.target.currentValue = e.target.getValue();
}
catch (ex) {
e.srcElement.currentValue = e.srcElement.getValue();    // ie
}
$('schoolSearchFormId')._dontDisplayResults = true;
$('schoolSearchFormSubmitId').click();
waitingPanel.display();
});
});
},
resetComboboxes : function (onlyElement) {
if($('id_form.languageCombobox'))this.populateComboBox.bind($('id_form.languageCombobox'))(this.languageElements);
if($('id_form.countryCombobox'))this.populateComboBox.bind($('id_form.countryCombobox'))(this.countryElements);
if($('id_form.cityCombobox'))this.populateComboBox.bind($('id_form.cityCombobox'))(this.cityElements);
if($('id_form.schoolGroupCombobox'))this.populateComboBox.bind($('id_form.schoolGroupCombobox'))(this.schoolGroupElements);
if($('id_form.programCombobox'))this.populateComboBox.bind($('id_form.programCombobox'))(this.schoolProgramElements);
if($('id_form.categoriesCombobox'))this.populateComboBox.bind($('id_form.categoriesCombobox'))(this.schoolCategoryElements);
if($('id_form.levelCombobox'))this.populateComboBox.bind($('id_form.levelCombobox'))(this.schoolLevelElements);
if($('id_form.climateCombobox'))this.populateComboBox.bind($('id_form.climateCombobox'))(this.schoolClimateElements);
if($('id_form.courseCombobox'))this.populateComboBox.bind($('id_form.courseCombobox'))(this.schoolCourseElements);
if($('id_form.accommodationCombobox'))this.populateComboBox.bind($('id_form.accommodationCombobox'))(this.schoolAccommodationElements);
if($('id_form.populationCombobox'))this.populateComboBox.bind($('id_form.populationCombobox'))(this.schoolPopulationElements);
if($('id_form.nearTheSeaCombobox'))this.populateComboBox.bind($('id_form.nearTheSeaCombobox'))(this.schoolNearTheSeaElements);
if (!onlyElement) {
if($('id_form.languageCombobox'))$('id_form.languageCombobox').currentValue = 0;
if($('id_form.countryCombobox'))$('id_form.countryCombobox').currentValue = 0;
if($('id_form.cityCombobox'))$('id_form.cityCombobox').currentValue = 0;
if($('id_form.schoolGroupCombobox'))$('id_form.schoolGroupCombobox').currentValue = 0;
if($('id_form.climateCombobox'))$('id_form.climateCombobox').selectedIndex = 0;
if($('id_form.accommodationCombobox'))$('id_form.accommodationCombobox').selectedIndex = 0;
if($('id_form.levelCombobox'))$('id_form.levelCombobox').selectedIndex = 0;
if($('id_form.courseCombobox'))$('id_form.courseCombobox').selectedIndex = 0;
if($('id_form.programCombobox'))$('id_form.programCombobox').selectedIndex = 0;
if($('id_form.populationCombobox'))$('id_form.populationCombobox').selectedIndex = 0;
if($('id_form.nearTheSeaCombobox'))$('id_form.nearTheSeaCombobox').selectedIndex = 0;
if($('id_form.ageTextField'))$('id_form.ageTextField').value = '';
if($('id_form.categoriesCombobox'))$('id_form.categoriesCombobox').value = '';
}
},
/**
* refresh the comboboxes
*
* @param items List of element to populate the combo
*/
refreshComboBox : function(items) {
var itemIds = new Hash();
items.each(function(item) {
itemIds.set(item.id, true);
}.bind(this));
for (var i = this.options.length - 1; i > 0; i--) {
this.options[i].setStyle('display', '');
if (!itemIds.hasKey(this.options[i].value)) {
this.options[i].setStyle('display', 'none');
}
}
},
/**
* Populate the comboboxes
*
* @param items List of element to populate the combo
*/
populateComboBox : function (items) {
// first we empty the combobox
for (var i = this.options.length - 1; i > 0; i--) {
this.options[i] = null;
}
// we populate with the items
items.each(function (item) {
var elem = new Element('option');
elem.text = decodeHtmlEntities(item.value);
elem.value = item.id;
try {
this.add(elem, null);
} catch(ex) {
this.add(elem);
}
}, this);
},
// needed to select the correct item when the combobox is modified
selectComboBoxCurrentValue : function () {
if (this.currentValue) {
for (var i = 0; i < this.length; i++) {
if (this.currentValue == this.options[i].value) {
this.selectedIndex = i;
break;
}
}
}
},
// display the search results
form_method : function(response) {
//        alert('toto')
//        $('leftColumnContainer').setStyle('display', 'block');
//        $('leftColumnContainer').addClass('SchoolSearchActivated');
this.resultContainer.setStyle('display', 'block');
// The comboboxes are limited
if ($('id_form.countryCombobox') && response.countries.length > 0) {
this.refreshComboBox.bind($('id_form.countryCombobox'))(response.countries);
}
if ($('id_form.cityCombobox') && response.cities.length > 0) {
this.refreshComboBox.bind($('id_form.cityCombobox'))(response.cities);
}
if ($('id_form.schoolGroupCombobox') && response.schoolGroups.length > 0) {
this.refreshComboBox.bind($('id_form.schoolGroupCombobox'))(response.schoolGroups);
}
if ($('id_form.programCombobox') && response.continents.length > 0) {
this.refreshComboBox.bind($('id_form.programCombobox'))(response.schoolPrograms);
}
if($('id_form.categoriesCombobox'))this.refreshComboBox.bind($('id_form.categoriesCombobox'))(response.categories);
if($('id_form.levelCombobox'))this.refreshComboBox.bind($('id_form.levelCombobox'))(response.levels);
if($('id_form.climateCombobox'))this.refreshComboBox.bind($('id_form.climateCombobox'))(response.climate);
if($('id_form.courseCombobox'))this.refreshComboBox.bind($('id_form.courseCombobox'))(response.courseTypes);
if($('id_form.accommodationCombobox'))this.refreshComboBox.bind($('id_form.accommodationCombobox'))(response.accommodationTypes);
if($('id_form.populationCombobox'))this.refreshComboBox.bind($('id_form.populationCombobox'))(response.populations);
if($('id_form.nearTheSeaCombobox'))this.refreshComboBox.bind($('id_form.nearTheSeaCombobox'))(response.nearTheSea);
if($('id_form.countryCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.countryCombobox'))();
if($('id_form.cityCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.cityCombobox'))();
if($('id_form.schoolGroupCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.schoolGroupCombobox'))();
if($('id_form.programCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.programCombobox'))();
if($('id_form.categoriesCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.categoriesCombobox'))();
if($('id_form.levelCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.levelCombobox'))();
if($('id_form.climateCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.climateCombobox'))();
if($('id_form.courseCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.courseCombobox'))();
if($('id_form.accommodationCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.accommodationCombobox'))();
if($('id_form.populationCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.populationCombobox'))();
if($('id_form.nearTheSeaCombobox'))this.selectComboBoxCurrentValue.bind($('id_form.nearTheSeaCombobox'))();
if (!$('schoolSearchFormId')._dontDisplayResults) {
this.resultContainer.setHTML(response.html);
$("main_content_search_container").appearStart();
var nbResults = $$('.Synergee-Web-Page-Component-SchoolSearch-Results-Item').length;
var results = new ResultHelper(12, nbResults);
results.injectNavBar('SchoolSearchResultNavCount', 'button', 'NavClass', '');
$$('.NavPrevious').addClass('NavSelectedColor');
$$('.NavClass0').setStyles('border-style:solid;border-width:1px;');
$$('.NavClass0').addClass('NavSelectedColor');
$$('.NavNext').addEvent('click', function (e) {
results.nextPage();
if (e.target) e.target.blur();
else e.srcElement.blur();
});
$$('.NavPrevious').addEvent('click', function (e) {
results.previousPage();
if (e.target) e.target.blur();
else e.srcElement.blur();
});
results.addEvent('onPageChangeBefore', function (e) {
$$('.SchoolSearchResult-Class' + results.getCurrentPage()).setStyle('display', 'none');
$$('.NavClass' + results.getCurrentPage()).setStyles('border-style:none;');
$$('.NavClass' + results.getCurrentPage()).removeClass('NavSelectedColor');
});
results.addEvent('onPageChangeAfter', function (e) {
$$('.SchoolSearchResult-Class' + results.getCurrentPage()).setStyle('display', 'block');
$$('.NavClass' + results.getCurrentPage()).setStyles('border-style:solid;border-width:1px;');
$$('.NavClass' + results.getCurrentPage()).addClass('NavSelectedColor');
$$('.NavNext').removeClass('NavSelectedColor');
$$('.NavPrevious').removeClass('NavSelectedColor');
});
results.addEvent('onPageChangeLowerLimit', function (e) {
$$('.NavPrevious').addClass('NavSelectedColor');
});
results.addEvent('onPageChangeUpperLimit', function (e) {
$$('.NavNext').addClass('NavSelectedColor');
});
for (var i = 0; i < results.getCountPages(); i++) {
var navClass = $$('.NavClass' + i);
navClass.each(function (e) {
e.pageNumber = i;
});
navClass.addClass('NavDefaultColor');
navClass.addEvent('click', function (e) {
if (e.target) {
results.selectPage(e.target.pageNumber);
e.target.blur();
}
else {
results.selectPage(e.srcElement.pageNumber);
e.srcElement.blur();
}
});
}
}
$('schoolSearchFormId')._dontDisplayResults = false;
this.resultContainer.waitingPanel.hide();
return true;
}
});
/*
Copyright (c) 2006-7, Tom Carden, Steve Coast, Mikel Maron, Andrew Turner
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 the Mapstraction 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.
*/
// Use http://jsdoc.sourceforge.net/ to generate documentation
////////////////////////////
//
// utility to functions, TODO namespace or remove before release
//
///////////////////////////
/**
* $, the dollar function, elegantising getElementById()
* @returns an element
*/
function $m() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}
/**
* loadScript is a JSON data fetcher
*/
function loadScript(src,callback) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
if (callback) {
var evl=new Object();
evl.handleEvent=function (e){callback();};
script.addEventListener('load',evl,true);
}
document.getElementsByTagName("head")[0].appendChild(script);
return;
}
function convertLatLonXY_Yahoo(point,level){ //Mercator
var size = 1 << (26 - level);
var pixel_per_degree = size / 360.0;
var pixel_per_radian = size / (2 * Math.PI);
var origin = new YCoordPoint(size / 2 , size / 2);
var answer = new YCoordPoint();
answer.x = Math.floor(origin.x + point.lon * pixel_per_degree);
var sin = Math.sin(point.lat * Math.PI / 180.0);
answer.y = Math.floor(origin.y + 0.5 * Math.log((1 + sin) / (1 - sin)) * -pixel_per_radian);
return answer;
}
/**
*
*/
function loadStyle(href) {
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = href;
document.getElementsByTagName("head")[0].appendChild(link);
return;
}
/**
* getStyle provides cross-browser access to css
*/
function getStyle(el, prop) {
var y;
if (el.currentStyle)
y = el.currentStyle[prop];
else if (window.getComputedStyle)
y = window.getComputedStyle( el, '').getPropertyValue(prop);
return y;
}
// longitude to metres
// http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM
// "A degree of longitude at the equator is 111.2km... For other latitudes,
// multiply by cos(lat)"
// assumes the earth is a sphere but good enough for our purposes
function lonToMetres (lon,lat) {
return lon * 111200 * Math.cos(lat * (Math.PI/180));
}
function metresToLon(m,lat) {
return m / (111200*Math.cos(lat * (Math.PI/180)));
}
// stuff to convert google zoom levels to/from degrees
// assumes zoom 0 = 256 pixels = 360 degrees
//         zoom 1 = 256 pixels = 180 degrees
// etc.
function getDegreesFromGoogleZoomLevel (pixels,zoom)
{
return (360*pixels) / (Math.pow(2,zoom+8));
}
function getGoogleZoomLevelFromDegrees (pixels,degrees)
{
return logN ((360*pixels)/degrees, 2) - 8;
}
function logN (number,base)
{
return Math.log(number) / Math.log(base);
}
/////////////////////////////
//
// Mapstraction proper begins here
//
/////////////////////////////
/**
* Mapstraction instantiates a map with some API choice into the HTML element given
* @param {String} element The HTML element to replace with a map
* @param {String} api The API to use, one of 'google', 'yahoo', 'microsoft', 'openstreetmap', 'multimap', 'map24', 'openlayers', 'mapquest'
* @param {Bool} debug optional parameter to turn on debug support - this uses alert panels for unsupported actions
* @constructor
*/
function Mapstraction(element,api,debug) {
this.api = api; // could detect this from imported scripts?
this.maps = new Object();
this.currentElement = $m(element);
this.eventListeners = new Array();
this.markers = new Array();
this.polylines = new Array();
this.images = new Array();
this.loaded = new Object();
this.onload = new Object();
// optional debug support
if(debug == true)
this.debug = true
else
this.debug = false
// This is so that it is easy to tell which revision of this file
// has been copied into other projects.
this.svn_revision_string = '$Revision$';
this.addControlsArgs = new Object();
this.addAPI($m(element),api);
}
/**
* swap will change the current api on the fly
* @param {String} api The API to swap to
*/
Mapstraction.prototype.swap = function(element,api) {
if (this.api == api) { return; }
var center = this.getCenter();
var zoom = this.getZoom();
this.currentElement.style.visibility = 'hidden';
this.currentElement.style.display = 'none';
this.currentElement = $m(element);
this.currentElement.style.visibility = 'visible';
this.currentElement.style.display = 'block';
this.api = api;
if (this.maps[this.api] == undefined) {
this.addAPI($m(element),api);
this.setCenterAndZoom(center,zoom);
for (var i=0; i<this.markers.length; i++) {
this.addMarker( this.markers[i], true);
}
for (var i=0; i<this.polylines.length; i++) {
this.addPolyline( this.polylines[i], true);
}
}else{
//sync the view
this.setCenterAndZoom(center,zoom);
//TODO synchronize the markers and polylines too
// (any overlays created after api instantiation are not sync'd)
}
this.addControls(this.addControlsArgs);
}
Mapstraction.prototype.addAPI = function(element,api) {
me = this;
this.loaded[api] = false;
this.onload[api] = new Array();
switch (api) {
case 'yahoo':
if (YMap) {
this.maps[api] = new YMap(element);
YEvent.Capture(this.maps[api],EventsList.MouseClick,function(event,location) { me.clickHandler(location.Lat,location.Lon,location,me) });
YEvent.Capture(this.maps[api],EventsList.changeZoom,function() { me.moveendHandler(me) });
YEvent.Capture(this.maps[api],EventsList.endPan,function() { me.moveendHandler(me) });
this.loaded[api] = true;
}
else {
alert('Yahoo map script not imported');
}
break;
case 'google':
if (GMap2) {
if (GBrowserIsCompatible()) {
this.maps[api] = new GMap2(element);
GEvent.addListener(this.maps[api], 'click', function(marker,location) {
// If the user puts their own Google markers directly on the map
// then there is no location and this event should not fire.
if ( location ) {
me.clickHandler(location.y,location.x,location,me);
}
});
GEvent.addListener(this.maps[api], 'moveend', function() {me.moveendHandler(me)});
this.loaded[api] = true;
}
else {
alert('browser not compatible with Google Maps');
}
}
else {
alert('Google map script not imported');
}
break;
case 'microsoft':
if (VEMap) {
element.style.position='relative';
var msft_width = parseFloat(getStyle($m(element),'width'));
var msft_height = parseFloat(getStyle($m(element),'height'));
/* Hack so the VE works with FF2 */
var ffv = 0;
var ffn = "Firefox/";
var ffp = navigator.userAgent.indexOf(ffn);
if (ffp != -1) ffv = parseFloat(navigator.userAgent.substring(ffp+ffn.length));
if (ffv >= 1.5) {
Msn.Drawing.Graphic.CreateGraphic=function(f,b) { return new Msn.Drawing.SVGGraphic(f,b) }
}
this.maps[api] = new VEMap(element.id);
this.maps[api].LoadMap();
this.maps[api].AttachEvent("onclick", function(e) { me.clickHandler(e.view.LatLong.Latitude, e.view.LatLong.Longitude, me); });
this.maps[api].AttachEvent("onchangeview", function(e) {me.moveendHandler(me)});
//Source of our trouble with Mapufacture?
this.resizeTo(msft_width, msft_height);
this.loaded[api] = true;
}
else {
alert('Virtual Earth script not imported');
}
break;
case 'openlayers':
this.maps[api] = new OpenLayers.Map(element.id);
this.loaded[api] = true;
break;
case 'openstreetmap':
// for now, osm is a hack on top of google
if (GMap2) {
if (GBrowserIsCompatible()) {
this.maps[api] = new GMap2(element);
GEvent.addListener(this.maps[api], 'click', function(marker,location) {
// If the user puts their own Google markers directly on the map
// then there is no location and this event should not fire.
if ( location ) {
me.clickHandler(location.y,location.x,location,me);
}
});
GEvent.addListener(this.maps[api], 'moveend', function() {me.moveendHandler(me)});
// Add OSM tiles
var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, "copyleft");
var copyrightCollection = new GCopyrightCollection('OSM');
copyrightCollection.addCopyright(copyright);
var tilelayers = new Array();
tilelayers[0] = new GTileLayer(copyrightCollection, 1, 18);
tilelayers[0].getTileUrl = function (a, b) {
return "http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png";
};
tilelayers[0].isPng = function() { return true;};
tilelayers[0].getOpacity = function() { return 1.0; }
var custommap = new GMapType(tilelayers, new GMercatorProjection(19), "OSM", {errorMessage:"More OSM coming soon"});
this.maps[api].addMapType(custommap);
this.loaded[api] = true;
var myPoint = new LatLonPoint(50.6805,-1.4062505);
this.setCenterAndZoom(myPoint, 11);
this.maps[api].setMapType(custommap);
}
else {
alert('browser not compatible with Google Maps');
}
}
else {
alert('Google map script not imported');
}
break;
case 'multimap':
this.maps[api] = new MultimapViewer( element );
this.maps[api].addEventHandler( 'click', function(eventType, eventTarget, arg1, arg2, arg3) {
if (arg1) {
me.clickHandler(arg1.lat, arg1.lon, me);
}
});
this.maps[api].addEventHandler( 'changeZoom', function(eventType, eventTarget, arg1, arg2, arg3) {
me.moveendHandler(me);
});
this.maps[api].addEventHandler( 'endPan', function(eventType, eventTarget, arg1, arg2, arg3) {
me.moveendHandler(me);
});
this.loaded[api] = true;
break;
case 'map24':
// Copied from Google and modified
if (Map24) {
Map24.loadApi(["core_api","wrapper_api"] , function() {
Map24.MapApplication.init
( { NodeName: element.id, MapType: "Static" } );
me.maps[api] = Map24.MapApplication.Map;
Map24.MapApplication.Map.addListener('Map24.Event.MapClick',
function(e) {
me.clickHandler(e.Coordinate.Latitude/60,
e.Coordinate.Longitude/60,
me);
e.stop();
}
);
Map24.MapApplication.Map.addListener("MapPanStop",
function(e) {
me.moveendHandler(me);
}
);
/**/
var client=Map24.MapApplication.Map.MapClient['Static'];
/*
These *will* cause the specified listener to run when we stop
panning the map, but the default pan stop handler will be
cancelled. The result of this will be that when we have stopped
panning, we will permanently be in 'pan' mode and unable to do
anything else (e.g. click on the map to create a new marker).
var defaultOnPanStop = client.onPanStop;
var defaultOnZoomInStop = client.onZoomInStop;
var defaultOnZoomOutStop = client.onZoomOutStop;
client.onPanStop = function(e)
{ me.moveendHandler(me); defaultOnPanStop(e);
status('DEFAULTONPANSTOP DONE');}
// Handle zoom events - these also fire moveendHandler for the
// other APIs in Mapstraction
client.onZoomInStop = function(e)
{ me.moveendHandler(me); defaultOnZoomInStop(e); }
client.onZoomOutStop = function(e)
{ me.moveendHandler(me); defaultOnZoomOutStop(e);  }
*/
me.loaded[api] = true;
for (var i = 0; i < me.onload[api].length; i++) {
me.onload[api][i]();
}
}, "2.0.1247" );
} else {
alert('map24 api not loaded');
}
break;
case 'mapquest':
MQInitOverlays( function() {
self.loaded[api] = true;
self.maps[api] = new MQTileMap(element);
for (var i = 0; i < self.onload[api].length; i++) {
self.onload[api][i]();
}
});
// MQEventManager.addListener(this.maps[api],"click",function(event,location) { me.clickHandler(location.Lat,location.Lon,location,me) });
// MQEventManager.addListener(this.maps[api],"zoomend",function() { me.moveendHandler(me) });
// MQEventManager.addListener(this.maps[api],"moveend",function() { me.moveendHandler(me) });
break;
case 'freeearth':
this.maps[api] = new FE.Map($m(element));
self = this;
this.maps[api].onLoad = function() {
self.freeEarthLoaded = true;
self.loaded[api] = true;
for (var i = 0; i < self.onload[api].length; i++) {
self.onload[api][i]();
}
}
this.maps[api].load();
break;
default:
if(this.debug)
alert(api + ' not supported by mapstraction');
}
// this.resizeTo(getStyle($m(element),'width'), getStyle($m(element),'height'));
// the above line was called on all APIs but MSFT alters with the div size when it loads
// so you have to find the dimensions and set them again (see msft constructor).
// FIXME: test if google/yahoo etc need this resize called. Also - getStyle returns
// CSS size ('200px') not an integer, and resizeTo seems to expect ints
}
/* Returns the loaded state of a Map Provider
*
* @param {String} api Optional API to query for. If not specified, returns state of the originally created API
* @returns the state of the map loading
* @type Boolean
*/
Mapstraction.prototype.isLoaded = function(api){
if(api == null)
api = this.api;
return this.loaded[api];
}
/* Set the debugging on or off - shows alert panels for functions that don't exist in Mapstraction
*
* @param {Bool} debug true to turn on debugging, false to turn it off
* @returns the state of debugging
* @type Boolean
*/
Mapstraction.prototype.setDebug = function(debug){
if(debug != null)
return this.debug = debug;
else
return this.debug;
}
/* Resize the current map to the specified width and height
* (since it is actually on a child div of the mapElement passed
* as argument to the Mapstraction constructor, the resizing of this
* mapElement may have no effect on the size of the actual map)
*
* @param {int} width The width the map should be.
* @param {int} height The width the map should be.
*/
Mapstraction.prototype.resizeTo = function(width,height){
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.resizeTo(width,height); } );
return;
}
switch (this.api) {
case 'yahoo':
this.maps[this.api].resizeTo(new YSize(width,height));
break;
case 'google':
case 'openstreetmap':
this.currentElement.style.width = width;
this.currentElement.style.height = height;
this.maps[this.api].checkResize();
break;
case 'microsoft':
this.maps[this.api].Resize(width, height);
break;
case 'multimap':
this.currentElement.style.width = width;
this.currentElement.style.height = height;
this.maps[this.api].resize();
break;
case 'mapquest':
this.currentElement.style.width = width;
this.currentElement.style.height = height;
this.maps[this.api].setSize(new MQSize(width, height));
break;
case 'map24':
Map24.MapApplication.Map.Canvas['c'].resizeTo(width,height);
break;
}
}
/////////////////////////
//
// Event Handling
//
///////////////////////////
Mapstraction.prototype.clickHandler = function(lat,lon, me) { //FIXME need to consolidate some of these handlers...
for(var i = 0; i < this.eventListeners.length; i++) {
if(this.eventListeners[i][1] == 'click') {
this.eventListeners[i][0](new LatLonPoint(lat,lon));
}
}
}
Mapstraction.prototype.moveendHandler = function(me) {
for(var i = 0; i < this.eventListeners.length; i++) {
if(this.eventListeners[i][1] == 'moveend') {
this.eventListeners[i][0]();
}
}
}
Mapstraction.prototype.addEventListener = function(type, func) {
var listener = new Array();
listener.push(func);
listener.push(type);
this.eventListeners.push(listener);
}
////////////////////
//
// map manipulation
//
/////////////////////
/**
* addControls adds controls to the map. You specify which controls to add in
* the associative array that is the only argument.
* addControls can be called multiple time, with different args, to dynamically change controls.
*
* args = {
*     pan:      true,
*     zoom:     'large' || 'small',
*     overview: true,
*     scale:    true,
*     map_type: true,
* }
*
* @param {args} array Which controls to switch on
*/
Mapstraction.prototype.addControls = function( args ) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addControls(args); } );
return;
}
var map = this.maps[this.api];
this.addControlsArgs = args;
switch (this.api) {
case 'google':
case 'openstreetmap':
//remove old controls
if (this.controls) {
while (ctl = this.controls.pop()) {
map.removeControl(ctl);
}
} else {
this.controls = new Array();
}
c = this.controls;
// Google has a combined zoom and pan control.
if ( args.zoom || args.pan ) {
if ( args.zoom == 'large' ) {
c.unshift(new GLargeMapControl());
map.addControl(c[0]);
} else {
c.unshift(new GSmallMapControl());
map.addControl(c[0]);
}
}
if ( args.scale    ) { c.unshift(new GScaleControl()); map.addControl(c[0]); }
if (this.api != "openstreetmap") {
if ( args.overview ) { c.unshift(new GOverviewMapControl()); map.addControl(c[0]); }
if ( args.map_type ) { c.unshift(new GMapTypeControl()); map.addControl(c[0]); }
}
break;
case 'yahoo':
if ( args.pan             ) map.addPanControl();
else map.removePanControl();
if ( args.zoom == 'large' ) map.addZoomLong();
else if ( args.zoom == 'small' ) map.addZoomShort();
else map.removeZoomScale();
break;
case 'openlayers':
// FIXME - which one should this be?
map.addControl(new OpenLayers.Control.LayerSwitcher());
break;
case 'multimap':
//FIXME -- removeAllWidgets();  -- can't call addControls repeatedly
pan_zoom_widget = "MM";
if (args.zoom && args.zoom == "small") { pan_zoom_widget = pan_zoom_widget + "Small"; }
if (args.pan) { pan_zoom_widget = pan_zoom_widget + "Pan"; }
if (args.zoom) { pan_zoom_widget = pan_zoom_widget + "Zoom"; }
pan_zoom_widget = pan_zoom_widget + "Widget";
if (pan_zoom_widget != "MMWidget") {
eval(" map.addWidget( new " + pan_zoom_widget + "() );");
}
if ( args.map_type ) { map.addWidget( new MMMapTypeWidget() ); }
if ( args.overview ) { map.addWidget( new MMOverviewWidget() ); }
break;
case 'mapquest':
//remove old controls
if (this.controls) {
while (ctl = this.controls.pop()) {
map.removeControl(ctl);
}
} else {
this.controls = new Array();
}
c = this.controls;
if ( args.pan ) { c.unshift(new MQPanControl()); map.addControl(c[0], new MQMapCornerPlacement(MQMapCorner.TOP_LEFT, new MQSize(0,0))); }
if ( args.zoom == 'large' ) { c.unshift(new MQLargeZoomControl()); map.addControl(c[0], new MQMapCornerPlacement(MQMapCorner.TOP_LEFT, new MQSize(0,0))); }
else if ( args.zoom == 'small' ) { c.unshift(new MQZoomControl()); map.addControl(c[0],  new MQMapCornerPlacement(MQMapCorner.BOTTOM_LEFT, new MQSize(0,0))); }
// TODO: Map View Control is wonky
if ( args.map_type ) { c.unshift(new MQViewControl()); map.addControl(c[0], new MQMapCornerPlacement(MQMapCorner.TOP_RIGHT, new MQSize(0,0))); }
break;
}
}
/**
* addSmallControls adds a small map panning control and zoom buttons to the map
* Supported by: yahoo, google, openstreetmap, openlayers, multimap, mapquest
*/
Mapstraction.prototype.addSmallControls = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addSmallControls(); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.addPanControl();
map.addZoomShort();
this.addControlsArgs.pan = true;
this.addControlsArgs.zoom = 'small';
break;
case 'google':
case 'openstreetmap':
map.addControl(new GSmallMapControl());
this.addControlsArgs.zoom = 'small';
break;
case 'openlayers':
map.addControl(new OpenLayers.Control.LayerSwitcher());
break;
case 'multimap':
smallPanzoomWidget = new MMSmallPanZoomWidget();
map.addWidget( smallPanzoomWidget );
this.addControlsArgs.pan = true;
this.addControlsArgs.zoom = 'small';
break;
case 'mapquest':
map.addControl(new MQZoomControl(map));
map.addControl(new PanControl(map));
this.addControlsArgs.pan = true;
this.addControlsArgs.zoom = 'small';
break;
}
}
/**
* addLargeControls adds a small map panning control and zoom buttons to the map
* Supported by: yahoo, google, openstreetmap, multimap, mapquest
*/
Mapstraction.prototype.addLargeControls = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addLargeControls(); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.addPanControl();
map.addZoomLong();
this.addControlsArgs.pan = true;  // keep the controls in case of swap
this.addControlsArgs.zoom = 'large';
break;
case 'google':
map.addControl(new GMapTypeControl());
map.addControl(new GOverviewMapControl()) ;
this.addControlsArgs.overview = true;
this.addControlsArgs.map_type = true;
case 'openstreetmap':
map.addControl(new GLargeMapControl());
map.addControl(new GScaleControl()) ;
this.addControlsArgs.pan = true;
this.addControlsArgs.zoom = 'large';
this.addControlsArgs.scale = true;
break;
case 'multimap':
panzoomWidget = new MMPanZoomWidget();
map.addWidget( panzoomWidget );
this.addControlsArgs.pan = true;  // keep the controls in case of swap
this.addControlsArgs.zoom = 'large';
break;
case 'mapquest':
map.addControl(new MQLargeZoomControl(map));
map.addControl(new PanControl(map));
map.addControl(new MQViewControl(map));
this.addControlsArgs.pan = true;
this.addControlsArgs.zoom = 'large';
this.addControlsArgs.map_type = true;
break;
}
}
/**
* addMapTypeControls adds a map type control to the map (streets, aerial imagery etc)
* Supported by: yahoo, google, openstreetmap, multimap, mapquest
*/
Mapstraction.prototype.addMapTypeControls = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addMapTypeControls(); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.addTypeControl();
break;
case 'google':
case 'openstreetmap':
map.addControl(new GMapTypeControl());
break;
case 'multimap':
map.addWidget( new MMMapTypeWidget() );
break;
case 'mapquest':
map.addControl(new MQViewControl(map));
break;
}
}
/**
* dragging
*  enable/disable dragging of the map
*  (only implemented for yahoo and google)
* Supported by: yahoo, google, openstreetmap, multimap
* @param {on} on Boolean
*/
Mapstraction.prototype.dragging = function(on) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.dragging(on); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'google':
case 'openstreetmap':
if (on) {
map.enableDragging();
} else {
map.disableDragging();
}
break;
case 'yahoo':
if (on) {
map.enableDragMap();
} else {
map.disableDragMap();
}
break;
case 'multimap':
if (on) {
map.setOption("drag","dragmap");
} else {
map.setOption("drag","");
}
break;
case 'mapquest':
map.enableDragging(on);
break;
}
}
/**
* centers the map to some place and zoom level
* @param {LatLonPoint} point Where the center of the map should be
* @param {int} zoom The zoom level where 0 is all the way out.
*/
Mapstraction.prototype.setCenterAndZoom = function(point, zoom) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setCenterAndZoom(point, zoom); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
var yzoom = 18 - zoom; // maybe?
map.drawZoomAndCenter(point.toYahoo(),yzoom);
break;
case 'google':
case 'openstreetmap':
map.setCenter(point.toGoogle(), zoom);
break;
case 'microsoft':
map.SetCenterAndZoom(point.toMicrosoft(),zoom);
break;
case 'openlayers':
map.setCenter(new OpenLayers.LonLat(point.lng, point.lat), zoom);
break;
case 'multimap':
map.goToPosition( new MMLatLon( point.lat, point.lng ) );
map.setZoomFactor( zoom );
break;
case 'map24':
var newSettings = new Object();
newSettings.Latitude = point.lat*60;
newSettings.Longitude = point.lon*60;
var client = map.MapClient['Static'];
var dLon = getDegreesFromGoogleZoomLevel
(client.getCanvasSize().Width,zoom);
newSettings.MinimumWidth = lonToMetres (dLon, point.lat);
Map24.MapApplication.center ( newSettings );
break;
case 'mapquest':
// MapQuest's zoom levels appear to be off by '3' from the other providers for the same bbox
map.setCenter(new MQLatLng( point.lat, point.lng ), zoom - 3 );
break;
case 'freeearth':
if (this.freeEarthLoaded) {
map.setTargetLatLng( point.toFreeEarth() );
} else {
self = this;
this.freeEarthOnLoad.push( function() { self.setCenterAndZoom(point); } );
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setCenterAndZoom');
}
}
/**
* addMarker adds a marker pin to the map
* @param {Marker} marker The marker to add
* @param {old} old If true, doesn't add this marker to the markers array. Used by the "swap" method
*/
Mapstraction.prototype.addMarker = function(marker,old) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addMarker(marker, old); } );
return;
}
var map = this.maps[this.api];
marker.api = this.api;
marker.map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
var ypin = marker.toYahoo();
marker.setChild(ypin);
map.addOverlay(ypin);
if (! old) { this.markers.push(marker); }
break;
case 'google':
case 'openstreetmap':
var gpin = marker.toGoogle();
marker.setChild(gpin);
map.addOverlay(gpin);
if (! old) { this.markers.push(marker); }
break;
case 'microsoft':
var mpin = marker.toMicrosoft();
marker.setChild(mpin); // FIXME: MSFT maps remove the pin by pinID so this isn't needed?
map.AddPushpin(mpin);
if (! old) { this.markers.push(marker); }
break;
case 'openlayers':
//this.map.addPopup(new OpenLayers.Popup("chicken", new OpenLayers.LonLat(5,40), new OpenLayers.Size(200,200), "example popup"));
break;
case 'multimap':
var mmpin = marker.toMultiMap();
marker.setChild(mmpin);
map.addOverlay(mmpin);
if (! old) { this.markers.push(marker); }
break;
case 'map24':
var m24pin = marker.toMap24();
marker.setChild(m24pin);
m24pin.commit();
if (! old) { this.markers.push(marker); }
break;
case 'mapquest':
var mqpin = marker.toMapQuest();
marker.setChild(mqpin);
map.addPoi(mqpin);
if (! old) { this.markers.push(marker); }
break;
case 'freeearth':
var fepin = marker.toFreeEarth();
marker.setChild(fepin);
map.addOverlay(fepin);
if (! old) { this.markers.push(marker); }
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.addMarker');
}
}
/**
* addMarkerWithData will addData to the marker, then add it to the map
* @param{marker} marker The marker to add
* @param{data} data A data has to add
*/
Mapstraction.prototype.addMarkerWithData = function(marker,data) {
marker.addData(data);
this.addMarker(marker);
}
/**
* addPolylineWithData will addData to the polyline, then add it to the map
* @param{polyline} polyline The polyline to add
* @param{data} data A data has to add
*/
Mapstraction.prototype.addPolylineWithData = function(polyline,data) {
polyline.addData(data);
this.addPolyline(polyline);
}
/**
* removeMarker removes a Marker from the map
* @param {Marker} marker The marker to remove
*/
Mapstraction.prototype.removeMarker = function(marker) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.removeMarker(marker); } );
return;
}
var map = this.maps[this.api];
var tmparray = new Array();
while(this.markers.length > 0){
current_marker = this.markers.pop();
if(marker == current_marker) {
switch (this.api) {
case 'google':
case 'openstreetmap':
map.removeOverlay(marker.proprietary_marker);
break;
case 'yahoo':
map.removeOverlay(marker.proprietary_marker);
break;
case 'microsoft':
map.DeletePushpin(marker.pinID);
break;
case 'multimap':
map.removeOverlay(marker.proprietary_marker);
break;
case 'mapquest':
map.removePoi(marker.proprietary_marker);
break;
case 'map24':
marker.proprietary_marker.remove();
break;
}
marker.onmap = false;
break;
} else {
tmparray.push(current_marker);
}
}
this.markers = this.markers.concat(tmparray);
}
/**
* removeAllMarkers removes all the Markers on a map
*/
Mapstraction.prototype.removeAllMarkers = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.removeAllMarkers(); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.removeMarkersAll();
break;
case 'google':
case 'openstreetmap':
map.clearOverlays();
break;
case 'microsoft':
map.DeleteAllPushpins();
break;
case 'multimap':
map.removeAllOverlays();
break;
case 'mapquest':
map.removeAllPois();
break;
case 'map24':
// don't think map24 has a specific method for this
var current_marker;
while(this.markers.length > 0) {
current_marker = this.markers.pop();
current_marker.proprietary_marker.remove();
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.removeAllMarkers');
}
this.markers = new Array(); // clear the mapstraction list of markers too
}
/**
* Add a polyline to the map
*/
Mapstraction.prototype.addPolyline = function(polyline,old) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addPolyline(polyline,old); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
ypolyline = polyline.toYahoo();
polyline.setChild(ypolyline);
map.addOverlay(ypolyline);
if(!old) {this.polylines.push(polyline);}
break;
case 'google':
case 'openstreetmap':
gpolyline = polyline.toGoogle();
polyline.setChild(gpolyline);
map.addOverlay(gpolyline);
if(!old) {this.polylines.push(polyline);}
break;
case 'microsoft':
mpolyline = polyline.toMicrosoft();
polyline.setChild(mpolyline);
map.AddPolyline(mpolyline);
if(!old) {this.polylines.push(polyline);}
break;
case 'openlayers':
if(this.debug)
alert(this.api + ' not supported by Mapstraction.addPolyline');
break;
case 'multimap':
mmpolyline = polyline.toMultiMap();
polyline.setChild(mmpolyline);
map.addOverlay( mmpolyline );
if(!old) {this.polylines.push(polyline);}
break;
case 'mapquest':
mqpolyline = polyline.toMapQuest();
polyline.setChild(mqpolyline);
map.addOverlay( mqpolyline );
if(!old) {this.polylines.push(polyline);}
break;
case 'map24':
var m24polyline = polyline.toMap24();
polyline.setChild(m24polyline);
m24polyline.commit();
if(!old) {this.polylines.push(polyline);}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.addPolyline');
}
}
/**
* Remove the polyline from the map
*/
Mapstraction.prototype.removePolyline = function(polyline) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.removePolyline(polyline); } );
return;
}
var map = this.maps[this.api];
var tmparray = new Array();
while(this.polylines.length > 0){
current_polyline = this.polylines.pop();
if(polyline == current_polyline) {
switch (this.api) {
case 'google':
case 'openstreetmap':
map.removeOverlay(polyline.proprietary_polyline);
break;
case 'yahoo':
map.removeOverlay(polyline.proprietary_polyline);
break;
case 'microsoft':
map.DeletePolyline(polyline.pllID);
break;
case 'multimap':
polyline.proprietary_polyline.remove();
break;
case 'mapquest':
map.removeOverlay(polyline.proprietary_polyline);
break;
case 'map24':
polyline.proprietary_polyline.remove();
break;
}
polyline.onmap = false;
break;
} else {
tmparray.push(current_polyline);
}
}
this.polylines = this.polylines.concat(tmparray);
}
/**
* Removes all polylines from the map
*/
Mapstraction.prototype.removeAllPolylines = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.removeAllPolylines(); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
for(var i = 0, length = this.polylines.length;i < length;i++){
map.removeOverlay(this.polylines[i].proprietary_polyline);
}
break;
case 'google':
case 'openstreetmap':
for(var i = 0, length = this.polylines.length;i < length;i++){
map.removeOverlay(this.polylines[i].proprietary_polyline);
}
break;
case 'microsoft':
map.DeleteAllPolylines();
break;
case 'multimap':
for(var i = 0, length = this.polylines.length;i < length;i++){
this.polylines[i].proprietary_polyline.remove();
}
break;
case 'mapquest':
map.removeAllOverlays();
break;
case 'map24':
// don't think map24 has a specific method for this
var current_polyline;
while(this.polylines.length > 0) {
current_polyline = this.polylines.pop();
current_polyline.proprietary_polyline.remove();
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.removeAllPolylines');
}
this.polylines = new Array();
}
/**
* getCenter gets the central point of the map
* @returns  the center point of the map
* @type LatLonPoint
*/
Mapstraction.prototype.getCenter = function() {
if(this.loaded[this.api] == false) {
return null;
}
var map = this.maps[this.api];
var point = undefined;
switch (this.api) {
case 'yahoo':
var pt = map.getCenterLatLon();
point = new LatLonPoint(pt.Lat,pt.Lon);
break;
case 'google':
case 'openstreetmap':
var pt = map.getCenter();
point = new LatLonPoint(pt.lat(),pt.lng());
break;
case 'microsoft':
var pt = map.GetCenter();
point = new LatLonPoint(pt.Latitude,pt.Longitude);
break;
case 'multimap':
var pt = map.getCurrentPosition();
point = new LatLonPoint(pt.y, pt.x);
break;
case 'mapquest':
var pt = map.getCenter();
point = new LatLonPoint(pt.getLatitude(), pt.getLongitude());
break;
case 'map24':
var pt = map.MapClient['Static'].getCurrentMapView().getCenter();
point = new LatLonPoint(pt.Y/60,pt.X/60);
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.getCenter');
}
return point;
}
/**
* setCenter sets the central point of the map
* @param {LatLonPoint} point The point at which to center the map
*/
Mapstraction.prototype.setCenter = function(point) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setCenter(point); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.panToLatLon(point.toYahoo());
break;
case 'google':
case 'openstreetmap':
map.setCenter(point.toGoogle());
break;
case 'microsoft':
map.SetCenter(point.toMicrosoft());
break;
case 'multimap':
map.goToPosition(point.toMultiMap());
break;
case 'mapquest':
map.setCenter(point.toMapQuest());
break;
case 'freeearth':
if (this.freeEarthLoaded) {
map.setTargetLatLng( point.toFreeEarth() );
} else {
self = this;
this.freeEarthOnLoad.push( function() { self.setCenterAndZoom(point); }
);
}
break;
case 'map24':
// Since center changes the zoom level to default
// we have to get the original metre width and pass it back in when
// centering.
var mv = map.MapClient['Static'].getCurrentMapView();
var newSettings = new Object();
newSettings.MinimumWidth = lonToMetres
(mv.LowerRight.Longitude - mv.TopLeft.Longitude,
(mv.LowerRight.Latitude+mv.TopLeft.Latitude)/2);
newSettings.Latitude =  point.lat*60;
newSettings.Longitude = point.lon*60;
Map24.MapApplication.center(newSettings);
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setCenter');
}
}
/**
* setZoom sets the zoom level for the map
* MS doesn't seem to do zoom=0, and Gg's sat goes closer than it's maps, and MS's sat goes closer than Y!'s
* TODO: Mapstraction.prototype.getZoomLevels or something.
* @param {int} zoom The (native to the map) level zoom the map to.
*/
Mapstraction.prototype.setZoom = function(zoom) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setZoom(zoom); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
var yzoom = 18 - zoom; // maybe?
map.setZoomLevel(yzoom);
break;
case 'google':
case 'openstreetmap':
map.setZoom(zoom);
break;
case 'microsoft':
map.SetZoomLevel(zoom);
break;
case 'multimap':
map.setZoomFactor(zoom);
break;
case 'mapquest':
map.setZoomLevel(zoom - 3); // MapQuest seems off by 3
break;
case 'map24':
// get the current centre than calculate the settings based on this
var point = this.getCenter();
var newSettings = new Object();
newSettings.Latitude = point.lat*60;
newSettings.Longitude = point.lon*60;
var client = map.MapClient['Static'];
var dLon = getDegreesFromGoogleZoomLevel
(client.getCanvasSize().Width,zoom);
newSettings.MinimumWidth = lonToMetres (dLon, point.lat);
Map24.MapApplication.center ( newSettings );
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setZoom');
}
}
/**
* autoCenterAndZoom sets the center and zoom of the map to the smallest bounding box
*  containing all markers
*
*/
Mapstraction.prototype.autoCenterAndZoom = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.autoCenterAndZoom(); } );
return;
}
var lat_max = -90;
var lat_min = 90;
var lon_max = -180;
var lon_min = 180;
for (var i=0; i<this.markers.length; i++) {
lat = this.markers[i].location.lat;
lon = this.markers[i].location.lon;
if (lat > lat_max) lat_max = lat;
if (lat < lat_min) lat_min = lat;
if (lon > lon_max) lon_max = lon;
if (lon < lon_min) lon_min = lon;
}
this.setBounds( new BoundingBox(lat_min, lon_min, lat_max, lon_max) );
}
/**
* centerAndZoomOnPoints sets the center and zoom of the map from an array of points
*
* This is useful if you don't want to have to add markers to the map
*/
Mapstraction.prototype.centerAndZoomOnPoints = function(points) {
var bounds = new BoundingBox(points[0].lat,points[0].lon,points[0].lat,points[0].lon);
for (var i=1, len = points.length ; i<len; i++) {
bounds.extend(points[i]);
}
this.setBounds(bounds);
}
/**
* getZoom returns the zoom level of the map
* @returns the zoom level of the map
* @type int
*/
Mapstraction.prototype.getZoom = function() {
if(this.loaded[this.api] == false) {
self = this;
return -1;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
return 18 - map.getZoomLevel(); // maybe?
case 'google':
case 'openstreetmap':
return map.getZoom();
case 'microsoft':
return map.GetZoomLevel();
case 'multimap':
return map.getZoomFactor();
case 'mapquest':
return map.getZoomLevel() + 3; // Mapquest seems off by 3?
case 'map24':
// since map24 doesn't use a Google-style set of zoom levels, we have
// to round to the nearest zoom
var mv = map.MapClient['Static'].getCurrentMapView();
var dLon = (mv.LowerRight.Longitude - mv.TopLeft.Longitude) / 60;
var width = map.MapClient['Static'].getCanvasSize().Width;
var zoom = getGoogleZoomLevelFromDegrees (width,dLon);
return Math.round(zoom);
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.getZoom');
}
}
/**
* getZoomLevelForBoundingBox returns the best zoom level for bounds given
* @param boundingBox the bounds to fit
* @returns the closest zoom level that contains the bounding box
* @type int
*/
Mapstraction.prototype.getZoomLevelForBoundingBox = function( bbox ) {
if(this.loaded[this.api] == false) {
self = this;
return -1;
}
var map = this.maps[this.api];
// NE and SW points from the bounding box.
var ne = bbox.getNorthEast();
var sw = bbox.getSouthWest();
switch (this.api) {
case 'google':
case 'openstreetmap':
var gbox = new GLatLngBounds( sw.toGoogle(), ne.toGoogle() );
var zoom = map.getBoundsZoomLevel( gbox );
return zoom;
break;
case 'multimap':
var mmlocation = map.getBoundsZoomFactor( sw.toMultiMap(), ne.toMultiMap() );
var zoom = mmlocation.zoom_factor();
return zoom;
break;
case 'map24':
// since map24 doesn't use a Google-style set of zoom levels, we work
// out what zoom level will show the given longitude difference within
// the current map pixel width
var dLon = ne.lon - sw.lon;
var width = map.MapClient['Static'].getCanvasSize().Width;
var zoom = getGoogleZoomLevelFromDegrees (width,dLon);
return Math.round(zoom);
break;
default:
if(this.debug)
alert( this.api + ' not supported by Mapstraction.getZoomLevelForBoundingBox' );
}
}
// any use this being a bitmask? Should HYBRID = ROAD | SATELLITE?
Mapstraction.ROAD = 1;
Mapstraction.SATELLITE = 2;
Mapstraction.HYBRID = 3;
/**
* setMapType sets the imagery type for the map.
* The type can be one of:
* Mapstraction.ROAD
* Mapstraction.SATELLITE
* Mapstraction.HYBRID
* @param {int} type The (native to the map) level zoom the map to.
*/
Mapstraction.prototype.setMapType = function(type) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setMapType(type); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
switch(type) {
case Mapstraction.ROAD:
map.setMapType(YAHOO_MAP_REG);
break;
case Mapstraction.SATELLITE:
map.setMapType(YAHOO_MAP_SAT);
break;
case Mapstraction.HYBRID:
map.setMapType(YAHOO_MAP_HYB);
break;
default:
map.setMapType(YAHOO_MAP_REG);
}
break;
case 'google':
case 'openstreetmap':
switch(type) {
case Mapstraction.ROAD:
map.setMapType(G_NORMAL_MAP);
break;
case Mapstraction.SATELLITE:
map.setMapType(G_SATELLITE_MAP);
break;
case Mapstraction.HYBRID:
map.setMapType(G_HYBRID_MAP);
break;
default:
map.setMapType(G_NORMAL_MAP);
}
break;
case 'microsoft':
// TODO: oblique?
switch(type) {
case Mapstraction.ROAD:
map.SetMapStyle(Msn.VE.MapStyle.Road);
break;
case Mapstraction.SATELLITE:
map.SetMapStyle(Msn.VE.MapStyle.Aerial);
break;
case Mapstraction.HYBRID:
map.SetMapStyle(Msn.VE.MapStyle.Hybrid);
break;
default:
map.SetMapStyle(Msn.VE.MapStyle.Road);
}
break;
case 'multimap':
maptypes = map.getAvailableMapTypes();
maptype = -1;
for (var i = 0; i < maptypes.length; i++) {
switch (maptypes[i]) {
case MM_WORLD_MAP:
if (type == Mapstraction.ROAD) {
maptype = maptypes[i];
}
default_type = maptypes[i];
break;
case MM_WORLD_AERIAL:
if (type == Mapstraction.SATELLITE) {
maptype = maptypes[i];
}
break;
case MM_WORLD_HYBRID:
if (type == Mapstraction.HYBRID) {
maptype = maptypes[i];
}
break;
}
}
if (maptype == -1) { maptype = default_type; }
map.setMapType(maptype);
break;
case 'mapquest':
switch (type) {
case Mapstraction.ROAD:
map.setMapType("map");
break;
case Mapstraction.SATELLITE:
map.setMapType("sat");
break;
case Mapstraction.HYBRID:
map.setMapType("hyb");
break;
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setMapType');
}
}
/**
* getMapType gets the imagery type for the map.
* The type can be one of:
* Mapstraction.ROAD
* Mapstraction.SATELLITE
* Mapstraction.HYBRID
*/
Mapstraction.prototype.getMapType = function() {
if(this.loaded[this.api] == false) {
self = this;
return -1;
}
var map = this.maps[this.api];
var type;
switch (this.api) {
case 'yahoo':
type = map.getCurrentMapType();
switch(type) {
case YAHOO_MAP_REG:
return Mapstraction.ROAD;
break;
case YAHOO_MAP_SAT:
return Mapstraction.SATELLITE;
break;
case YAHOO_MAP_HYB:
return Mapstraction.HYBRID;
break;
default:
return null;
}
break;
case 'google':
case 'openstreetmap':
type = map.getCurrentMapType();
switch(type) {
case G_NORMAL_MAP:
return Mapstraction.ROAD;
break;
case G_SATELLITE_MAP:
return Mapstraction.SATELLITE;
break;
case G_HYBRID_MAP:
return Mapstraction.HYBRID;
break;
default:
return null;
}
break;
case 'microsoft':
// TODO: oblique?
type = map.GetMapStyle();
switch(type) {
case Msn.VE.MapStyle.Road:
return Mapstraction.ROAD;
break;
case Msn.VE.MapStyle.Aerial:
return Mapstraction.SATELLITE;
break;
case Msn.VE.MapStyle.Hybrid:
return Mapstraction.HYBRID;
break;
default:
return null;
}
break;
case 'multimap':
maptypes = map.getAvailableMapTypes();
type = map.getMapType();
switch(type) {
case MM_WORLD_MAP:
return Mapstraction.ROAD;
break;
case MM_WORLD_AERIAL:
return Mapstraction.SATELLITE;
break;
case MM_WORLD_HYBRID:
return Mapstraction.HYBRID;
break;
default:
return null;
}
break;
case 'mapquest':
type = map.getMapType();
switch(type) {
case "map":
return Mapstraction.ROAD;
break;
case "sat":
return Mapstraction.SATELLITE;
break;
case "hyb":
return Mapstraction.HYBRID;
break;
default:
return null;
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.getMapType');
}
}
/**
* getBounds gets the BoundingBox of the map
* @returns the bounding box for the current map state
* @type BoundingBox
*/
Mapstraction.prototype.getBounds = function () {
if(this.loaded[this.api] == false) {
return null;
}
var map = this.maps[this.api];
switch (this.api) {
case 'google':
case 'openstreetmap':
var gbox = map.getBounds();
var sw = gbox.getSouthWest();
var ne = gbox.getNorthEast();
return new BoundingBox(sw.lat(), sw.lng(), ne.lat(), ne.lng());
break;
case 'yahoo':
var ybox = map.getBoundsLatLon();
return new BoundingBox(ybox.LatMin, ybox.LonMin, ybox.LatMax, ybox.LonMax);
break;
case 'microsoft':
var mbox = map.GetMapView();
var nw = mbox.TopLeftLatLong;
var se = mbox.BottomRightLatLong;
return new BoundingBox(se.Latitude,nw.Longitude,nw.Latitude,se.Longitude);
break;
case 'multimap':
var mmbox = map.getMapBounds();
var sw = mmbox.getSouthWest();
var ne = mmbox.getNorthEast();
return new BoundingBox(sw.lat, sw.lon, ne.lat, ne.lon);
break;
case 'mapquest':
var mqbox = map.getMapBounds(); // MQRectLL
var se = mqbox.getLowerRightLatLng();
var nw = mqbox.getUpperLeftLatLng();
// NW is this correct ???
// return new BoundingBox(se.lat, se.lon, nw.lat, nw.lon);
// should be this instead
return new BoundingBox(se.lat, nw.lon, nw.lat, se.lon);
break;
case 'map24':
var mv = map.MapClient['Static'].getCurrentMapView();
var se = mv.LowerRight;
var nw = mv.TopLeft;
return new BoundingBox (se.Latitude/60, nw.Longitude/60,
nw.Latitude/60, se.Longitude/60 );
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.getBounds');
}
}
/**
* setBounds sets the map to the appropriate location and zoom for a given BoundingBox
* @param {BoundingBox} the bounding box you want the map to show
*/
Mapstraction.prototype.setBounds = function(bounds){
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setBounds(bounds); } );
return;
}
var map = this.maps[this.api];
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();
switch (this.api) {
case 'google':
case 'openstreetmap':
var gbounds = new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));
map.setCenter(gbounds.getCenter(), map.getBoundsZoomLevel(gbounds));
break;
case 'yahoo':
if(sw.lon > ne.lon)
sw.lon -= 360;
var center = new YGeoPoint((sw.lat + ne.lat)/2,
(ne.lon + sw.lon)/2);
var container = map.getContainerSize();
for(var zoom = 1 ; zoom <= 17 ; zoom++){
var sw_pix = convertLatLonXY_Yahoo(sw,zoom);
var ne_pix = convertLatLonXY_Yahoo(ne,zoom);
if(sw_pix.x > ne_pix.x)
sw_pix.x -= (1 << (26 - zoom)); //earth circumference in pixel
if(Math.abs(ne_pix.x - sw_pix.x)<=container.width
&& Math.abs(ne_pix.y - sw_pix.y) <= container.height){
map.drawZoomAndCenter(center,zoom); //Call drawZoomAndCenter here: OK if called multiple times anyway
break;
}
}
break;
case 'microsoft':
map.SetMapView([new VELatLong(sw.lat,sw.lon),new VELatLong(ne.lat,ne.lon)]);
break;
case 'multimap':
var mmlocation = map.getBoundsZoomFactor( sw.toMultiMap(), ne.toMultiMap() );
var center = new LatLonPoint(mmlocation.coords.lat, mmlocation.coords.lon);
this.setCenterAndZoom(center, mmlocation.zoom_factor);
break;
case 'mapquest':
// TODO: MapQuest.setBounds
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setBounds');
break;
case 'freeearth':
var center = new LatLonPoint((sw.lat + ne.lat)/2, (ne.lon + sw.lon)/2);
this.setCenter(center);
break;
case 'map24':
var settings = new Object();
settings.Latitude = ((sw.lat+ne.lat) / 2) * 60;
settings.Longitude = ((sw.lon+ne.lon) / 2) * 60;
// need to convert lat/lon to metres
settings.MinimumWidth = lonToMetres
(ne.lon-sw.lon, (ne.lat+sw.lat)/2);
Map24.MapApplication.center ( settings );
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.setBounds');
}
}
/**
* addImageOverlay layers an georeferenced image over the map
* @param {id} unique DOM identifier
* @param {src} url of image
* @param {opacity} opacity 0-100
* @param {west} west boundary
* @param {south} south boundary
* @param {east} east boundary
* @param {north} north boundary
*/
Mapstraction.prototype.addImageOverlay = function(id, src, opacity, west, south, east, north) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addImageOverlay(id, src, opacity, west, south, east, north); } );
return;
}
var map = this.maps[this.api];
var b = document.createElement("img");
b.style.display = 'block';
b.setAttribute('id',id);
b.setAttribute('src',src);
b.style.position = 'absolute';
b.style.zIndex = 1;
b.setAttribute('west',west);
b.setAttribute('south',south);
b.setAttribute('east',east);
b.setAttribute('north',north);
switch (this.api) {
case 'google':
case 'openstreetmap':
map.getPane(G_MAP_MAP_PANE).appendChild(b);
this.setImageOpacity(id, opacity);
this.setImagePosition(id);
GEvent.bind(map, "zoomend", this, function(){this.setImagePosition(id)});
GEvent.bind(map, "moveend", this, function(){this.setImagePosition(id)});
break;
case 'multimap':
map.getContainer().appendChild(b);
this.setImageOpacity(id, opacity);
this.setImagePosition(id);
me = this;
map.addEventHandler( 'changeZoom', function(eventType, eventTarget, arg1, arg2, arg3) {
me.setImagePosition(id);
});
map.addEventHandler( 'drag', function(eventType, eventTarget, arg1, arg2, arg3) {
me.setImagePosition(id);
});
map.addEventHandler( 'endPan', function(eventType, eventTarget, arg1, arg2, arg3) {
me.setImagePosition(id);
});
break;
default:
b.style.display = 'none';
if(this.debug)
alert(this.api + "not supported by Mapstraction.addImageOverlay not supported");
break;
}
}
Mapstraction.prototype.setImageOpacity = function(id, opacity) {
if(opacity<0){opacity=0;}  if(opacity>=100){opacity=100;}
var c=opacity/100;
var d=document.getElementById(id);
if(typeof(d.style.filter)=='string'){d.style.filter='alpha(opacity:'+opacity+')';}
if(typeof(d.style.KHTMLOpacity)=='string'){d.style.KHTMLOpacity=c;}
if(typeof(d.style.MozOpacity)=='string'){d.style.MozOpacity=c;}
if(typeof(d.style.opacity)=='string'){d.style.opacity=c;}
}
Mapstraction.prototype.setImagePosition = function(id) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.setImagePosition(id); } );
return;
}
var map = this.maps[this.api];
var x = document.getElementById(id);
var d; var e;
switch (this.api) {
case 'google':
case 'openstreetmap':
d = map.fromLatLngToDivPixel(new GLatLng(x.getAttribute('north'), x.getAttribute('west')));
e = map.fromLatLngToDivPixel(new GLatLng(x.getAttribute('south'), x.getAttribute('east')));
break;
case 'multimap':
d = map.geoPosToContainerPixels(new MMLatLon(x.getAttribute('north'), x.getAttribute('west')));
e = map.geoPosToContainerPixels(new MMLatLon(x.getAttribute('south'), x.getAttribute('east')));
break;
}
x.style.top=d.y+'px';
x.style.left=d.x+'px';
x.style.width=e.x-d.x+'px';
x.style.height=e.y-d.y+'px';
}
/**
* addGeoRSSOverlay adds a GeoRSS overlay to the map
* @param{georssURL} GeoRSS feed URL
*/
Mapstraction.prototype.addGeoRSSOverlay = function(georssURL) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.addGeoRSSOverlay(georssURL); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'yahoo':
map.addOverlay(new YGeoRSS(georssURL));
break;
// case 'openstreetmap': // OSM uses the google interface, so allow cascade
case 'google':
map.addOverlay(new GGeoXml(georssURL));
break;
case 'microsoft':
var veLayerSpec = new VELayerSpecification();
veLayerSpec.Type = VELayerType.GeoRSS;
veLayerSpec.ID = 1;
veLayerSpec.LayerSource = georssURL;
veLayerSpec.Method = 'get';
// veLayerSpec.FnCallback = onFeedLoad;
map.AddLayer(veLayerSpec);
break;
// case 'openlayers':
// 	map.addLayer(new OpenLayers.Layer.GeoRSS("GeoRSS Layer", georssURL));
// break;
case 'multimap':
break;
case 'freeearth':
if (this.freeEarthLoaded) {
var ferss = new FE.GeoRSS(georssURL);
map.addOverlay(ferss);
} else {
self = this;
this.freeEarthOnLoad.push( function() { self.addGeoRSSOverlay(georssURL); } );
}
break;
default:
if(this.debug)
alert(this.api + ' not supported by Mapstraction.addGeoRSSOverlay');
}
}
/**
* addFilter adds a marker filter
* @param {field} name of attribute to filter on
* @param {operator} presently only "ge" or "le"
* @param {value} the value to compare against
*/
Mapstraction.prototype.addFilter = function(field, operator, value) {
if (! this.filters) {
this.filters = [];
}
this.filters.push( [field, operator, value] );
}
/**
* removeFilter
*/
Mapstraction.prototype.removeFilter = function(field, operator, value) {
if (! this.filters) { return; }
var del;
for (var f=0; f<this.filters.length; f++) {
if (this.filters[f][0] == field &&
(! operator || (this.filters[f][1] == operator && this.filters[f][2] == value))) {
this.filters.splice(f,1);
f--; //array size decreased
}
}
}
/*
* toggleFilter: delete the current filter if present; otherwise add it
*/
Mapstraction.prototype.toggleFilter = function(field, operator, value) {
if (! this.filters) {
this.filters = [];
}
var found = false;
for (var f=0; f<this.filters.length; f++) {
if (this.filters[f][0] == field && this.filters[f][1] == operator && this.filters[f][2] == value) {
this.filters.splice(f,1);
f--; //array size decreased
found = true;
}
}
if (! found) {
this.addFilter(field, operator, value);
}
}
/*
* removeAllFilters
*/
Mapstraction.prototype.removeAllFilters = function() {
this.filters = [];
}
/**
* doFilter executes all filters added since last call
*/
Mapstraction.prototype.doFilter = function() {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.doFilter(); } );
return;
}
var map = this.maps[this.api];
if (this.filters) {
switch (this.api) {
case 'multimap':
/* TODO polylines aren't filtered in multimap */
var mmfilters = [];
for (var f=0; f<this.filters.length; f++) {
mmfilters.push( new MMSearchFilter( this.filters[f][0], this.filters[f][1], this.filters[f][2] ));
}
map.setMarkerFilters( mmfilters );
map.redrawMap();
break;
default:
var vis;
for (var m=0; m<this.markers.length; m++) {
vis = true;
for (var f=0; f<this.filters.length; f++) {
if (! this.applyFilter(this.markers[m], this.filters[f])) {
vis = false;
}
}
if (vis) {
this.markers[m].show();
} else {
this.markers[m].hide();
}
}
/*
for (var p=0; m<this.polylines.length; p++) {
vis = true;
for (var f=0; f<this.filters.length; f++) {
if (! this.applyFilter(this.polylines[p], this.filters[f])) {
vis = false;
}
}
if (vis) {
this.polylines[p].show();
} else {
this.polylines[p].hide();
}
}
*/
break;
}
}
}
Mapstraction.prototype.applyFilter = function(o, f) {
var vis = true;
switch (f[1]) {
case 'ge':
if (o.getAttribute( f[0] ) < f[2]) {
vis = false;
}
break;
case 'le':
if (o.getAttribute( f[0] ) > f[2]) {
vis = false;
}
break;
case 'eq':
if (o.getAttribute( f[0] ) != f[2]) {
vis = false;
}
break;
}
return vis;
}
/**
* getAttributeExtremes returns the minimum/maximum of "field" from all markers
* @param {field} name of "field" to query
* @returns {array} of minimum/maximum
*/
Mapstraction.prototype.getAttributeExtremes = function(field) {
var min;
var max;
for (var m=0; m<this.markers.length; m++) {
if (! min || min > this.markers[m].getAttribute(field)) {
min = this.markers[m].getAttribute(field);
}
if (! max || max < this.markers[m].getAttribute(field)) {
max = this.markers[m].getAttribute(field);
}
}
for (var p=0; m<this.polylines.length; m++) {
if (! min || min > this.polylines[p].getAttribute(field)) {
min = this.polylines[p].getAttribute(field);
}
if (! max || max < this.polylines[p].getAttribute(field)) {
max = this.polylines[p].getAttribute(field);
}
}
return [min, max];
}
/**
* getMap returns the native map object that mapstraction is talking to
* @returns the native map object mapstraction is using
*/
Mapstraction.prototype.getMap = function() {
// FIXME in an ideal world this shouldn't exist right?
return this.maps[this.api];
}
//////////////////////////////
//
//   LatLonPoint
//
/////////////////////////////
/**
* LatLonPoint is a point containing a latitude and longitude with helper methods
* @param {double} lat is the latitude
* @param {double} lon is the longitude
* @returns a new LatLonPoint
* @type LatLonPoint
*/
function LatLonPoint(lat,lon) {
// TODO error if undefined?
//  if (lat == undefined) alert('undefined lat');
//  if (lon == undefined) alert('undefined lon');
this.lat = lat;
this.lon = lon;
this.lng = lon; // lets be lon/lng agnostic
}
/**
* toYahoo returns a Y! maps point
* @returns a YGeoPoint
*/
LatLonPoint.prototype.toYahoo = function() {
return new YGeoPoint(this.lat,this.lon);
}
/**
* toGoogle returns a Google maps point
* @returns a GLatLng
*/
LatLonPoint.prototype.toGoogle = function() {
return new GLatLng(this.lat,this.lon);
}
/**
* toMicrosoft returns a VE maps point
* @returns a VELatLong
*/
LatLonPoint.prototype.toMicrosoft = function() {
return new VELatLong(this.lat,this.lon);
}
/**
* toMultiMap returns a MultiMap point
* @returns a MMLatLon
*/
LatLonPoint.prototype.toMultiMap = function() {
return new MMLatLon(this.lat, this.lon);
}
/**
* toMapQuest returns a MapQuest point
* @returns a MQLatLng
*/
LatLonPoint.prototype.toMapQuest = function() {
return new MQLatLng(this.lat, this.lon);
}
/**
* toFreeEarth returns a FreeEarth point
* @returns a FE.LatLng
*/
LatLonPoint.prototype.toFreeEarth = function() {
return new FE.LatLng(this.lat,this.lon);
}
/**
* toMap24 returns a Map24 point
* @returns a Map24.Point
*/
LatLonPoint.prototype.toMap24 = function() {
return new Map24.Point (this.lon,this.lat);
}
/**
* toString returns a string represntation of a point
* @returns a string like '51.23, -0.123'
* @type String
*/
LatLonPoint.prototype.toString = function() {
return this.lat + ', ' + this.lon;
}
/**
* distance returns the distance in kilometers between two points
* @param {LatLonPoint} otherPoint The other point to measure the distance from to this one
* @returns the distance between the points in kilometers
* @type double
*/
LatLonPoint.prototype.distance = function(otherPoint) {
var d,dr;
with (Math) {
dr = 0.017453292519943295; // 2.0 * PI / 360.0; or, radians per degree
d = cos(otherPoint.lon*dr - this.lon*dr) * cos(otherPoint.lat*dr - this.lat*dr);
return acos(d)*6378.137; // equatorial radius
}
return -1;
}
/**
* equals tests if this point is the same as some other one
* @param {LatLonPoint} otherPoint The other point to test with
* @returns true or false
* @type boolean
*/
LatLonPoint.prototype.equals = function(otherPoint) {
return this.lat == otherPoint.lat && this.lon == otherPoint.lon;
}
//////////////////////////
//
//  BoundingBox
//
//////////////////////////
/**
* BoundingBox creates a new bounding box object
* @param {double} swlat the latitude of the south-west point
* @param {double} swlon the longitude of the south-west point
* @param {double} nelat the latitude of the north-east point
* @param {double} nelon the longitude of the north-east point
* @returns a new BoundingBox
* @type BoundingBox
* @constructor
*/
function BoundingBox(swlat, swlon, nelat, nelon) {
//FIXME throw error if box bigger than world
//alert('new bbox ' + swlat + ',' +  swlon + ',' +  nelat + ',' + nelon);
this.sw = new LatLonPoint(swlat, swlon);
this.ne = new LatLonPoint(nelat, nelon);
}
/**
* getSouthWest returns a LatLonPoint of the south-west point of the bounding box
* @returns the south-west point of the bounding box
* @type LatLonPoint
*/
BoundingBox.prototype.getSouthWest = function() {
return this.sw;
}
/**
* getNorthEast returns a LatLonPoint of the north-east point of the bounding box
* @returns the north-east point of the bounding box
* @type LatLonPoint
*/
BoundingBox.prototype.getNorthEast = function() {
return this.ne;
}
/**
* isEmpty finds if this bounding box has zero area
* @returns whether the north-east and south-west points of the bounding box are the same point
* @type boolean
*/
BoundingBox.prototype.isEmpty = function() {
return this.ne == this.sw; // is this right? FIXME
}
/**
* contains finds whether a given point is within a bounding box
* @param {LatLonPoint} point the point to test with
* @returns whether point is within this bounding box
* @type boolean
*/
BoundingBox.prototype.contains = function(point){
return point.lat >= this.sw.lat && point.lat <= this.ne.lat && point.lon>= this.sw.lon && point.lon <= this.ne.lon;
}
/**
* toSpan returns a LatLonPoint with the lat and lon as the height and width of the bounding box
* @returns a LatLonPoint containing the height and width of this bounding box
* @type LatLonPoint
*/
BoundingBox.prototype.toSpan = function() {
return new LatLonPoint( Math.abs(this.sw.lat - this.ne.lat), Math.abs(this.sw.lon - this.ne.lon) );
}
/**
* extend extends the bounding box to include the new point
*/
BoundingBox.prototype.extend = function(point) {
if(this.sw.lat > point.lat)
this.sw.setLat(point.lat);
if(this.sw.lon > point.lon)
this.sw.setLon(point.lon);
if(this.ne.lat < point.lat)
this.ne.setLat(point.lat);
if(this.ne.lon < point.lon)
this.ne.setLon(point.lon);
return;
}
//////////////////////////////
//
//  Marker
//
///////////////////////////////
/**
* Marker create's a new marker pin
* @param {LatLonPoint} point the point on the map where the marker should go
* @constructor
*/
function Marker(point) {
this.location = point;
this.onmap = false;
this.proprietary_marker = false;
this.attributes = new Array();
this.pinID = "mspin-"+new Date().getTime()+'-'+(Math.floor(Math.random()*Math.pow(2,16)));
}
Marker.prototype.setChild = function(some_proprietary_marker) {
this.proprietary_marker = some_proprietary_marker;
this.onmap = true
}
Marker.prototype.setLabel = function(labelText) {
this.labelText = labelText;
}
/**
* addData conviniently set a hash of options on a marker
*/
Marker.prototype.addData = function(options){
if(options.label)
this.setLabel(options.label);
if(options.infoBubble)
this.setInfoBubble(options.infoBubble);
if(options.icon) {
if(options.iconSize)
this.setIcon(options.icon, new Array(options.iconSize[0], options.iconSize[1]));
else
this.setIcon(options.icon);
}
if(options.infoDiv)
this.setInfoDiv(options.infoDiv[0],options.infoDiv[1]);
if(options.draggable)
this.setDraggable(options.draggable);
if(options.hover)
this.setHover(options.hover);
if(options.hoverIcon)
this.setHoverIcon(options.hoverIcon);
if(options.openBubble)
this.openBubble();
if(options.date)
this.setAttribute( 'date', eval(options.date) );
if(options.category)
this.setAttribute( 'category', options.category );
}
/**
* setInfoBubble sets the html/text content for a bubble popup for a marker
* @param {String} infoBubble the html/text you want displayed
*/
Marker.prototype.setInfoBubble = function(infoBubble) {
this.infoBubble = infoBubble;
}
/**
* setInfoDiv sets the text and the id of the div element where to the information
*  useful for putting information in a div outside of the map
* @param {String} infoDiv the html/text you want displayed
* @param {String} div the element id to use for displaying the text/html
*/
Marker.prototype.setInfoDiv = function(infoDiv,div){
this.infoDiv = infoDiv;
this.div = div;
}
/**
* setIcon sets the icon for a marker
* @param {String} iconUrl The URL of the image you want to be the icon
*/
Marker.prototype.setIcon = function(iconUrl, iconSize){
this.iconUrl = iconUrl;
if(iconSize)
this.iconSize = iconSize;
}
Marker.prototype.setHoverIcon = function(hoverIconUrl){
this.hoverIconUrl = hoverIconUrl;
}
/**
* setDraggable sets the draggable state of the marker
* @param {Bool} draggable set to true if marker should be draggable by the user
*/
Marker.prototype.setDraggable = function(draggable) {
this.draggable = draggable;
}
/**
* setHover sets that the marker info is displayed on hover
* @param {Bool} hover set to true if marker should display info on hover
*/
Marker.prototype.setHover = function(hover) {
this.hover = hover;
}
/**
* toYahoo returns a Yahoo Maps compatible marker pin
* @returns a Yahoo Maps compatible marker
*/
Marker.prototype.toYahoo = function() {
var ymarker;
if(this.iconUrl) {
ymarker = new YMarker(this.location.toYahoo (),new YImage(this.iconUrl));
} else {
ymarker = new YMarker(this.location.toYahoo());
}
if(this.iconSize) {
ymarker.size = new YSize(this.iconSize[0], this.iconSize[1]);
}
if(this.labelText) {
ymarker.addLabel(this.labelText);
}
if(this.infoBubble) {
var theInfo = this.infoBubble;
var event_action;
if(this.hover) {
event_action = EventsList.MouseOver;
}
else {
event_action = EventsList.MouseClick;
}
YEvent.Capture(ymarker, event_action, function() {
ymarker.openSmartWindow(theInfo); });
}
if(this.infoDiv) {
var theInfo = this.infoDiv;
var div = this.div;
var event_div;
if(this.hover) {
event_action = EventsList.MouseOver;
}
else {
event_action = EventsList.MouseClick;
}
YEvent.Capture(ymarker, event_action, function() {
document.getElementById(div).innerHTML = theInfo;});
}
return ymarker;
}
/**
* toGoogle returns a Google Maps compatible marker pin
* @returns Google Maps compatible marker
*/
Marker.prototype.toGoogle = function() {
var options = new Object();
if(this.labelText) {
options.title =  this.labelText;
}
if(this.iconUrl){
var icon = new GIcon(G_DEFAULT_ICON,this.iconUrl);
if(this.iconSize)
icon.iconSize = new GSize(this.iconSize[0], this.iconSize[1]);
options.icon = icon;
}
if(this.draggable){
options.draggable = this.draggable;
}
var gmarker = new GMarker( this.location.toGoogle(),options);
if(this.infoBubble) {
var theInfo = this.infoBubble;
var event_action;
if(this.hover) {
event_action = "mouseover";
}
else {
event_action = "click";
}
GEvent.addListener(gmarker, event_action, function() {
gmarker.openInfoWindowHtml(theInfo, {maxWidth: 100});
});
}
if(this.hoverIconUrl) {
GEvent.addListener(gmarker, "mouseover", function() {
gmarker.setImage(this.hoverIconUrl);
});
GEvent.addListener(gmarker, "mouseout", function() {
gmarker.setImage(this.iconUrl);
});
}
if(this.infoDiv){
var theInfo = this.infoDiv;
var div = this.div;
var event_action;
if(this.hover) {
event_action = "mouseover";
}
else {
event_action = "click";
}
GEvent.addListener(gmarker, event_action, function() {
document.getElementById(div).innerHTML = theInfo;
});
}
return gmarker;
}
/**
* toMicrosoft returns a MSFT VE compatible marker pin
* @returns MSFT VE compatible marker
*/
Marker.prototype.toMicrosoft = function() {
var pin = new VEPushpin(this.pinID,this.location.toMicrosoft(),
this.iconUrl,this.labelText,this.infoBubble);
return pin;
}
/**
* toMap24 returns a Map24 Location
* @returns Map24 Location
*/
Marker.prototype.toMap24 = function() {
var ops = new Object();
ops.Longitude = this.location.lon*60;
ops.Latitude = this.location.lat*60;
if(this.infoBubble) {
// not sure how map24 differentiates between tooltips and
// info bubble content
ops.TooltipContent =  this.infoBubble;
}
if(this.labelText) {
// ????
}
ops.LogoURL = this.iconUrl ? this.iconUrl :
"http://www.free-map.org.uk/images/marker.png";
ops.TooltipLayout = Map24.MapObject.LAYOUT_BUBBLE;
if(this.hover) {
ops.TooltipOpen = "OnMouseOver";
//        ops.TooltipClose = "OnMouseOut";
} else {
ops.TooltipOpen = "OnClick";
//        ops.TooltipClose = "OnMouseOut";
}
var m24Location = new Map24.Location ( ops );
return m24Location;
}
/**
* toMultiMap returns a MultiMap compatible marker pin
* @returns MultiMap compatible marker
*/
Marker.prototype.toMultiMap = function() {
if (this.iconUrl) {
var icon = new MMIcon(this.iconUrl);
icon.iconSize = new MMDimensions(32, 32); //how to get this?
var mmmarker = new MMMarkerOverlay( this.location.toMultiMap(), {'icon' : icon} );
} else {
var mmmarker = new MMMarkerOverlay( this.location.toMultiMap());
}
if(this.labelText){
}
if(this.infoBubble) {
mmmarker.setInfoBoxContent(this.infoBubble);
}
if(this.infoDiv) {
}
for (var key in this.attributes) {
mmmarker.setAttribute(key, this.attributes[ key ]);
}
return mmmarker;
}
/**
* toMapQuest returns a MapQuest compatible marker pin
* @returns MapQuest compatible marker
*/
Marker.prototype.toMapQuest = function() {
var mqmarker = new MQPoi( this.location.toMapQuest() );
if(this.iconUrl){
var mqicon = new MQMapIcon();
mqicon.setImage(this.iconUrl,32,32,true,false);
// TODO: Finish MapQuest icon params - icon file location, width, height, recalc infowindow offset, is it a PNG image?
mqmarker.setIcon(mqicon);
// mqmarker.setLabel('Hola!');
}
if(this.labelText) { mqmarker.setInfoTitleHTML( this.labelText ); }
if(this.infoBubble) { mqmarker.setInfoContentHTML( this.infoBubble ); }
if(this.infoDiv){
var theInfo = this.infoDiv;
var div = this.div;
MQEventManager.addListener(mqmarker, "click", function() {
document.getElementById(div).innerHTML = theInfo;
});
}
return mqmarker;
}
/**
* toFreeEarth returns a FreeEarth compatible marker pin
* @returns FreeEarth compatible marker
*/
Marker.prototype.toFreeEarth = function() {
var feicon;
if (this.iconUrl) {
feicon = new FE.Icon(this.iconUrl);
} else {
feicon = new FE.Icon("http://freeearth.poly9.com/images/bullmarker.png");
}
var femarker = new FE.Pushpin( this.location.toFreeEarth(), feicon);
if(this.infoBubble) {
var theBubble = this.infoBubble;
FE.Event.addListener(femarker, 'click', function() {
femarker.openInfoWindowHtml( theBubble, 200, 100 );
} );
}
if(this.infoDiv) {
var theInfo = this.infoDiv;
var div = this.div;
FE.Event.addListener(femarker, 'click', function() {
document.getElementById(div).innerHTML = theInfo;
});
}
return femarker;
}
/**
* setAttribute: set an arbitrary key/value pair on a marker
* @arg(String) key
* @arg value
*/
Marker.prototype.setAttribute = function(key,value) {
this.attributes[key] = value;
}
/**
* getAttribute: gets the value of "key"
* @arg(String) key
* @returns value
*/
Marker.prototype.getAttribute = function(key) {
return this.attributes[key];
}
/**
* openBubble opens the infoBubble
*/
Marker.prototype.openBubble = function() {
if( this.api) {
switch (this.api) {
case 'yahoo':
var ypin = this.proprietary_marker;
ypin.openSmartWindow(this.infoBubble);
break;
case 'google':
case 'openstreetmap':
var gpin = this.proprietary_marker;
gpin.openInfoWindowHtml(this.infoBubble);
break;
case 'microsoft':
var pin = this.proprietary_marker;
// bloody microsoft -- this is broken
var el = $m(this.pinID + "_" + this.maps[this.api].GUID).onmouseover;
setTimeout(el, 1000); // wait a second in case the map is booting as it cancels the event
break;
case 'multimap':
this.proprietary_marker.openInfoBox();
break;
case 'mapquest':
// MapQuest hack to work around bug when opening marker
this.proprietary_marker.setRolloverEnabled(false);
this.proprietary_marker.showInfoWindow();
this.proprietary_marker.setRolloverEnabled(true);
break;
}
} else {
alert('You need to add the marker before opening it');
}
}
/**
* hide the marker
*/
Marker.prototype.hide = function() {
if (this.api) {
switch (this.api) {
case 'google':
case 'openstreetmap':
this.proprietary_marker.hide();
break;
case 'yahoo':
this.proprietary_marker.hide();
break;
case 'map24':
this.proprietary_marker.hide();
break;
case 'multimap':
this.proprietary_marker.setVisibility(false);
break;
case 'mapquest':
this.proprietary_marker.setVisible(false);
break;
default:
if(this.debug)
alert(this.api + "not supported by Marker.hide");
}
}
}
/**
* show the marker
*/
Marker.prototype.show = function() {
if (this.api) {
switch (this.api) {
case 'google':
case 'openstreetmap':
this.proprietary_marker.show();
break;
case 'map24':
this.proprietary_marker.show();
break;
case 'yahoo':
this.proprietary_marker.unhide();
break;
case 'multimap':
this.proprietary_marker.setVisibility(true);
break;
case 'mapquest':
this.proprietary_marker.setVisible(true);
break;
default:
if(this.debug)
alert(this.api + "not supported by Marker.show");
}
}
}
///////////////
// Polyline ///
///////////////
function Polyline(points) {
this.points = points;
this.attributes = new Array();
this.onmap = false;
this.proprietary_polyline = false;
this.pllID = "mspll-"+new Date().getTime()+'-'+(Math.floor(Math.random()*Math.pow(2,16)));
}
/**
* addData conviniently set a hash of options on a polyline
*/
Polyline.prototype.addData = function(options){
if(options.color)
this.setColor(options.color);
if(options.width)
this.setWidth(options.width); // NW corrected from setInfoBubble()
if(options.opacity)
this.setIcon(options.opacity);
if(options.date)
this.setAttribute( 'date', eval(options.date) );
if(options.category)
this.setAttribute( 'category', options.category );
}
Polyline.prototype.setChild = function(some_proprietary_polyline) {
this.proprietary_polyline = some_proprietary_polyline;
this.onmap = true;
}
//in the form: #RRGGBB
//Note map24 insists on upper case, so we convert it.
Polyline.prototype.setColor = function(color){
this.color = (color.length==7 && color[0]=="#") ? color.toUpperCase() : color;
}
//An integer
Polyline.prototype.setWidth = function(width){
this.width = width;
}
//A float between 0.0 and 1.0
Polyline.prototype.setOpacity = function(opacity){
this.opacity = opacity;
}
Polyline.prototype.toYahoo = function() {
var ypolyline;
var ypoints = [];
for (var i = 0, length = this.points.length ; i< length; i++){
ypoints.push(this.points[i].toYahoo());
}
ypolyline = new YPolyline(ypoints,this.color,this.width,this.opacity);
return ypolyline;
}
Polyline.prototype.toGoogle = function() {
var gpolyline;
var gpoints = [];
for (var i = 0,  length = this.points.length ; i< length; i++){
gpoints.push(this.points[i].toGoogle());
}
gpolyline = new GPolyline(gpoints,this.color,this.width,this.opacity);
return gpolyline;
}
Polyline.prototype.toMap24 = function() {
var m24polyline;
var m24longs = "";
var m24lats = "";
for (var i=0; i<this.points.length; i++) {
if(i) {
m24longs += "|";
m24lats += "|";
}
m24longs += (this.points[i].lon*60);
m24lats += (this.points[i].lat*60);
}
m24polyline = new Map24.Polyline({
Longitudes: m24longs,
Latitudes: m24lats,
Color: this.color || "black",
Width: this.width || 3
});
return m24polyline;
}
Polyline.prototype.toMicrosoft = function() {
var mpolyline;
var mpoints = [];
for (var i = 0, length = this.points.length ; i< length; i++){
mpoints.push(this.points[i].toMicrosoft());
}
var color;
var opacity = this.opacity ||1.0;
if(this.color){
color = new VEColor(parseInt(this.color.substr(1,2),16),parseInt(this.color.substr(3,2),16),parseInt(this.color.substr(5,2),16), opacity);
}else{
color = new VEColor(0,255,0, opacity);
}
mpolyline = new VEPolyline(this.pllID,mpoints,color,this.width);
return mpolyline;
}
Polyline.prototype.toMultiMap = function() {
var mmpolyline;
var mmpoints = [];
for (var i = 0, length = this.points.length ; i< length; i++){
mmpoints.push(this.points[i].toMultiMap());
}
mmpolyline = new MMPolyLineOverlay(mmpoints, this.color, this.opacity, this.width, false, undefined);
return mmpolyline;
}
Polyline.prototype.toMapQuest = function() {
var mqpolyline = new MQLineOverlay();
mqpolyline.setColor(this.color||"red");
mqpolyline.setBorderWidth(this.width || 3);
mqpolyline.setKey("Line");
mqpolyline.setColorAlpha(this.opacity);
var mqpoints = new MQLatLngCollection();
for (var i = 0, length = this.points.length ; i< length; i++){
mqpoints.add(this.points[i].toMapQuest());
}
mqpolyline.setShapePoints(mqpoints);
return mqpolyline;
}
Polyline.prototype.toFreeEarth = function() {
var fepoints = new Array();
for (var i = 0, length = this.points.length ; i< length; i++){
fepoints.push(this.points[i].toFreeEarth());
}
var fepolyline = new FE.Polyline(fepoints, this.color || '0xff0000', this.width || 1, this.opacity || 1);
return fepolyline;
}
/**
* setAttribute: set an arbitrary key/value pair on a polyline
* @arg(String) key
* @arg value
*/
Polyline.prototype.setAttribute = function(key,value) {
this.attributes[key] = value;
}
/**
* getAttribute: gets the value of "key"
* @arg(String) key
* @returns value
*/
Polyline.prototype.getAttribute = function(key) {
return this.attributes[key];
}
/**
* show: not yet implemented
*/
Polyline.prototype.show = function() {
if (this.api) {
}
}
/**
* hide: not yet implemented
*/
Polyline.prototype.hide = function() {
if (this.api) {
}
}
/////////////
/// Route ///
/////////////
/**
* Show a route from MapstractionRouter on a mapstraction map
* Currently only supported by MapQuest
* @params {Object} route The route object returned in the callback from MapstractionRouter
*/
Mapstraction.prototype.showRoute = function(route) {
if(this.loaded[this.api] == false) {
self = this;
this.onload[this.api].push( function() { self.showRoute(route); } );
return;
}
var map = this.maps[this.api];
switch (this.api) {
case 'mapquest':
map.addRouteHighlight(route['bounding_box'],"http://map.access.mapquest.com",route['session_id'],true);
break;
default:
if(this.debug)
alert(api + ' not supported by Mapstration.showRoute');
break;
}
}

