
/*
---
MooTools: the javascript framework

web build:
 - http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7

packager build:
 - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff

copyrights:
  - [MooTools](http://mootools.net)

licenses:
  - [MIT License](http://mootools.net/license.txt)
...
*/

(function(){this.MooTools={version:"1.3.1",build:"af48c8d589f43f32212f9bb8ff68a127e6a3ba6c"};var e=this.typeOf=function(i){if(i==null){return"null";}if(i.$family){return i.$family();
}if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments";
}if("item" in i){return"collection";}}}return typeof i;};var u=this.instanceOf=function(w,i){if(w==null){return false;}var v=w.$constructor||w.constructor;
while(v){if(v===i){return true;}v=v.parent;}return w instanceof i;};var f=this.Function;var r=true;for(var q in {toString:1}){r=null;}if(r){r=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];
}f.prototype.overloadSetter=function(v){var i=this;return function(x,w){if(x==null){return this;}if(v||typeof x!="string"){for(var y in x){i.call(this,y,x[y]);
}if(r){for(var z=r.length;z--;){y=r[z];if(x.hasOwnProperty(y)){i.call(this,y,x[y]);}}}}else{i.call(this,x,w);}return this;};};f.prototype.overloadGetter=function(v){var i=this;
return function(x){var y,w;if(v||typeof x!="string"){y=x;}else{if(arguments.length>1){y=arguments;}}if(y){w={};for(var z=0;z<y.length;z++){w[y[z]]=i.call(this,y[z]);
}}else{w=i.call(this,x);}return w;};};f.prototype.extend=function(i,v){this[i]=v;}.overloadSetter();f.prototype.implement=function(i,v){this.prototype[i]=v;
}.overloadSetter();var o=Array.prototype.slice;f.from=function(i){return(e(i)=="function")?i:function(){return i;};};Array.from=function(i){if(i==null){return[];
}return(k.isEnumerable(i)&&typeof i!="string")?(e(i)=="array")?i:o.call(i):[i];};Number.from=function(v){var i=parseFloat(v);return isFinite(i)?i:null;
};String.from=function(i){return i+"";};f.implement({hide:function(){this.$hidden=true;return this;},protect:function(){this.$protected=true;return this;
}});var k=this.Type=function(x,w){if(x){var v=x.toLowerCase();var i=function(y){return(e(y)==v);};k["is"+x]=i;if(w!=null){w.prototype.$family=(function(){return v;
}).hide();w.type=i;}}if(w==null){return null;}w.extend(this);w.$constructor=k;w.prototype.$constructor=w;return w;};var p=Object.prototype.toString;k.isEnumerable=function(i){return(i!=null&&typeof i.length=="number"&&p.call(i)!="[object Function]");
};var b={};var d=function(i){var v=e(i.prototype);return b[v]||(b[v]=[]);};var h=function(w,A){if(A&&A.$hidden){return;}var v=d(this);for(var x=0;x<v.length;
x++){var z=v[x];if(e(z)=="type"){h.call(z,w,A);}else{z.call(this,w,A);}}var y=this.prototype[w];if(y==null||!y.$protected){this.prototype[w]=A;}if(this[w]==null&&e(A)=="function"){t.call(this,w,function(i){return A.apply(i,o.call(arguments,1));
});}};var t=function(i,w){if(w&&w.$hidden){return;}var v=this[i];if(v==null||!v.$protected){this[i]=w;}};k.implement({implement:h.overloadSetter(),extend:t.overloadSetter(),alias:function(i,v){h.call(this,i,this.prototype[v]);
}.overloadSetter(),mirror:function(i){d(this).push(i);return this;}});new k("Type",k);var c=function(v,z,x){var w=(z!=Object),D=z.prototype;if(w){z=new k(v,z);
}for(var A=0,y=x.length;A<y;A++){var E=x[A],C=z[E],B=D[E];if(C){C.protect();}if(w&&B){delete D[E];D[E]=B.protect();}}if(w){z.implement(D);}return c;};c("String",String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","quote","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase"])("Array",Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"])("Number",Number,["toExponential","toFixed","toLocaleString","toPrecision"])("Function",f,["apply","call","bind"])("RegExp",RegExp,["exec","test"])("Object",Object,["create","defineProperty","defineProperties","keys","getPrototypeOf","getOwnPropertyDescriptor","getOwnPropertyNames","preventExtensions","isExtensible","seal","isSealed","freeze","isFrozen"])("Date",Date,["now"]);
Object.extend=t.overloadSetter();Date.extend("now",function(){return +(new Date);});new k("Boolean",Boolean);Number.prototype.$family=function(){return isFinite(this)?"number":"null";
}.hide();Number.extend("random",function(v,i){return Math.floor(Math.random()*(i-v+1)+v);});var l=Object.prototype.hasOwnProperty;Object.extend("forEach",function(i,w,x){for(var v in i){if(l.call(i,v)){w.call(x,i[v],v,i);
}}});Object.each=Object.forEach;Array.implement({forEach:function(x,y){for(var w=0,v=this.length;w<v;w++){if(w in this){x.call(y,this[w],w,this);}}},each:function(i,v){Array.forEach(this,i,v);
return this;}});var s=function(i){switch(e(i)){case"array":return i.clone();case"object":return Object.clone(i);default:return i;}};Array.implement("clone",function(){var v=this.length,w=new Array(v);
while(v--){w[v]=s(this[v]);}return w;});var a=function(v,i,w){switch(e(w)){case"object":if(e(v[i])=="object"){Object.merge(v[i],w);}else{v[i]=Object.clone(w);
}break;case"array":v[i]=w.clone();break;default:v[i]=w;}return v;};Object.extend({merge:function(C,y,x){if(e(y)=="string"){return a(C,y,x);}for(var B=1,w=arguments.length;
B<w;B++){var z=arguments[B];for(var A in z){a(C,A,z[A]);}}return C;},clone:function(i){var w={};for(var v in i){w[v]=s(i[v]);}return w;},append:function(z){for(var y=1,w=arguments.length;
y<w;y++){var v=arguments[y]||{};for(var x in v){z[x]=v[x];}}return z;}});["Object","WhiteSpace","TextNode","Collection","Arguments"].each(function(i){new k(i);
});var j=Date.now();String.extend("uniqueID",function(){return(j++).toString(36);});var g=this.Hash=new k("Hash",function(i){if(e(i)=="hash"){i=Object.clone(i.getClean());
}for(var v in i){this[v]=i[v];}return this;});g.implement({forEach:function(i,v){Object.forEach(this,i,v);},getClean:function(){var v={};for(var i in this){if(this.hasOwnProperty(i)){v[i]=this[i];
}}return v;},getLength:function(){var v=0;for(var i in this){if(this.hasOwnProperty(i)){v++;}}return v;}});g.alias("each","forEach");Object.type=k.isObject;
var n=this.Native=function(i){return new k(i.name,i.initialize);};n.type=k.type;n.implement=function(x,v){for(var w=0;w<x.length;w++){x[w].implement(v);
}return n;};var m=Array.type;Array.type=function(i){return u(i,Array)||m(i);};this.$A=function(i){return Array.from(i).slice();};this.$arguments=function(v){return function(){return arguments[v];
};};this.$chk=function(i){return !!(i||i===0);};this.$clear=function(i){clearTimeout(i);clearInterval(i);return null;};this.$defined=function(i){return(i!=null);
};this.$each=function(w,v,x){var i=e(w);((i=="arguments"||i=="collection"||i=="array"||i=="elements")?Array:Object).each(w,v,x);};this.$empty=function(){};
this.$extend=function(v,i){return Object.append(v,i);};this.$H=function(i){return new g(i);};this.$merge=function(){var i=Array.slice(arguments);i.unshift({});
return Object.merge.apply(null,i);};this.$lambda=f.from;this.$mixin=Object.merge;this.$random=Number.random;this.$splat=Array.from;this.$time=Date.now;
this.$type=function(i){var v=e(i);if(v=="elements"){return"array";}return(v=="null")?false:v;};this.$unlink=function(i){switch(e(i)){case"object":return Object.clone(i);
case"array":return Array.clone(i);case"hash":return new g(i);default:return i;}};}).call(this);Array.implement({invoke:function(a){var b=Array.slice(arguments,1);
return this.map(function(c){return c[a].apply(c,b);});},every:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&!c.call(d,this[b],b,this)){return false;
}}return true;},filter:function(d,e){var c=[];for(var b=0,a=this.length;b<a;b++){if((b in this)&&d.call(e,this[b],b,this)){c.push(this[b]);}}return c;},clean:function(){return this.filter(function(a){return a!=null;
});},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b;}}return -1;},map:function(d,e){var c=[];
for(var b=0,a=this.length;b<a;b++){if(b in this){c[b]=d.call(e,this[b],b,this);}}return c;},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&c.call(d,this[b],b,this)){return true;
}}return false;},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];}return d;},link:function(c){var a={};
for(var e=0,b=this.length;e<b;e++){for(var d in c){if(c[d](this[e])){a[d]=this[e];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;
},append:function(a){this.push.apply(this,a);return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[Number.random(0,this.length-1)]:null;
},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;
},erase:function(b){for(var a=this.length;a--;){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];
for(var b=0,a=this.length;b<a;b++){var c=typeOf(this[b]);if(c=="null"){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments"||instanceOf(this[b],Array))?Array.flatten(this[b]):this[b]);
}return d;},pick:function(){for(var b=0,a=this.length;b<a;b++){if(this[b]!=null){return this[b];}}return null;},hexToRgb:function(b){if(this.length!=3){return null;
}var a=this.map(function(c){if(c.length==1){c+=c;}return c.toInt(16);});return(b)?a:"rgb("+a+")";},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";
}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});Array.alias("extend","append");
var $pick=function(){return Array.from(arguments).pick();};String.implement({test:function(a,b){return((typeOf(a)=="regexp")?a:new RegExp(""+a,b)).test(this);
},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);
}return(a[c]!=null)?a[c]:"";});}});Number.implement({limit:function(b,a){return Math.min(a,Math.max(b,this));},round:function(a){a=Math.pow(10,a||0).toFixed(a<0?-a:0);
return Math.round(this*a)/a;},times:function(b,c){for(var a=0;a<this;a++){b.call(c,a,this);}},toFloat:function(){return parseFloat(this);},toInt:function(a){return parseInt(this,a||10);
}});Number.alias("each","times");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat(Array.from(arguments)));
};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);Function.extend({attempt:function(){for(var b=0,a=arguments.length;
b<a;b++){try{return arguments[b]();}catch(c){}}return null;}});Function.implement({attempt:function(a,c){try{return this.apply(c,Array.from(a));}catch(b){}return null;
},bind:function(c){var a=this,b=(arguments.length>1)?Array.slice(arguments,1):null;return function(){if(!b&&!arguments.length){return a.call(c);}if(b&&arguments.length){return a.apply(c,b.concat(Array.from(arguments)));
}return a.apply(c,b||arguments);};},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b);
},periodical:function(c,b,a){return setInterval(this.pass((a==null?[]:a),b),c);}});delete Function.prototype.bind;Function.implement({create:function(b){var a=this;
b=b||{};return function(d){var c=b.arguments;c=(c!=null)?Array.from(c):Array.slice(arguments,(b.event)?1:0);if(b.event){c=[d||window.event].extend(c);}var e=function(){return a.apply(b.bind||null,c);
};if(b.delay){return setTimeout(e,b.delay);}if(b.periodical){return setInterval(e,b.periodical);}if(b.attempt){return Function.attempt(e);}return e();};
},bind:function(c,b){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},bindWithEvent:function(c,b){var a=this;
if(b!=null){b=Array.from(b);}return function(d){return a.apply(c,(b==null)?arguments:[d].concat(b));};},run:function(a,b){return this.apply(b,Array.from(a));
}});var $try=Function.attempt;(function(){var a=Object.prototype.hasOwnProperty;Object.extend({subset:function(d,g){var f={};for(var e=0,b=g.length;e<b;
e++){var c=g[e];f[c]=d[c];}return f;},map:function(b,e,f){var d={};for(var c in b){if(a.call(b,c)){d[c]=e.call(f,b[c],c,b);}}return d;},filter:function(b,d,e){var c={};
Object.each(b,function(g,f){if(d.call(e,g,f,b)){c[f]=g;}});return c;},every:function(b,d,e){for(var c in b){if(a.call(b,c)&&!d.call(e,b[c],c)){return false;
}}return true;},some:function(b,d,e){for(var c in b){if(a.call(b,c)&&d.call(e,b[c],c)){return true;}}return false;},keys:function(b){var d=[];for(var c in b){if(a.call(b,c)){d.push(c);
}}return d;},values:function(c){var b=[];for(var d in c){if(a.call(c,d)){b.push(c[d]);}}return b;},getLength:function(b){return Object.keys(b).length;},keyOf:function(b,d){for(var c in b){if(a.call(b,c)&&b[c]===d){return c;
}}return null;},contains:function(b,c){return Object.keyOf(b,c)!=null;},toQueryString:function(b,c){var d=[];Object.each(b,function(h,g){if(c){g=c+"["+g+"]";
}var f;switch(typeOf(h)){case"object":f=Object.toQueryString(h,g);break;case"array":var e={};h.each(function(k,j){e[j]=k;});f=Object.toQueryString(e,g);
break;default:f=g+"="+encodeURIComponent(h);}if(h!=null){d.push(f);}});return d.join("&");}});})();Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(a){return Object.keyOf(this,a);
},hasValue:function(a){return Object.contains(this,a);},extend:function(a){Hash.each(a||{},function(c,b){Hash.set(this,b,c);},this);return this;},combine:function(a){Hash.each(a||{},function(c,b){Hash.include(this,b,c);
},this);return this;},erase:function(a){if(this.hasOwnProperty(a)){delete this[a];}return this;},get:function(a){return(this.hasOwnProperty(a))?this[a]:null;
},set:function(a,b){if(!this[a]||this.hasOwnProperty(a)){this[a]=b;}return this;},empty:function(){Hash.each(this,function(b,a){delete this[a];},this);
return this;},include:function(a,b){if(this[a]==null){this[a]=b;}return this;},map:function(a,b){return new Hash(Object.map(this,a,b));},filter:function(a,b){return new Hash(Object.filter(this,a,b));
},every:function(a,b){return Object.every(this,a,b);},some:function(a,b){return Object.some(this,a,b);},getKeys:function(){return Object.keys(this);},getValues:function(){return Object.values(this);
},toQueryString:function(a){return Object.toQueryString(this,a);}});Hash.extend=Object.append;Hash.alias({indexOf:"keyOf",contains:"hasValue"});(function(){var l=this.document;
var j=l.window=this;var b=1;this.$uid=(j.ActiveXObject)?function(e){return(e.uid||(e.uid=[b++]))[0];}:function(e){return e.uid||(e.uid=b++);};$uid(j);$uid(l);
var a=navigator.userAgent.toLowerCase(),c=navigator.platform.toLowerCase(),k=a.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],g=k[1]=="ie"&&l.documentMode;
var p=this.Browser={extend:Function.prototype.extend,name:(k[1]=="version")?k[3]:k[1],version:g||parseFloat((k[1]=="opera"&&k[4])?k[4]:k[2]),Platform:{name:a.match(/ip(?:ad|od|hone)/)?"ios":(a.match(/(?:webos|android)/)||c.match(/mac|win|linux/)||["other"])[0]},Features:{xpath:!!(l.evaluate),air:!!(j.runtime),query:!!(l.querySelector),json:!!(j.JSON)},Plugins:{}};
p[p.name]=true;p[p.name+parseInt(p.version,10)]=true;p.Platform[p.Platform.name]=true;p.Request=(function(){var r=function(){return new XMLHttpRequest();
};var q=function(){return new ActiveXObject("MSXML2.XMLHTTP");};var e=function(){return new ActiveXObject("Microsoft.XMLHTTP");};return Function.attempt(function(){r();
return r;},function(){q();return q;},function(){e();return e;});})();p.Features.xhr=!!(p.Request);var i=(Function.attempt(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);p.Plugins.Flash={version:Number(i[0]||"0."+i[1])||0,build:Number(i[2])||0};
p.exec=function(q){if(!q){return q;}if(j.execScript){j.execScript(q);}else{var e=l.createElement("script");e.setAttribute("type","text/javascript");e.text=q;
l.head.appendChild(e);l.head.removeChild(e);}return q;};String.implement("stripScripts",function(q){var e="";var r=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(s,t){e+=t+"\n";
return"";});if(q===true){p.exec(e);}else{if(typeOf(q)=="function"){q(e,r);}}return r;});p.extend({Document:this.Document,Window:this.Window,Element:this.Element,Event:this.Event});
this.Window=this.$constructor=new Type("Window",function(){});this.$family=Function.from("window").hide();Window.mirror(function(e,q){j[e]=q;});this.Document=l.$constructor=new Type("Document",function(){});
l.$family=Function.from("document").hide();Document.mirror(function(e,q){l[e]=q;});l.html=l.documentElement;l.head=l.getElementsByTagName("head")[0];if(l.execCommand){try{l.execCommand("BackgroundImageCache",false,true);
}catch(h){}}if(this.attachEvent&&!this.addEventListener){var d=function(){this.detachEvent("onunload",d);l.head=l.html=l.window=null;};this.attachEvent("onunload",d);
}var n=Array.from;try{n(l.html.childNodes);}catch(h){Array.from=function(q){if(typeof q!="string"&&Type.isEnumerable(q)&&typeOf(q)!="array"){var e=q.length,r=new Array(e);
while(e--){r[e]=q[e];}return r;}return n(q);};var m=Array.prototype,o=m.slice;["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice"].each(function(e){var q=m[e];
Array[e]=function(r){return q.apply(Array.from(r),o.call(arguments,1));};});}if(p.Platform.ios){p.Platform.ipod=true;}p.Engine={};var f=function(q,e){p.Engine.name=q;
p.Engine[q+e]=true;p.Engine.version=e;};if(p.ie){p.Engine.trident=true;switch(p.version){case 6:f("trident",4);break;case 7:f("trident",5);break;case 8:f("trident",6);
}}if(p.firefox){p.Engine.gecko=true;if(p.version>=3){f("gecko",19);}else{f("gecko",18);}}if(p.safari||p.chrome){p.Engine.webkit=true;switch(p.version){case 2:f("webkit",419);
break;case 3:f("webkit",420);break;case 4:f("webkit",525);}}if(p.opera){p.Engine.presto=true;if(p.version>=9.6){f("presto",960);}else{if(p.version>=9.5){f("presto",950);
}else{f("presto",925);}}}if(p.name=="unknown"){switch((a.match(/(?:webkit|khtml|gecko)/)||[])[0]){case"webkit":case"khtml":p.Engine.webkit=true;break;case"gecko":p.Engine.gecko=true;
}}this.$exec=p.exec;}).call(this);var Event=new Type("Event",function(a,i){if(!i){i=window;}var o=i.document;a=a||i.event;if(a.$extended){return a;}this.$extended=true;
var n=a.type,k=a.target||a.srcElement,m={},c={},q=null,h,l,b,p;while(k&&k.nodeType==3){k=k.parentNode;}if(n.indexOf("key")!=-1){b=a.which||a.keyCode;p=Object.keyOf(Event.Keys,b);
if(n=="keydown"){var d=b-111;if(d>0&&d<13){p="f"+d;}}if(!p){p=String.fromCharCode(b).toLowerCase();}}else{if((/click|mouse|menu/i).test(n)){o=(!o.compatMode||o.compatMode=="CSS1Compat")?o.html:o.body;
m={x:(a.pageX!=null)?a.pageX:a.clientX+o.scrollLeft,y:(a.pageY!=null)?a.pageY:a.clientY+o.scrollTop};c={x:(a.pageX!=null)?a.pageX-i.pageXOffset:a.clientX,y:(a.pageY!=null)?a.pageY-i.pageYOffset:a.clientY};
if((/DOMMouseScroll|mousewheel/).test(n)){l=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3;}h=(a.which==3)||(a.button==2);if((/over|out/).test(n)){q=a.relatedTarget||a[(n=="mouseover"?"from":"to")+"Element"];
var j=function(){while(q&&q.nodeType==3){q=q.parentNode;}return true;};var g=(Browser.firefox2)?j.attempt():j();q=(g)?q:null;}}else{if((/gesture|touch/i).test(n)){this.rotation=a.rotation;
this.scale=a.scale;this.targetTouches=a.targetTouches;this.changedTouches=a.changedTouches;var f=this.touches=a.touches;if(f&&f[0]){var e=f[0];m={x:e.pageX,y:e.pageY};
c={x:e.clientX,y:e.clientY};}}}}return Object.append(this,{event:a,type:n,page:m,client:c,rightClick:h,wheel:l,relatedTarget:document.id(q),target:document.id(k),code:b,key:p,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey});
});Event.Keys={enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46};Event.Keys=new Hash(Event.Keys);Event.implement({stop:function(){return this.stopPropagation().preventDefault();
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
}else{this.event.returnValue=false;}return this;}});(function(){var a=this.Class=new Type("Class",function(h){if(instanceOf(h,Function)){h={initialize:h};
}var g=function(){e(this);if(g.$prototyping){return this;}this.$caller=null;var i=(this.initialize)?this.initialize.apply(this,arguments):this;this.$caller=this.caller=null;
return i;}.extend(this).implement(h);g.$constructor=a;g.prototype.$constructor=g;g.prototype.parent=c;return g;});var c=function(){if(!this.$caller){throw new Error('The method "parent" cannot be called.');
}var g=this.$caller.$name,h=this.$caller.$owner.parent,i=(h)?h.prototype[g]:null;if(!i){throw new Error('The method "'+g+'" has no parent.');}return i.apply(this,arguments);
};var e=function(g){for(var h in g){var j=g[h];switch(typeOf(j)){case"object":var i=function(){};i.prototype=j;g[h]=e(new i);break;case"array":g[h]=j.clone();
break;}}return g;};var b=function(g,h,j){if(j.$origin){j=j.$origin;}var i=function(){if(j.$protected&&this.$caller==null){throw new Error('The method "'+h+'" cannot be called.');
}var l=this.caller,m=this.$caller;this.caller=m;this.$caller=i;var k=j.apply(this,arguments);this.$caller=m;this.caller=l;return k;}.extend({$owner:g,$origin:j,$name:h});
return i;};var f=function(h,i,g){if(a.Mutators.hasOwnProperty(h)){i=a.Mutators[h].call(this,i);if(i==null){return this;}}if(typeOf(i)=="function"){if(i.$hidden){return this;
}this.prototype[h]=(g)?i:b(this,h,i);}else{Object.merge(this.prototype,h,i);}return this;};var d=function(g){g.$prototyping=true;var h=new g;delete g.$prototyping;
return h;};a.implement("implement",f.overloadSetter());a.Mutators={Extends:function(g){this.parent=g;this.prototype=d(g);},Implements:function(g){Array.from(g).each(function(j){var h=new j;
for(var i in h){f.call(this,i,h[i],true);}},this);}};}).call(this);(function(){this.Chain=new Class({$chain:[],chain:function(){this.$chain.append(Array.flatten(arguments));
return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){this.$chain.empty();
return this;}});var a=function(b){return b.replace(/^on([A-Z])/,function(c,d){return d.toLowerCase();});};this.Events=new Class({$events:{},addEvent:function(d,c,b){d=a(d);
if(c==$empty){return this;}this.$events[d]=(this.$events[d]||[]).include(c);if(b){c.internal=true;}return this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
}return this;},fireEvent:function(e,c,b){e=a(e);var d=this.$events[e];if(!d){return this;}c=Array.from(c);d.each(function(f){if(b){f.delay(b,this,c);}else{f.apply(this,c);
}},this);return this;},removeEvent:function(e,d){e=a(e);var c=this.$events[e];if(c&&!d.internal){var b=c.indexOf(d);if(b!=-1){delete c[b];}}return this;
},removeEvents:function(d){var e;if(typeOf(d)=="object"){for(e in d){this.removeEvent(e,d[e]);}return this;}if(d){d=a(d);}for(e in this.$events){if(d&&d!=e){continue;
}var c=this.$events[e];for(var b=c.length;b--;){if(b in c){this.removeEvent(e,c[b]);}}}return this;}});this.Options=new Class({setOptions:function(){var b=this.options=Object.merge.apply(null,[{},this.options].append(arguments));
if(this.addEvent){for(var c in b){if(typeOf(b[c])!="function"||!(/^on[A-Z]/).test(c)){continue;}this.addEvent(c,b[c]);delete b[c];}}return this;}});}).call(this);
(function(){var k,n,l,g,a={},c={},m=/\\/g;var e=function(q,p){if(q==null){return null;}if(q.Slick===true){return q;}q=(""+q).replace(/^\s+|\s+$/g,"");g=!!p;
var o=(g)?c:a;if(o[q]){return o[q];}k={Slick:true,expressions:[],raw:q,reverse:function(){return e(this.raw,true);}};n=-1;while(q!=(q=q.replace(j,b))){}k.length=k.expressions.length;
return o[k.raw]=(g)?h(k):k;};var i=function(o){if(o==="!"){return" ";}else{if(o===" "){return"!";}else{if((/^!/).test(o)){return o.replace(/^!/,"");}else{return"!"+o;
}}}};var h=function(u){var r=u.expressions;for(var p=0;p<r.length;p++){var t=r[p];var q={parts:[],tag:"*",combinator:i(t[0].combinator)};for(var o=0;o<t.length;
o++){var s=t[o];if(!s.reverseCombinator){s.reverseCombinator=" ";}s.combinator=s.reverseCombinator;delete s.reverseCombinator;}t.reverse().push(q);}return u;
};var f=function(o){return o.replace(/[-[\]{}()*+?.\\^$|,#\s]/g,function(p){return"\\"+p;});};var j=new RegExp("^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)".replace(/<combinator>/,"["+f(">+~`!@$%^&={}\\;</")+"]").replace(/<unicode>/g,"(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])").replace(/<unicode1>/g,"(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])"));
function b(x,s,D,z,r,C,q,B,A,y,u,F,G,v,p,w){if(s||n===-1){k.expressions[++n]=[];l=-1;if(s){return"";}}if(D||z||l===-1){D=D||" ";var t=k.expressions[n];
if(g&&t[l]){t[l].reverseCombinator=i(D);}t[++l]={combinator:D,tag:"*"};}var o=k.expressions[n][l];if(r){o.tag=r.replace(m,"");}else{if(C){o.id=C.replace(m,"");
}else{if(q){q=q.replace(m,"");if(!o.classList){o.classList=[];}if(!o.classes){o.classes=[];}o.classList.push(q);o.classes.push({value:q,regexp:new RegExp("(^|\\s)"+f(q)+"(\\s|$)")});
}else{if(G){w=w||p;w=w?w.replace(m,""):null;if(!o.pseudos){o.pseudos=[];}o.pseudos.push({key:G.replace(m,""),value:w,type:F.length==1?"class":"element"});
}else{if(B){B=B.replace(m,"");u=(u||"").replace(m,"");var E,H;switch(A){case"^=":H=new RegExp("^"+f(u));break;case"$=":H=new RegExp(f(u)+"$");break;case"~=":H=new RegExp("(^|\\s)"+f(u)+"(\\s|$)");
break;case"|=":H=new RegExp("^"+f(u)+"(-|$)");break;case"=":E=function(I){return u==I;};break;case"*=":E=function(I){return I&&I.indexOf(u)>-1;};break;
case"!=":E=function(I){return u!=I;};break;default:E=function(I){return !!I;};}if(u==""&&(/^[*$^]=$/).test(A)){E=function(){return false;};}if(!E){E=function(I){return I&&H.test(I);
};}if(!o.attributes){o.attributes=[];}o.attributes.push({key:B,operator:A,value:u,test:E});}}}}}return"";}var d=(this.Slick||{});d.parse=function(o){return e(o);
};d.escapeRegExp=f;if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);(function(){var j={},l={},b=Object.prototype.toString;
j.isNativeCode=function(c){return(/\{\s*\[native code\]\s*\}/).test(""+c);};j.isXML=function(c){return(!!c.xmlVersion)||(!!c.xml)||(b.call(c)=="[object XMLDocument]")||(c.nodeType==9&&c.documentElement.nodeName!="HTML");
};j.setDocument=function(w){var t=w.nodeType;if(t==9){}else{if(t){w=w.ownerDocument;}else{if(w.navigator){w=w.document;}else{return;}}}if(this.document===w){return;
}this.document=w;var y=w.documentElement,u=this.getUIDXML(y),o=l[u],A;if(o){for(A in o){this[A]=o[A];}return;}o=l[u]={};o.root=y;o.isXMLDocument=this.isXML(w);
o.brokenStarGEBTN=o.starSelectsClosedQSA=o.idGetsName=o.brokenMixedCaseQSA=o.brokenGEBCN=o.brokenCheckedQSA=o.brokenEmptyAttributeQSA=o.isHTMLDocument=o.nativeMatchesSelector=false;
var m,n,x,q,r;var s,c="slick_uniqueid";var z=w.createElement("div");var p=w.body||w.getElementsByTagName("body")[0]||y;p.appendChild(z);try{z.innerHTML='<a id="'+c+'"></a>';
o.isHTMLDocument=!!w.getElementById(c);}catch(v){}if(o.isHTMLDocument){z.style.display="none";z.appendChild(w.createComment(""));n=(z.getElementsByTagName("*").length>1);
try{z.innerHTML="foo</foo>";s=z.getElementsByTagName("*");m=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");}catch(v){}o.brokenStarGEBTN=n||m;try{z.innerHTML='<a name="'+c+'"></a><b id="'+c+'"></b>';
o.idGetsName=w.getElementById(c)===z.firstChild;}catch(v){}if(z.getElementsByClassName){try{z.innerHTML='<a class="f"></a><a class="b"></a>';z.getElementsByClassName("b").length;
z.firstChild.className="b";q=(z.getElementsByClassName("b").length!=2);}catch(v){}try{z.innerHTML='<a class="a"></a><a class="f b a"></a>';x=(z.getElementsByClassName("a").length!=2);
}catch(v){}o.brokenGEBCN=q||x;}if(z.querySelectorAll){try{z.innerHTML="foo</foo>";s=z.querySelectorAll("*");o.starSelectsClosedQSA=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");
}catch(v){}try{z.innerHTML='<a class="MiX"></a>';o.brokenMixedCaseQSA=!z.querySelectorAll(".MiX").length;}catch(v){}try{z.innerHTML='<select><option selected="selected">a</option></select>';
o.brokenCheckedQSA=(z.querySelectorAll(":checked").length==0);}catch(v){}try{z.innerHTML='<a class=""></a>';o.brokenEmptyAttributeQSA=(z.querySelectorAll('[class*=""]').length!=0);
}catch(v){}}try{z.innerHTML='<form action="s"><input id="action"/></form>';r=(z.firstChild.getAttribute("action")!="s");}catch(v){}o.nativeMatchesSelector=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector;
if(o.nativeMatchesSelector){try{o.nativeMatchesSelector.call(y,":slick");o.nativeMatchesSelector=null;}catch(v){}}}try{y.slick_expando=1;delete y.slick_expando;
o.getUID=this.getUIDHTML;}catch(v){o.getUID=this.getUIDXML;}p.removeChild(z);z=s=p=null;o.getAttribute=(o.isHTMLDocument&&r)?function(D,B){var E=this.attributeGetters[B];
if(E){return E.call(D);}var C=D.getAttributeNode(B);return(C)?C.nodeValue:null;}:function(C,B){var D=this.attributeGetters[B];return(D)?D.call(C):C.getAttribute(B);
};o.hasAttribute=(y&&this.isNativeCode(y.hasAttribute))?function(C,B){return C.hasAttribute(B);}:function(C,B){C=C.getAttributeNode(B);return !!(C&&(C.specified||C.nodeValue));
};o.contains=(y&&this.isNativeCode(y.contains))?function(B,C){return B.contains(C);}:(y&&y.compareDocumentPosition)?function(B,C){return B===C||!!(B.compareDocumentPosition(C)&16);
}:function(B,C){if(C){do{if(C===B){return true;}}while((C=C.parentNode));}return false;};o.documentSorter=(y.compareDocumentPosition)?function(C,B){if(!C.compareDocumentPosition||!B.compareDocumentPosition){return 0;
}return C.compareDocumentPosition(B)&4?-1:C===B?0:1;}:("sourceIndex" in y)?function(C,B){if(!C.sourceIndex||!B.sourceIndex){return 0;}return C.sourceIndex-B.sourceIndex;
}:(w.createRange)?function(E,C){if(!E.ownerDocument||!C.ownerDocument){return 0;}var D=E.ownerDocument.createRange(),B=C.ownerDocument.createRange();D.setStart(E,0);
D.setEnd(E,0);B.setStart(C,0);B.setEnd(C,0);return D.compareBoundaryPoints(Range.START_TO_END,B);}:null;y=null;for(A in o){this[A]=o[A];}};var e=/^([#.]?)((?:[\w-]+|\*))$/,g=/\[.+[*$^]=(?:""|'')?\]/,f={};
j.search=function(q,D,O,v){var B=this.found=(v)?null:(O||[]);if(!q){return B;}else{if(q.navigator){q=q.document;}else{if(!q.nodeType){return B;}}}var z,N,s=this.uniques={},y=!!(O&&O.length),c=(q.nodeType==9);
if(this.document!==(c?q:q.ownerDocument)){this.setDocument(q);}if(y){for(N=B.length;N--;){s[this.getUID(B[N])]=true;}}if(typeof D=="string"){var C=D.match(e);
simpleSelectors:if(C){var K=C[1],V=C[2],I,G;if(!K){if(V=="*"&&this.brokenStarGEBTN){break simpleSelectors;}G=q.getElementsByTagName(V);if(v){return G[0]||null;
}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{if(K=="#"){if(!this.isHTMLDocument||!c){break simpleSelectors;}I=q.getElementById(V);
if(!I){return B;}if(this.idGetsName&&I.getAttributeNode("id").nodeValue!=V){break simpleSelectors;}if(v){return I||null;}if(!(y&&s[this.getUID(I)])){B.push(I);
}}else{if(K=="."){if(!this.isHTMLDocument||((!q.getElementsByClassName||this.brokenGEBCN)&&q.querySelectorAll)){break simpleSelectors;}if(q.getElementsByClassName&&!this.brokenGEBCN){G=q.getElementsByClassName(V);
if(v){return G[0]||null;}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{var u=new RegExp("(^|\\s)"+d.escapeRegExp(V)+"(\\s|$)");G=q.getElementsByTagName("*");
for(N=0;I=G[N++];){className=I.className;if(!(className&&u.test(className))){continue;}if(v){return I;}if(!(y&&s[this.getUID(I)])){B.push(I);}}}}}}if(y){this.sort(B);
}return(v)?null:B;}querySelector:if(q.querySelectorAll){if(!this.isHTMLDocument||this.brokenMixedCaseQSA||f[D]||(this.brokenCheckedQSA&&D.indexOf(":checked")>-1)||(this.brokenEmptyAttributeQSA&&g.test(D))||d.disableQSA){break querySelector;
}var A=D;if(!c){var M=q.getAttribute("id"),p="slickid__";q.setAttribute("id",p);A="#"+p+" "+A;}try{if(v){return q.querySelector(A)||null;}else{G=q.querySelectorAll(A);
}}catch(P){f[D]=1;break querySelector;}finally{if(!c){if(M){q.setAttribute("id",M);}else{q.removeAttribute("id");}}}if(this.starSelectsClosedQSA){for(N=0;
I=G[N++];){if(I.nodeName>"@"&&!(y&&s[this.getUID(I)])){B.push(I);}}}else{for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}if(y){this.sort(B);
}return B;}z=this.Slick.parse(D);if(!z.length){return B;}}else{if(D==null){return B;}else{if(D.Slick){z=D;}else{if(this.contains(q.documentElement||q,D)){(B)?B.push(D):B=D;
return B;}else{return B;}}}}this.posNTH={};this.posNTHLast={};this.posNTHType={};this.posNTHTypeLast={};this.push=(!y&&(v||(z.length==1&&z.expressions[0].length==1)))?this.pushArray:this.pushUID;
if(B==null){B=[];}var L,H,F;var J,U,E,T,Q,x,t;var w,r,o,R,S=z.expressions;search:for(N=0;(r=S[N]);N++){for(L=0;(o=r[L]);L++){J="combinator:"+o.combinator;
if(!this[J]){continue search;}U=(this.isXMLDocument)?o.tag:o.tag.toUpperCase();E=o.id;T=o.classList;Q=o.classes;x=o.attributes;t=o.pseudos;R=(L===(r.length-1));
this.bitUniques={};if(R){this.uniques=s;this.found=B;}else{this.uniques={};this.found=[];}if(L===0){this[J](q,U,E,Q,x,t,T);if(v&&R&&B.length){break search;
}}else{if(v&&R){for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);if(B.length){break search;}}}else{for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);
}}}w=this.found;}}if(y||(z.expressions.length>1)){this.sort(B);}return(v)?(B[0]||null):B;};j.uidx=1;j.uidk="slick-uniqueid";j.getUIDXML=function(m){var c=m.getAttribute(this.uidk);
if(!c){c=this.uidx++;m.setAttribute(this.uidk,c);}return c;};j.getUIDHTML=function(c){return c.uniqueNumber||(c.uniqueNumber=this.uidx++);};j.sort=function(c){if(!this.documentSorter){return c;
}c.sort(this.documentSorter);return c;};j.cacheNTH={};j.matchNTH=/^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;j.parseNTHArgument=function(p){var n=p.match(this.matchNTH);
if(!n){return false;}var o=n[2]||false;var m=n[1]||1;if(m=="-"){m=-1;}var c=+n[3]||0;n=(o=="n")?{a:m,b:c}:(o=="odd")?{a:2,b:1}:(o=="even")?{a:2,b:0}:{a:0,b:m};
return(this.cacheNTH[p]=n);};j.createNTHPseudo=function(o,m,c,n){return function(r,p){var t=this.getUID(r);if(!this[c][t]){var z=r.parentNode;if(!z){return false;
}var q=z[o],s=1;if(n){var y=r.nodeName;do{if(q.nodeName!=y){continue;}this[c][this.getUID(q)]=s++;}while((q=q[m]));}else{do{if(q.nodeType!=1){continue;
}this[c][this.getUID(q)]=s++;}while((q=q[m]));}}p=p||"n";var u=this.cacheNTH[p]||this.parseNTHArgument(p);if(!u){return false;}var x=u.a,w=u.b,v=this[c][t];
if(x==0){return w==v;}if(x>0){if(v<w){return false;}}else{if(w<v){return false;}}return((v-w)%x)==0;};};j.pushArray=function(o,c,q,n,m,p){if(this.matchSelector(o,c,q,n,m,p)){this.found.push(o);
}};j.pushUID=function(p,c,r,o,m,q){var n=this.getUID(p);if(!this.uniques[n]&&this.matchSelector(p,c,r,o,m,q)){this.uniques[n]=true;this.found.push(p);}};
j.matchNode=function(m,n){if(this.isHTMLDocument&&this.nativeMatchesSelector){try{return this.nativeMatchesSelector.call(m,n.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g,'[$1="$2"]'));
}catch(u){}}var t=this.Slick.parse(n);if(!t){return true;}var r=t.expressions,p,s=0,q;for(q=0;(currentExpression=r[q]);q++){if(currentExpression.length==1){var o=currentExpression[0];
if(this.matchSelector(m,(this.isXMLDocument)?o.tag:o.tag.toUpperCase(),o.id,o.classes,o.attributes,o.pseudos)){return true;}s++;}}if(s==t.length){return false;
}var c=this.search(this.document,t),v;for(q=0;v=c[q++];){if(v===m){return true;}}return false;};j.matchPseudo=function(p,c,o){var m="pseudo:"+c;if(this[m]){return this[m](p,o);
}var n=this.getAttribute(p,c);return(o)?o==n:!!n;};j.matchSelector=function(n,u,c,o,p,r){if(u){var s=(this.isXMLDocument)?n.nodeName:n.nodeName.toUpperCase();
if(u=="*"){if(s<"@"){return false;}}else{if(s!=u){return false;}}}if(c&&n.getAttribute("id")!=c){return false;}var q,m,t;if(o){for(q=o.length;q--;){t=n.getAttribute("class")||n.className;
if(!(t&&o[q].regexp.test(t))){return false;}}}if(p){for(q=p.length;q--;){m=p[q];if(m.operator?!m.test(this.getAttribute(n,m.key)):!this.hasAttribute(n,m.key)){return false;
}}}if(r){for(q=r.length;q--;){m=r[q];if(!this.matchPseudo(n,m.key,m.value)){return false;}}}return true;};var i={" ":function(p,v,m,q,r,t,o){var s,u,n;
if(this.isHTMLDocument){getById:if(m){u=this.document.getElementById(m);if((!u&&p.all)||(this.idGetsName&&u&&u.getAttributeNode("id").nodeValue!=m)){n=p.all[m];
if(!n){return;}if(!n[0]){n=[n];}for(s=0;u=n[s++];){var c=u.getAttributeNode("id");if(c&&c.nodeValue==m){this.push(u,v,null,q,r,t);break;}}return;}if(!u){if(this.contains(this.root,p)){return;
}else{break getById;}}else{if(this.document!==p&&!this.contains(p,u)){return;}}this.push(u,v,null,q,r,t);return;}getByClass:if(q&&p.getElementsByClassName&&!this.brokenGEBCN){n=p.getElementsByClassName(o.join(" "));
if(!(n&&n.length)){break getByClass;}for(s=0;u=n[s++];){this.push(u,v,m,null,r,t);}return;}}getByTag:{n=p.getElementsByTagName(v);if(!(n&&n.length)){break getByTag;
}if(!this.brokenStarGEBTN){v=null;}for(s=0;u=n[s++];){this.push(u,v,m,q,r,t);}}},">":function(o,c,q,n,m,p){if((o=o.firstChild)){do{if(o.nodeType==1){this.push(o,c,q,n,m,p);
}}while((o=o.nextSibling));}},"+":function(o,c,q,n,m,p){while((o=o.nextSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);break;}}},"^":function(o,c,q,n,m,p){o=o.firstChild;
if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:+"](o,c,q,n,m,p);}}},"~":function(p,c,r,o,m,q){while((p=p.nextSibling)){if(p.nodeType!=1){continue;
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}},"++":function(o,c,q,n,m,p){this["combinator:+"](o,c,q,n,m,p);
this["combinator:!+"](o,c,q,n,m,p);},"~~":function(o,c,q,n,m,p){this["combinator:~"](o,c,q,n,m,p);this["combinator:!~"](o,c,q,n,m,p);},"!":function(o,c,q,n,m,p){while((o=o.parentNode)){if(o!==this.document){this.push(o,c,q,n,m,p);
}}},"!>":function(o,c,q,n,m,p){o=o.parentNode;if(o!==this.document){this.push(o,c,q,n,m,p);}},"!+":function(o,c,q,n,m,p){while((o=o.previousSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);
break;}}},"!^":function(o,c,q,n,m,p){o=o.lastChild;if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:!+"](o,c,q,n,m,p);}}},"!~":function(p,c,r,o,m,q){while((p=p.previousSibling)){if(p.nodeType!=1){continue;
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}}};for(var h in i){j["combinator:"+h]=i[h];}var k={empty:function(c){var m=c.firstChild;
return !(m&&m.nodeType==1)&&!(c.innerText||c.textContent||"").length;},not:function(c,m){return !this.matchNode(c,m);},contains:function(c,m){return(c.innerText||c.textContent||"").indexOf(m)>-1;
},"first-child":function(c){while((c=c.previousSibling)){if(c.nodeType==1){return false;}}return true;},"last-child":function(c){while((c=c.nextSibling)){if(c.nodeType==1){return false;
}}return true;},"only-child":function(n){var m=n;while((m=m.previousSibling)){if(m.nodeType==1){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeType==1){return false;
}}return true;},"nth-child":j.createNTHPseudo("firstChild","nextSibling","posNTH"),"nth-last-child":j.createNTHPseudo("lastChild","previousSibling","posNTHLast"),"nth-of-type":j.createNTHPseudo("firstChild","nextSibling","posNTHType",true),"nth-last-of-type":j.createNTHPseudo("lastChild","previousSibling","posNTHTypeLast",true),index:function(m,c){return this["pseudo:nth-child"](m,""+c+1);
},even:function(c){return this["pseudo:nth-child"](c,"2n");},odd:function(c){return this["pseudo:nth-child"](c,"2n+1");},"first-of-type":function(c){var m=c.nodeName;
while((c=c.previousSibling)){if(c.nodeName==m){return false;}}return true;},"last-of-type":function(c){var m=c.nodeName;while((c=c.nextSibling)){if(c.nodeName==m){return false;
}}return true;},"only-of-type":function(n){var m=n,o=n.nodeName;while((m=m.previousSibling)){if(m.nodeName==o){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeName==o){return false;
}}return true;},enabled:function(c){return !c.disabled;},disabled:function(c){return c.disabled;},checked:function(c){return c.checked||c.selected;},focus:function(c){return this.isHTMLDocument&&this.document.activeElement===c&&(c.href||c.type||this.hasAttribute(c,"tabindex"));
},root:function(c){return(c===this.root);},selected:function(c){return c.selected;}};for(var a in k){j["pseudo:"+a]=k[a];}j.attributeGetters={"class":function(){return this.getAttribute("class")||this.className;
},"for":function(){return("htmlFor" in this)?this.htmlFor:this.getAttribute("for");},href:function(){return("href" in this)?this.getAttribute("href",2):this.getAttribute("href");
},style:function(){return(this.style)?this.style.cssText:this.getAttribute("style");},tabindex:function(){var c=this.getAttributeNode("tabindex");return(c&&c.specified)?c.nodeValue:null;
},type:function(){return this.getAttribute("type");}};var d=j.Slick=(this.Slick||{});d.version="1.1.5";d.search=function(m,n,c){return j.search(m,n,c);
};d.find=function(c,m){return j.search(c,m,null,true);};d.contains=function(c,m){j.setDocument(c);return j.contains(c,m);};d.getAttribute=function(m,c){return j.getAttribute(m,c);
};d.match=function(m,c){if(!(m&&c)){return false;}if(!c||c===m){return true;}j.setDocument(m);return j.matchNode(m,c);};d.defineAttributeGetter=function(c,m){j.attributeGetters[c]=m;
return this;};d.lookupAttributeGetter=function(c){return j.attributeGetters[c];};d.definePseudo=function(c,m){j["pseudo:"+c]=function(o,n){return m.call(o,n);
};return this;};d.lookupPseudo=function(c){var m=j["pseudo:"+c];if(m){return function(n){return m.call(this,n);};}return null;};d.override=function(m,c){j.override(m,c);
return this;};d.isXML=j.isXML;d.uidOf=function(c){return j.getUIDHTML(c);};if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);
var Element=function(b,g){var h=Element.Constructors[b];if(h){return h(g);}if(typeof b!="string"){return document.id(b).set(g);}if(!g){g={};}if(!(/^[\w-]+$/).test(b)){var e=Slick.parse(b).expressions[0][0];
b=(e.tag=="*")?"div":e.tag;if(e.id&&g.id==null){g.id=e.id;}var d=e.attributes;if(d){for(var f=0,c=d.length;f<c;f++){var a=d[f];if(a.value!=null&&a.operator=="="&&g[a.key]==null){g[a.key]=a.value;
}}}if(e.classList&&g["class"]==null){g["class"]=e.classList.join(" ");}}return document.newElement(b,g);};if(Browser.Element){Element.prototype=Browser.Element.prototype;
}new Type("Element",Element).mirror(function(a){if(Array.prototype[a]){return;}var b={};b[a]=function(){var h=[],e=arguments,j=true;for(var g=0,d=this.length;
g<d;g++){var f=this[g],c=h[g]=f[a].apply(f,e);j=(j&&typeOf(c)=="element");}return(j)?new Elements(h):h;};Elements.implement(b);});if(!Browser.Element){Element.parent=Object;
Element.Prototype={"$family":Function.from("element").hide()};Element.mirror(function(a,b){Element.Prototype[a]=b;});}Element.Constructors={};Element.Constructors=new Hash;
var IFrame=new Type("IFrame",function(){var e=Array.link(arguments,{properties:Type.isObject,iframe:function(f){return(f!=null);}});var c=e.properties||{},b;
if(e.iframe){b=document.id(e.iframe);}var d=c.onload||function(){};delete c.onload;c.id=c.name=[c.id,c.name,b?(b.id||b.name):"IFrame_"+String.uniqueID()].pick();
b=new Element(b||"iframe",c);var a=function(){d.call(b.contentWindow);};if(window.frames[c.id]){a();}else{b.addListener("load",a);}return b;});var Elements=this.Elements=function(a){if(a&&a.length){var e={},d;
for(var c=0;d=a[c++];){var b=Slick.uidOf(d);if(!e[b]){e[b]=true;this.push(d);}}}};Elements.prototype={length:0};Elements.parent=Array;new Type("Elements",Elements).implement({filter:function(a,b){if(!a){return this;
}return new Elements(Array.filter(this,(typeOf(a)=="string")?function(c){return c.match(a);}:a,b));}.protect(),push:function(){var d=this.length;for(var b=0,a=arguments.length;
b<a;b++){var c=document.id(arguments[b]);if(c){this[d++]=c;}}return(this.length=d);}.protect(),unshift:function(){var b=[];for(var c=0,a=arguments.length;
c<a;c++){var d=document.id(arguments[c]);if(d){b.push(d);}}return Array.prototype.unshift.apply(this,b);}.protect(),concat:function(){var b=new Elements(this);
for(var c=0,a=arguments.length;c<a;c++){var d=arguments[c];if(Type.isEnumerable(d)){b.append(d);}else{b.push(d);}}return b;}.protect(),append:function(c){for(var b=0,a=c.length;
b<a;b++){this.push(c[b]);}return this;}.protect(),empty:function(){while(this.length){delete this[--this.length];}return this;}.protect()});Elements.alias("extend","append");
(function(){var g=Array.prototype.splice,b={"0":0,"1":1,length:2};g.call(b,1,1);if(b[1]==1){Elements.implement("splice",function(){var e=this.length;g.apply(this,arguments);
while(e>=this.length){delete this[e--];}return this;}.protect());}Elements.implement(Array.prototype);Array.mirror(Elements);var f;try{var a=document.createElement("<input name=x>");
f=(a.name=="x");}catch(c){}var d=function(e){return(""+e).replace(/&/g,"&amp;").replace(/"/g,"&quot;");};Document.implement({newElement:function(e,h){if(h&&h.checked!=null){h.defaultChecked=h.checked;
}if(f&&h){e="<"+e;if(h.name){e+=' name="'+d(h.name)+'"';}if(h.type){e+=' type="'+d(h.type)+'"';}e+=">";delete h.name;delete h.type;}return this.id(this.createElement(e)).set(h);
}});})();Document.implement({newTextNode:function(a){return this.createTextNode(a);},getDocument:function(){return this;},getWindow:function(){return this.window;
},id:(function(){var a={string:function(d,c,b){d=Slick.find(b,"#"+d.replace(/(\W)/g,"\\$1"));return(d)?a.element(d,c):null;},element:function(b,c){$uid(b);
if(!c&&!b.$family&&!(/^(?:object|embed)$/i).test(b.tagName)){Object.append(b,Element.Prototype);}return b;},object:function(c,d,b){if(c.toElement){return a.element(c.toElement(b),d);
}return null;}};a.textnode=a.whitespace=a.window=a.document=function(b){return b;};return function(c,e,d){if(c&&c.$family&&c.uid){return c;}var b=typeOf(c);
return(a[b])?a[b](c,e,d||document):null;};})()});if(window.$==null){Window.implement("$",function(a,b){return document.id(a,b,this.document);});}Window.implement({getDocument:function(){return this.document;
},getWindow:function(){return this;}});[Document,Element].invoke("implement",{getElements:function(a){return Slick.search(this,a,new Elements);},getElement:function(a){return document.id(Slick.find(this,a));
}});(function(b,d,a){this.Selectors={};var e=this.Selectors.Pseudo=new Hash();var c=function(){for(var f in e){if(e.hasOwnProperty(f)){Slick.definePseudo(f,e[f]);
delete e[f];}}};Slick.search=function(g,h,f){c();return b.call(this,g,h,f);};Slick.find=function(f,g){c();return d.call(this,f,g);};Slick.match=function(g,f){c();
return a.call(this,g,f);};})(Slick.search,Slick.find,Slick.match);if(window.$$==null){Window.implement("$$",function(a){var f=new Elements;if(arguments.length==1&&typeof a=="string"){return Slick.search(this.document,a,f);
}var c=Array.flatten(arguments);for(var d=0,b=c.length;d<b;d++){var e=c[d];switch(typeOf(e)){case"element":f.push(e);break;case"string":Slick.search(this.document,e,f);
}}return f;});}if(window.$$==null){Window.implement("$$",function(a){if(arguments.length==1){if(typeof a=="string"){return Slick.search(this.document,a,new Elements);
}else{if(Type.isEnumerable(a)){return new Elements(a);}}}return new Elements(arguments);});}(function(){var k={},i={};var n={input:"checked",option:"selected",textarea:"value"};
var e=function(p){return(i[p]||(i[p]={}));};var j=function(q){var p=q.uid;if(q.removeEvents){q.removeEvents();}if(q.clearAttributes){q.clearAttributes();
}if(p!=null){delete k[p];delete i[p];}return q;};var o=["defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];
var d=["compact","nowrap","ismap","declare","noshade","checked","disabled","readOnly","multiple","selected","noresize","defer","defaultChecked"];var g={html:"innerHTML","class":"className","for":"htmlFor",text:(function(){var p=document.createElement("div");
return(p.textContent==null)?"innerText":"textContent";})()};var m=["type"];var h=["value","defaultValue"];var l=/^(?:href|src|usemap)$/i;d=d.associate(d);
o=o.associate(o.map(String.toLowerCase));m=m.associate(m);Object.append(g,h.associate(h));var c={before:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p);
}},after:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p.nextSibling);}},bottom:function(q,p){p.appendChild(q);},top:function(q,p){p.insertBefore(q,p.firstChild);
}};c.inside=c.bottom;Object.each(c,function(q,r){r=r.capitalize();var p={};p["inject"+r]=function(s){q(this,document.id(s,true));return this;};p["grab"+r]=function(s){q(document.id(s,true),this);
return this;};Element.implement(p);});var b=function(s,r){if(!s){return r;}s=Object.clone(Slick.parse(s));var q=s.expressions;for(var p=q.length;p--;){q[p][0].combinator=r;
}return s;};Element.implement({set:function(r,q){var p=Element.Properties[r];(p&&p.set)?p.set.call(this,q):this.setProperty(r,q);}.overloadSetter(),get:function(q){var p=Element.Properties[q];
return(p&&p.get)?p.get.apply(this):this.getProperty(q);}.overloadGetter(),erase:function(q){var p=Element.Properties[q];(p&&p.erase)?p.erase.apply(this):this.removeProperty(q);
return this;},setProperty:function(q,r){q=o[q]||q;if(r==null){return this.removeProperty(q);}var p=g[q];(p)?this[p]=r:(d[q])?this[q]=!!r:this.setAttribute(q,""+r);
return this;},setProperties:function(p){for(var q in p){this.setProperty(q,p[q]);}return this;},getProperty:function(q){q=o[q]||q;var p=g[q]||m[q];return(p)?this[p]:(d[q])?!!this[q]:(l.test(q)?this.getAttribute(q,2):(p=this.getAttributeNode(q))?p.nodeValue:null)||null;
},getProperties:function(){var p=Array.from(arguments);return p.map(this.getProperty,this).associate(p);},removeProperty:function(q){q=o[q]||q;var p=g[q];
(p)?this[p]="":(d[q])?this[q]=false:this.removeAttribute(q);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;
},hasClass:function(p){return this.className.clean().contains(p," ");},addClass:function(p){if(!this.hasClass(p)){this.className=(this.className+" "+p).clean();
}return this;},removeClass:function(p){this.className=this.className.replace(new RegExp("(^|\\s)"+p+"(?:\\s|$)"),"$1");return this;},toggleClass:function(p,q){if(q==null){q=!this.hasClass(p);
}return(q)?this.addClass(p):this.removeClass(p);},adopt:function(){var s=this,p,u=Array.flatten(arguments),t=u.length;if(t>1){s=p=document.createDocumentFragment();
}for(var r=0;r<t;r++){var q=document.id(u[r],true);if(q){s.appendChild(q);}}if(p){this.appendChild(p);}return this;},appendText:function(q,p){return this.grab(this.getDocument().newTextNode(q),p);
},grab:function(q,p){c[p||"bottom"](document.id(q,true),this);return this;},inject:function(q,p){c[p||"bottom"](this,document.id(q,true));return this;},replaces:function(p){p=document.id(p,true);
p.parentNode.replaceChild(this,p);return this;},wraps:function(q,p){q=document.id(q,true);return this.replaces(q).grab(q,p);},getPrevious:function(p){return document.id(Slick.find(this,b(p,"!~")));
},getAllPrevious:function(p){return Slick.search(this,b(p,"!~"),new Elements);},getNext:function(p){return document.id(Slick.find(this,b(p,"~")));},getAllNext:function(p){return Slick.search(this,b(p,"~"),new Elements);
},getFirst:function(p){return document.id(Slick.search(this,b(p,">"))[0]);},getLast:function(p){return document.id(Slick.search(this,b(p,">")).getLast());
},getParent:function(p){return document.id(Slick.find(this,b(p,"!")));},getParents:function(p){return Slick.search(this,b(p,"!"),new Elements);},getSiblings:function(p){return Slick.search(this,b(p,"~~"),new Elements);
},getChildren:function(p){return Slick.search(this,b(p,">"),new Elements);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;
},getElementById:function(p){return document.id(Slick.find(this,"#"+(""+p).replace(/(\W)/g,"\\$1")));},getSelected:function(){this.selectedIndex;return new Elements(Array.from(this.options).filter(function(p){return p.selected;
}));},toQueryString:function(){var p=[];this.getElements("input, select, textarea").each(function(r){var q=r.type;if(!r.name||r.disabled||q=="submit"||q=="reset"||q=="file"||q=="image"){return;
}var s=(r.get("tag")=="select")?r.getSelected().map(function(t){return document.id(t).get("value");}):((q=="radio"||q=="checkbox")&&!r.checked)?null:r.get("value");
Array.from(s).each(function(t){if(typeof t!="undefined"){p.push(encodeURIComponent(r.name)+"="+encodeURIComponent(t));}});});return p.join("&");},destroy:function(){var p=j(this).getElementsByTagName("*");
Array.each(p,j);Element.dispose(this);return null;},empty:function(){Array.from(this.childNodes).each(Element.dispose);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
},match:function(p){return !p||Slick.match(this,p);}});var a=function(t,s,q){if(!q){t.setAttributeNode(document.createAttribute("id"));}if(t.clearAttributes){t.clearAttributes();
t.mergeAttributes(s);t.removeAttribute("uid");if(t.options){var u=t.options,p=s.options;for(var r=u.length;r--;){u[r].selected=p[r].selected;}}}var v=n[s.tagName.toLowerCase()];
if(v&&s[v]){t[v]=s[v];}};Element.implement("clone",function(r,p){r=r!==false;var w=this.cloneNode(r),q;if(r){var s=w.getElementsByTagName("*"),u=this.getElementsByTagName("*");
for(q=s.length;q--;){a(s[q],u[q],p);}}a(w,this,p);if(Browser.ie){var t=w.getElementsByTagName("object"),v=this.getElementsByTagName("object");for(q=t.length;
q--;){t[q].outerHTML=v[q].outerHTML;}}return document.id(w);});var f={contains:function(p){return Slick.contains(this,p);}};if(!document.contains){Document.implement(f);
}if(!document.createElement("div").contains){Element.implement(f);}Element.implement("hasChild",function(p){return this!==p&&this.contains(p);});[Element,Window,Document].invoke("implement",{addListener:function(s,r){if(s=="unload"){var p=r,q=this;
r=function(){q.removeListener("unload",r);p();};}else{k[$uid(this)]=this;}if(this.addEventListener){this.addEventListener(s,r,!!arguments[2]);}else{this.attachEvent("on"+s,r);
}return this;},removeListener:function(q,p){if(this.removeEventListener){this.removeEventListener(q,p,!!arguments[2]);}else{this.detachEvent("on"+q,p);
}return this;},retrieve:function(q,p){var s=e($uid(this)),r=s[q];if(p!=null&&r==null){r=s[q]=p;}return r!=null?r:null;},store:function(q,p){var r=e($uid(this));
r[q]=p;return this;},eliminate:function(p){var q=e($uid(this));delete q[p];return this;}});if(window.attachEvent&&!window.addEventListener){window.addListener("unload",function(){Object.each(k,j);
if(window.CollectGarbage){CollectGarbage();}});}})();Element.Properties={};Element.Properties=new Hash;Element.Properties.style={set:function(a){this.style.cssText=a;
},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();
}};(function(a){if(a!=null){Element.Properties.maxlength=Element.Properties.maxLength={get:function(){var b=this.getAttribute("maxLength");return b==a?null:b;
}};}})(document.createElement("input").getAttribute("maxLength"));Element.Properties.html=(function(){var c=Function.attempt(function(){var e=document.createElement("table");
e.innerHTML="<tr><td></td></tr>";});var d=document.createElement("div");var a={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};
a.thead=a.tfoot=a.tbody;var b={set:function(){var f=Array.flatten(arguments).join("");var g=(!c&&a[this.get("tag")]);if(g){var h=d;h.innerHTML=g[1]+f+g[2];
for(var e=g[0];e--;){h=h.firstChild;}this.empty().adopt(h.childNodes);}else{this.innerHTML=f;}}};b.erase=b.set;return b;})();(function(){var c=document.html;
Element.Properties.styles={set:function(f){this.setStyles(f);}};var e=(c.style.opacity!=null);var d=/alpha\(opacity=([\d.]+)\)/i;var b=function(g,f){if(!g.currentStyle||!g.currentStyle.hasLayout){g.style.zoom=1;
}if(e){g.style.opacity=f;}else{f=(f==1)?"":"alpha(opacity="+f*100+")";var h=g.style.filter||g.getComputedStyle("filter")||"";g.style.filter=d.test(h)?h.replace(d,f):h+f;
}};Element.Properties.opacity={set:function(g){var f=this.style.visibility;if(g==0&&f!="hidden"){this.style.visibility="hidden";}else{if(g!=0&&f!="visible"){this.style.visibility="visible";
}}b(this,g);},get:(e)?function(){var f=this.style.opacity||this.getComputedStyle("opacity");return(f=="")?1:f;}:function(){var f,g=(this.style.filter||this.getComputedStyle("filter"));
if(g){f=g.match(d);}return(f==null||g==null)?1:(f[1]/100);}};var a=(c.style.cssFloat==null)?"styleFloat":"cssFloat";Element.implement({getComputedStyle:function(h){if(this.currentStyle){return this.currentStyle[h.camelCase()];
}var g=Element.getDocument(this).defaultView,f=g?g.getComputedStyle(this,null):null;return(f)?f.getPropertyValue((h==a)?"float":h.hyphenate()):null;},setOpacity:function(f){b(this,f);
return this;},getOpacity:function(){return this.get("opacity");},setStyle:function(g,f){switch(g){case"opacity":return this.set("opacity",parseFloat(f));
case"float":g=a;}g=g.camelCase();if(typeOf(f)!="string"){var h=(Element.Styles[g]||"@").split(" ");f=Array.from(f).map(function(k,j){if(!h[j]){return"";
}return(typeOf(k)=="number")?h[j].replace("@",Math.round(k)):k;}).join(" ");}else{if(f==String(Number(f))){f=Math.round(f);}}this.style[g]=f;return this;
},getStyle:function(l){switch(l){case"opacity":return this.get("opacity");case"float":l=a;}l=l.camelCase();var f=this.style[l];if(!f||l=="zIndex"){f=[];
for(var k in Element.ShortStyles){if(l!=k){continue;}for(var j in Element.ShortStyles[k]){f.push(this.getStyle(j));}return f.join(" ");}f=this.getComputedStyle(l);
}if(f){f=String(f);var h=f.match(/rgba?\([\d\s,]+\)/);if(h){f=f.replace(h[0],h[0].rgbToHex());}}if(Browser.opera||(Browser.ie&&isNaN(parseFloat(f)))){if((/^(height|width)$/).test(l)){var g=(l=="width")?["left","right"]:["top","bottom"],i=0;
g.each(function(m){i+=this.getStyle("border-"+m+"-width").toInt()+this.getStyle("padding-"+m).toInt();},this);return this["offset"+l.capitalize()]-i+"px";
}if(Browser.opera&&String(f).indexOf("px")!=-1){return f;}if((/^border(.+)Width|margin|padding/).test(l)){return"0px";}}return f;},setStyles:function(g){for(var f in g){this.setStyle(f,g[f]);
}return this;},getStyles:function(){var f={};Array.flatten(arguments).each(function(g){f[g]=this.getStyle(g);},this);return f;}});Element.Styles={left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"};
Element.Styles=new Hash(Element.Styles);Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(l){var k=Element.ShortStyles;
var g=Element.Styles;["margin","padding"].each(function(m){var n=m+l;k[m][n]=g[n]="@px";});var j="border"+l;k.border[j]=g[j]="@px @ rgb(@, @, @)";var i=j+"Width",f=j+"Style",h=j+"Color";
k[j]={};k.borderWidth[i]=k[j][i]=g[i]="@px";k.borderStyle[f]=k[j][f]=g[f]="@";k.borderColor[h]=k[j][h]=g[h]="rgb(@, @, @)";});}).call(this);(function(){Element.Properties.events={set:function(b){this.addEvents(b);
}};[Element,Window,Document].invoke("implement",{addEvent:function(f,h){var i=this.retrieve("events",{});if(!i[f]){i[f]={keys:[],values:[]};}if(i[f].keys.contains(h)){return this;
}i[f].keys.push(h);var g=f,b=Element.Events[f],d=h,j=this;if(b){if(b.onAdd){b.onAdd.call(this,h);}if(b.condition){d=function(k){if(b.condition.call(this,k)){return h.call(this,k);
}return true;};}g=b.base||g;}var e=function(){return h.call(j);};var c=Element.NativeEvents[g];if(c){if(c==2){e=function(k){k=new Event(k,j.getWindow());
if(d.call(j,k)===false){k.stop();}};}this.addListener(g,e,arguments[2]);}i[f].values.push(e);return this;},removeEvent:function(e,d){var c=this.retrieve("events");
if(!c||!c[e]){return this;}var h=c[e];var b=h.keys.indexOf(d);if(b==-1){return this;}var g=h.values[b];delete h.keys[b];delete h.values[b];var f=Element.Events[e];
if(f){if(f.onRemove){f.onRemove.call(this,d);}e=f.base||e;}return(Element.NativeEvents[e])?this.removeListener(e,g,arguments[2]):this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
}return this;},removeEvents:function(b){var d;if(typeOf(b)=="object"){for(d in b){this.removeEvent(d,b[d]);}return this;}var c=this.retrieve("events");
if(!c){return this;}if(!b){for(d in c){this.removeEvents(d);}this.eliminate("events");}else{if(c[b]){c[b].keys.each(function(e){this.removeEvent(b,e);},this);
delete c[b];}}return this;},fireEvent:function(e,c,b){var d=this.retrieve("events");if(!d||!d[e]){return this;}c=Array.from(c);d[e].keys.each(function(f){if(b){f.delay(b,this,c);
}else{f.apply(this,c);}},this);return this;},cloneEvents:function(e,d){e=document.id(e);var c=e.retrieve("events");if(!c){return this;}if(!d){for(var b in c){this.cloneEvents(e,b);
}}else{if(c[d]){c[d].keys.each(function(f){this.addEvent(d,f);},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,orientationchange:2,touchstart:2,touchmove:2,touchend:2,touchcancel:2,gesturestart:2,gesturechange:2,gestureend:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:2,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
var a=function(b){var c=b.relatedTarget;if(c==null){return true;}if(!c){return false;}return(c!=this&&c.prefix!="xul"&&typeOf(this)!="document"&&!this.contains(c));
};Element.Events={mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.firefox)?"DOMMouseScroll":"mousewheel"}};
Element.Events=new Hash(Element.Events);}).call(this);(function(){var h=document.createElement("div"),e=document.createElement("div");h.style.height="0";
h.appendChild(e);var d=(e.offsetParent===h);h=e=null;var l=function(m){return k(m,"position")!="static"||a(m);};var i=function(m){return l(m)||(/^(?:table|td|th)$/i).test(m.tagName);
};Element.implement({scrollTo:function(m,n){if(a(this)){this.getWindow().scrollTo(m,n);}else{this.scrollLeft=m;this.scrollTop=n;}return this;},getSize:function(){if(a(this)){return this.getWindow().getSize();
}return{x:this.offsetWidth,y:this.offsetHeight};},getScrollSize:function(){if(a(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};
},getScroll:function(){if(a(this)){return this.getWindow().getScroll();}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var n=this.parentNode,m={x:0,y:0};
while(n&&!a(n)){m.x+=n.scrollLeft;m.y+=n.scrollTop;n=n.parentNode;}return m;},getOffsetParent:d?function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
}var n=(k(m,"position")=="static")?i:l;while((m=m.parentNode)){if(n(m)){return m;}}return null;}:function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
}try{return m.offsetParent;}catch(n){}return null;},getOffsets:function(){if(this.getBoundingClientRect&&!Browser.Platform.ios){var r=this.getBoundingClientRect(),o=document.id(this.getDocument().documentElement),q=o.getScroll(),t=this.getScrolls(),s=(k(this,"position")=="fixed");
return{x:r.left.toInt()+t.x+((s)?0:q.x)-o.clientLeft,y:r.top.toInt()+t.y+((s)?0:q.y)-o.clientTop};}var n=this,m={x:0,y:0};if(a(this)){return m;}while(n&&!a(n)){m.x+=n.offsetLeft;
m.y+=n.offsetTop;if(Browser.firefox){if(!c(n)){m.x+=b(n);m.y+=g(n);}var p=n.parentNode;if(p&&k(p,"overflow")!="visible"){m.x+=b(p);m.y+=g(p);}}else{if(n!=this&&Browser.safari){m.x+=b(n);
m.y+=g(n);}}n=n.offsetParent;}if(Browser.firefox&&!c(this)){m.x-=b(this);m.y-=g(this);}return m;},getPosition:function(p){if(a(this)){return{x:0,y:0};}var q=this.getOffsets(),n=this.getScrolls();
var m={x:q.x-n.x,y:q.y-n.y};if(p&&(p=document.id(p))){var o=p.getPosition();return{x:m.x-o.x-b(p),y:m.y-o.y-g(p)};}return m;},getCoordinates:function(o){if(a(this)){return this.getWindow().getCoordinates();
}var m=this.getPosition(o),n=this.getSize();var p={left:m.x,top:m.y,width:n.x,height:n.y};p.right=p.left+p.width;p.bottom=p.top+p.height;return p;},computePosition:function(m){return{left:m.x-j(this,"margin-left"),top:m.y-j(this,"margin-top")};
},setPosition:function(m){return this.setStyles(this.computePosition(m));}});[Document,Window].invoke("implement",{getSize:function(){var m=f(this);return{x:m.clientWidth,y:m.clientHeight};
},getScroll:function(){var n=this.getWindow(),m=f(this);return{x:n.pageXOffset||m.scrollLeft,y:n.pageYOffset||m.scrollTop};},getScrollSize:function(){var o=f(this),n=this.getSize(),m=this.getDocument().body;
return{x:Math.max(o.scrollWidth,m.scrollWidth,n.x),y:Math.max(o.scrollHeight,m.scrollHeight,n.y)};},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var m=this.getSize();
return{top:0,left:0,bottom:m.y,right:m.x,height:m.y,width:m.x};}});var k=Element.getComputedStyle;function j(m,n){return k(m,n).toInt()||0;}function c(m){return k(m,"-moz-box-sizing")=="border-box";
}function g(m){return j(m,"border-top-width");}function b(m){return j(m,"border-left-width");}function a(m){return(/^(?:body|html)$/i).test(m.tagName);
}function f(m){var n=m.getDocument();return(!n.compatMode||n.compatMode=="CSS1Compat")?n.html:n.body;}}).call(this);Element.alias({position:"setPosition"});
[Window,Document,Element].invoke("implement",{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});(function(){var f=this.Fx=new Class({Implements:[Chain,Events,Options],options:{fps:60,unit:false,duration:500,frames:null,frameSkip:true,link:"ignore"},initialize:function(g){this.subject=this.subject||this;
this.setOptions(g);},getTransition:function(){return function(g){return -(Math.cos(Math.PI*g)-1)/2;};},step:function(g){if(this.options.frameSkip){var h=(this.time!=null)?(g-this.time):0,i=h/this.frameInterval;
this.time=g;this.frame+=i;}else{this.frame++;}if(this.frame<this.frames){var j=this.transition(this.frame/this.frames);this.set(this.compute(this.from,this.to,j));
}else{this.frame=this.frames;this.set(this.compute(this.from,this.to,1));this.stop();}},set:function(g){return g;},compute:function(i,h,g){return f.compute(i,h,g);
},check:function(){if(!this.isRunning()){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));
return false;}return false;},start:function(k,j){if(!this.check(k,j)){return this;}this.from=k;this.to=j;this.frame=(this.options.frameSkip)?0:-1;this.time=null;
this.transition=this.getTransition();var i=this.options.frames,h=this.options.fps,g=this.options.duration;this.duration=f.Durations[g]||g.toInt();this.frameInterval=1000/h;
this.frames=i||Math.round(this.duration/this.frameInterval);this.fireEvent("start",this.subject);b.call(this,h);return this;},stop:function(){if(this.isRunning()){this.time=null;
d.call(this,this.options.fps);if(this.frames==this.frame){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
}}else{this.fireEvent("stop",this.subject);}}return this;},cancel:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);this.frame=this.frames;
this.fireEvent("cancel",this.subject).clearChain();}return this;},pause:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);}return this;
},resume:function(){if((this.frame<this.frames)&&!this.isRunning()){b.call(this,this.options.fps);}return this;},isRunning:function(){var g=e[this.options.fps];
return g&&g.contains(this);}});f.compute=function(i,h,g){return(h-i)*g+i;};f.Durations={"short":250,normal:500,"long":1000};var e={},c={};var a=function(){var h=Date.now();
for(var j=this.length;j--;){var g=this[j];if(g){g.step(h);}}};var b=function(h){var g=e[h]||(e[h]=[]);g.push(this);if(!c[h]){c[h]=a.periodical(Math.round(1000/h),g);
}};var d=function(h){var g=e[h];if(g){g.erase(this);if(!g.length&&c[h]){delete e[h];c[h]=clearInterval(c[h]);}}};}).call(this);Fx.CSS=new Class({Extends:Fx,prepare:function(c,d,b){b=Array.from(b);
if(b[1]==null){b[1]=b[0];b[0]=c.getStyle(d);}var a=b.map(this.parse);return{from:a[0],to:a[1]};},parse:function(a){a=Function.from(a)();a=(typeof a=="string")?a.split(" "):Array.from(a);
return a.map(function(c){c=String(c);var b=false;Object.each(Fx.CSS.Parsers,function(f,e){if(b){return;}var d=f.parse(c);if(d||d===0){b={value:d,parser:f};
}});b=b||{value:c,parser:Fx.CSS.Parsers.String};return b;});},compute:function(d,c,b){var a=[];(Math.min(d.length,c.length)).times(function(e){a.push({value:d[e].parser.compute(d[e].value,c[e].value,b),parser:d[e].parser});
});a.$family=Function.from("fx:css:value");return a;},serve:function(c,b){if(typeOf(c)!="fx:css:value"){c=this.parse(c);}var a=[];c.each(function(d){a=a.concat(d.parser.serve(d.value,b));
});return a;},render:function(a,d,c,b){a.setStyle(d,this.serve(c,b));},search:function(a){if(Fx.CSS.Cache[a]){return Fx.CSS.Cache[a];}var c={},b=new RegExp("^"+a.escapeRegExp()+"$");
Array.each(document.styleSheets,function(f,e){var d=f.href;if(d&&d.contains("://")&&!d.contains(document.domain)){return;}var g=f.rules||f.cssRules;Array.each(g,function(k,h){if(!k.style){return;
}var j=(k.selectorText)?k.selectorText.replace(/^\w+/,function(i){return i.toLowerCase();}):null;if(!j||!b.test(j)){return;}Object.each(Element.Styles,function(l,i){if(!k.style[i]||Element.ShortStyles[i]){return;
}l=String(k.style[i]);c[i]=((/^rgb/).test(l))?l.rgbToHex():l;});});});return Fx.CSS.Cache[a]=c;}});Fx.CSS.Cache={};Fx.CSS.Parsers={Color:{parse:function(a){if(a.match(/^#[0-9a-f]{3,6}$/i)){return a.hexToRgb(true);
}return((a=a.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[a[1],a[2],a[3]]:false;},compute:function(c,b,a){return c.map(function(e,d){return Math.round(Fx.compute(c[d],b[d],a));
});},serve:function(a){return a.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(b,a){return(a)?b+a:b;}},String:{parse:Function.from(false),compute:function(b,a){return a;
},serve:function(a){return a;}}};Fx.CSS.Parsers=new Hash(Fx.CSS.Parsers);Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);
this.parent(a);},set:function(b,a){if(arguments.length==1){a=b;b=this.property||this.options.property;}this.render(this.element,b,a,this.options.unit);
return this;},start:function(c,e,d){if(!this.check(c,e,d)){return this;}var b=Array.flatten(arguments);this.property=this.options.property||b.shift();var a=this.prepare(this.element,this.property,b);
return this.parent(a.from,a.to);}});Element.Properties.tween={set:function(a){this.get("tween").cancel().setOptions(a);return this;},get:function(){var a=this.retrieve("tween");
if(!a){a=new Fx.Tween(this,{link:"cancel"});this.store("tween",a);}return a;}};Element.implement({tween:function(a,c,b){this.get("tween").start(arguments);
return this;},fade:function(c){var e=this.get("tween"),d="opacity",a;c=[c,"toggle"].pick();switch(c){case"in":e.start(d,1);break;case"out":e.start(d,0);
break;case"show":e.set(d,1);break;case"hide":e.set(d,0);break;case"toggle":var b=this.retrieve("fade:flag",this.get("opacity")==1);e.start(d,(b)?0:1);this.store("fade:flag",!b);
a=true;break;default:e.start(d,arguments);}if(!a){this.eliminate("fade:flag");}return this;},highlight:function(c,a){if(!a){a=this.retrieve("highlight:original",this.getStyle("background-color"));
a=(a=="transparent")?"#fff":a;}var b=this.get("tween");b.start("background-color",c||"#ffff88",a).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
b.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);
},set:function(a){if(typeof a=="string"){a=this.search(a);}for(var b in a){this.render(this.element,b,a[b],this.options.unit);}return this;},compute:function(e,d,c){var a={};
for(var b in e){a[b]=this.parent(e[b],d[b],c);}return a;},start:function(b){if(!this.check(b)){return this;}if(typeof b=="string"){b=this.search(b);}var e={},d={};
for(var c in b){var a=this.prepare(this.element,c,b[c]);e[c]=a.from;d[c]=a.to;}return this.parent(e,d);}});Element.Properties.morph={set:function(a){this.get("morph").cancel().setOptions(a);
return this;},get:function(){var a=this.retrieve("morph");if(!a){a=new Fx.Morph(this,{link:"cancel"});this.store("morph",a);}return a;}};Element.implement({morph:function(a){this.get("morph").start(a);
return this;}});Fx.implement({getTransition:function(){var a=this.options.transition||Fx.Transitions.Sine.easeInOut;if(typeof a=="string"){var b=a.split(":");
a=Fx.Transitions;a=a[b[0]]||a[b[0].capitalize()];if(b[1]){a=a["ease"+b[1].capitalize()+(b[2]?b[2].capitalize():"")];}}return a;}});Fx.Transition=function(c,b){b=Array.from(b);
var a=function(d){return c(d,b);};return Object.append(a,{easeIn:a,easeOut:function(d){return 1-c(1-d,b);},easeInOut:function(d){return(d<=0.5?c(2*d,b):(2-c(2*(1-d),b)))/2;
}});};Fx.Transitions={linear:function(a){return a;}};Fx.Transitions=new Hash(Fx.Transitions);Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);
}};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a&&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.cos(a*Math.PI/2);},Back:function(b,a){a=a&&a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a);},Bounce:function(f){var e;for(var d=0,c=1;
1;d+=c,c/=2){if(f>=(7-4*d)/11){e=c*c-Math.pow((11-6*d-11*f)/4,2);break;}}return e;},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a&&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);});});(function(){var d=function(){},a=("onprogress" in new Browser.Request);
var c=this.Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false,timeout:0,noCache:false},initialize:function(e){this.xhr=new Browser.Request();
this.setOptions(e);this.headers=this.options.headers;},onStateChange:function(){var e=this.xhr;if(e.readyState!=4||!this.running){return;}this.running=false;
this.status=0;Function.attempt(function(){var f=e.status;this.status=(f==1223)?204:f;}.bind(this));e.onreadystatechange=d;if(a){e.onprogress=e.onloadstart=d;
}clearTimeout(this.timer);this.response={text:this.xhr.responseText||"",xml:this.xhr.responseXML};if(this.options.isSuccess.call(this,this.status)){this.success(this.response.text,this.response.xml);
}else{this.failure();}},isSuccess:function(){var e=this.status;return(e>=200&&e<300);},isRunning:function(){return !!this.running;},processScripts:function(e){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return Browser.exec(e);
}return e.stripScripts(this.options.evalScripts);},success:function(f,e){this.onSuccess(this.processScripts(f),e);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},loadstart:function(e){this.fireEvent("loadstart",[e,this.xhr]);
},progress:function(e){this.fireEvent("progress",[e,this.xhr]);},timeout:function(){this.fireEvent("timeout",this.xhr);},setHeader:function(e,f){this.headers[e]=f;
return this;},getHeader:function(e){return Function.attempt(function(){return this.xhr.getResponseHeader(e);}.bind(this));},check:function(){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));return false;}return false;},send:function(o){if(!this.check(o)){return this;
}this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.running=true;var l=typeOf(o);if(l=="string"||l=="element"){o={data:o};}var h=this.options;
o=Object.append({data:h.data,url:h.url,method:h.method},o);var j=o.data,f=String(o.url),e=o.method.toLowerCase();switch(typeOf(j)){case"element":j=document.id(j).toQueryString();
break;case"object":case"hash":j=Object.toQueryString(j);}if(this.options.format){var m="format="+this.options.format;j=(j)?m+"&"+j:m;}if(this.options.emulation&&!["get","post"].contains(e)){var k="_method="+e;
j=(j)?k+"&"+j:k;e="post";}if(this.options.urlEncoded&&["post","put"].contains(e)){var g=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers["Content-type"]="application/x-www-form-urlencoded"+g;
}if(!f){f=document.location.pathname;}var i=f.lastIndexOf("/");if(i>-1&&(i=f.indexOf("#"))>-1){f=f.substr(0,i);}if(this.options.noCache){f+=(f.contains("?")?"&":"?")+String.uniqueID();
}if(j&&e=="get"){f+=(f.contains("?")?"&":"?")+j;j=null;}var n=this.xhr;if(a){n.onloadstart=this.loadstart.bind(this);n.onprogress=this.progress.bind(this);
}n.open(e.toUpperCase(),f,this.options.async,this.options.user,this.options.password);if(this.options.user&&"withCredentials" in n){n.withCredentials=true;
}n.onreadystatechange=this.onStateChange.bind(this);Object.each(this.headers,function(q,p){try{n.setRequestHeader(p,q);}catch(r){this.fireEvent("exception",[p,q]);
}},this);this.fireEvent("request");n.send(j);if(!this.options.async){this.onStateChange();}if(this.options.timeout){this.timer=this.timeout.delay(this.options.timeout,this);
}return this;},cancel:function(){if(!this.running){return this;}this.running=false;var e=this.xhr;e.abort();clearTimeout(this.timer);e.onreadystatechange=d;
if(a){e.onprogress=e.onloadstart=d;}this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});var b={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(e){b[e]=function(g){var f={method:e};
if(g!=null){f.data=g;}return this.send(f);};});c.implement(b);Element.Properties.send={set:function(e){var f=this.get("send").cancel();f.setOptions(e);
return this;},get:function(){var e=this.retrieve("send");if(!e){e=new c({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")});
this.store("send",e);}return e;}};Element.implement({send:function(e){var f=this.get("send");f.send({data:this,url:e||f.options.url});return this;}});})();
Request.HTML=new Class({Extends:Request,options:{update:false,append:false,evalScripts:true,filter:false,headers:{Accept:"text/html, application/xml, text/xml, */*"}},success:function(e){var d=this.options,b=this.response;
b.html=e.stripScripts(function(f){b.javascript=f;});var c=b.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);if(c){b.html=c[1];}var a=new Element("div").set("html",b.html);
b.tree=a.childNodes;b.elements=a.getElements("*");if(d.filter){b.tree=b.elements.filter(d.filter);}if(d.update){document.id(d.update).empty().set("html",b.html);
}else{if(d.append){document.id(d.append).adopt(a.getChildren());}}if(d.evalScripts){Browser.exec(b.javascript);}this.onSuccess(b.tree,b.elements,b.html,b.javascript);
}});Element.Properties.load={set:function(a){var b=this.get("load").cancel();b.setOptions(a);return this;},get:function(){var a=this.retrieve("load");if(!a){a=new Request.HTML({data:this,link:"cancel",update:this,method:"get"});
this.store("load",a);}return a;}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Type.isObject,url:Type.isString}));
return this;}});if(typeof JSON=="undefined"){this.JSON={};}JSON=new Hash({stringify:JSON.stringify,parse:JSON.parse});(function(){var special={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
var escape=function(chr){return special[chr]||"\\u"+("0000"+chr.charCodeAt(0).toString(16)).slice(-4);};JSON.validate=function(string){string=string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"");
return(/^[\],:{}\s]*$/).test(string);};JSON.encode=JSON.stringify?function(obj){return JSON.stringify(obj);}:function(obj){if(obj&&obj.toJSON){obj=obj.toJSON();
}switch(typeOf(obj)){case"string":return'"'+obj.replace(/[\x00-\x1f\\"]/g,escape)+'"';case"array":return"["+obj.map(JSON.encode).clean()+"]";case"object":case"hash":var string=[];
Object.each(obj,function(value,key){var json=JSON.encode(value);if(json){string.push(JSON.encode(key)+":"+json);}});return"{"+string+"}";case"number":case"boolean":return""+obj;
case"null":return"null";}return null;};JSON.decode=function(string,secure){if(!string||typeOf(string)!="string"){return null;}if(secure||JSON.secure){if(JSON.parse){return JSON.parse(string);
}if(!JSON.validate(string)){throw new Error("JSON could not decode the input; security is enabled and the value is not secure.");}}return eval("("+string+")");
};}).call(this);Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(a){this.parent(a);Object.append(this.headers,{Accept:"application/json","X-Request":"JSON"});
},success:function(c){var b;try{b=this.response.json=JSON.decode(c,this.options.secure);}catch(a){this.fireEvent("error",[c,a]);return;}if(b==null){this.onFailure();
}else{this.onSuccess(b,c);}}});var Cookie=new Class({Implements:Options,options:{path:"/",domain:false,duration:false,secure:false,document:document,encode:true},initialize:function(b,a){this.key=b;
this.setOptions(a);},write:function(b){if(this.options.encode){b=encodeURIComponent(b);}if(this.options.domain){b+="; domain="+this.options.domain;}if(this.options.path){b+="; path="+this.options.path;
}if(this.options.duration){var a=new Date();a.setTime(a.getTime()+this.options.duration*24*60*60*1000);b+="; expires="+a.toGMTString();}if(this.options.secure){b+="; secure";
}this.options.document.cookie=this.key+"="+b;return this;},read:function(){var a=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(a)?decodeURIComponent(a[1]):null;},dispose:function(){new Cookie(this.key,Object.merge({},this.options,{duration:-1})).write("");return this;}});
Cookie.write=function(b,c,a){return new Cookie(b,a).write(c);};Cookie.read=function(a){return new Cookie(a).read();};Cookie.dispose=function(b,a){return new Cookie(b,a).dispose();
};(function(j,l){var m,g,f=[],c,b,n=true;try{n=j.frameElement!=null;}catch(i){}var h=function(){clearTimeout(b);if(m){return;}Browser.loaded=m=true;l.removeListener("DOMContentLoaded",h).removeListener("readystatechange",a);
l.fireEvent("domready");j.fireEvent("domready");};var a=function(){for(var e=f.length;e--;){if(f[e]()){h();return true;}}return false;};var k=function(){clearTimeout(b);
if(!a()){b=setTimeout(k,10);}};l.addListener("DOMContentLoaded",h);var d=l.createElement("div");if(d.doScroll&&!n){f.push(function(){try{d.doScroll();return true;
}catch(o){}return false;});c=true;}if(l.readyState){f.push(function(){var e=l.readyState;return(e=="loaded"||e=="complete");});}if("onreadystatechange" in l){l.addListener("readystatechange",a);
}else{c=true;}if(c){k();}Element.Events.domready={onAdd:function(e){if(m){e.call(this);}}};Element.Events.load={base:"load",onAdd:function(e){if(g&&this==j){e.call(this);
}},condition:function(){if(this==j){h();delete Element.Events.load;}return true;}};j.addEvent("load",function(){g=true;});})(window,document);(function(){var Swiff=this.Swiff=new Class({Implements:Options,options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"window",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(path,options){this.instance="Swiff_"+String.uniqueID();this.setOptions(options);options=this.options;var id=this.id=options.id||this.instance;
var container=document.id(options.container);Swiff.CallBacks[this.instance]={};var params=options.params,vars=options.vars,callBacks=options.callBacks;
var properties=Object.append({height:options.height,width:options.width},options.properties);var self=this;for(var callBack in callBacks){Swiff.CallBacks[this.instance][callBack]=(function(option){return function(){return option.apply(self.object,arguments);
};})(callBacks[callBack]);vars[callBack]="Swiff.CallBacks."+this.instance+"."+callBack;}params.flashVars=Object.toQueryString(vars);if(Browser.ie){properties.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
params.movie=path;}else{properties.type="application/x-shockwave-flash";}properties.data=path;var build='<object id="'+id+'"';for(var property in properties){build+=" "+property+'="'+properties[property]+'"';
}build+=">";for(var param in params){if(params[param]){build+='<param name="'+param+'" value="'+params[param]+'" />';}}build+="</object>";this.object=((container)?container.empty():new Element("div")).set("html",build).firstChild;
},replaces:function(element){element=document.id(element,true);element.parentNode.replaceChild(this.toElement(),element);return this;},inject:function(element){document.id(element,true).appendChild(this.toElement());
return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].append(arguments));}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};}).call(this);

//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More={version:"1.2.4.4",build:"6f6057dc645fdb7547689183b2311063bd653ddf"};(function(){var a={language:"en-US",languages:{"en-US":{}},cascades:["en-US"]};
var b;MooTools.lang=new Events();$extend(MooTools.lang,{setLanguage:function(c){if(!a.languages[c]){return this;}a.language=c;this.load();this.fireEvent("langChange",c);
return this;},load:function(){var c=this.cascade(this.getCurrentLanguage());b={};$each(c,function(e,d){b[d]=this.lambda(e);},this);},getCurrentLanguage:function(){return a.language;
},addLanguage:function(c){a.languages[c]=a.languages[c]||{};return this;},cascade:function(e){var c=(a.languages[e]||{}).cascades||[];c.combine(a.cascades);
c.erase(e).push(e);var d=c.map(function(f){return a.languages[f];},this);return $merge.apply(this,d);},lambda:function(c){(c||{}).get=function(e,d){return $lambda(c[e]).apply(this,$splat(d));
};return c;},get:function(e,d,c){if(b&&b[e]){return(d?b[e].get(d,c):b[e]);}},set:function(d,e,c){this.addLanguage(d);langData=a.languages[d];if(!langData[e]){langData[e]={};
}$extend(langData[e],c);if(d==this.getCurrentLanguage()){this.load();this.fireEvent("langChange",d);}return this;},list:function(){return Hash.getKeys(a.languages);
}});})();Class.Mutators.Binds=function(a){return a;};Class.Mutators.initialize=function(a){return function(){$splat(this.Binds).each(function(b){var c=this[b];
if(c){this[b]=c.bind(this);}},this);return a.apply(this,arguments);};};Array.implement({min:function(){return Math.min.apply(null,this);},max:function(){return Math.max.apply(null,this);
},average:function(){return this.length?this.sum()/this.length:0;},sum:function(){var a=0,b=this.length;if(b){do{a+=this[--b];}while(b);}return a;},unique:function(){return[].combine(this);
},shuffle:function(){for(var b=this.length;b&&--b;){var a=this[b],c=Math.floor(Math.random()*(b+1));this[b]=this[c];this[c]=a;}return this;}});(function(){var i=this.Date;
if(!i.now){i.now=$time;}i.Methods={ms:"Milliseconds",year:"FullYear",min:"Minutes",mo:"Month",sec:"Seconds",hr:"Hours"};["Date","Day","FullYear","Hours","Milliseconds","Minutes","Month","Seconds","Time","TimezoneOffset","Week","Timezone","GMTOffset","DayOfYear","LastMonth","LastDayOfMonth","UTCDate","UTCDay","UTCFullYear","AMPM","Ordinal","UTCHours","UTCMilliseconds","UTCMinutes","UTCMonth","UTCSeconds"].each(function(p){i.Methods[p.toLowerCase()]=p;
});var d=function(q,p){return new Array(p-String(q).length+1).join("0")+q;};i.implement({set:function(t,r){switch($type(t)){case"object":for(var s in t){this.set(s,t[s]);
}break;case"string":t=t.toLowerCase();var q=i.Methods;if(q[t]){this["set"+q[t]](r);}}return this;},get:function(q){q=q.toLowerCase();var p=i.Methods;if(p[q]){return this["get"+p[q]]();
}return null;},clone:function(){return new i(this.get("time"));},increment:function(p,r){p=p||"day";r=$pick(r,1);switch(p){case"year":return this.increment("month",r*12);
case"month":var q=this.get("date");this.set("date",1).set("mo",this.get("mo")+r);return this.set("date",q.min(this.get("lastdayofmonth")));case"week":return this.increment("day",r*7);
case"day":return this.set("date",this.get("date")+r);}if(!i.units[p]){throw new Error(p+" is not a supported interval");}return this.set("time",this.get("time")+r*i.units[p]());
},decrement:function(p,q){return this.increment(p,-1*$pick(q,1));},isLeapYear:function(){return i.isLeapYear(this.get("year"));},clearTime:function(){return this.set({hr:0,min:0,sec:0,ms:0});
},diff:function(q,p){if($type(q)=="string"){q=i.parse(q);}return((q-this)/i.units[p||"day"](3,3)).toInt();},getLastDayOfMonth:function(){return i.daysInMonth(this.get("mo"),this.get("year"));
},getDayOfYear:function(){return(i.UTC(this.get("year"),this.get("mo"),this.get("date")+1)-i.UTC(this.get("year"),0,1))/i.units.day();},getWeek:function(){return(this.get("dayofyear")/7).ceil();
},getOrdinal:function(p){return i.getMsg("ordinal",p||this.get("date"));},getTimezone:function(){return this.toString().replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3");
},getGMTOffset:function(){var p=this.get("timezoneOffset");return((p>0)?"-":"+")+d((p.abs()/60).floor(),2)+d(p%60,2);},setAMPM:function(p){p=p.toUpperCase();
var q=this.get("hr");if(q>11&&p=="AM"){return this.decrement("hour",12);}else{if(q<12&&p=="PM"){return this.increment("hour",12);}}return this;},getAMPM:function(){return(this.get("hr")<12)?"AM":"PM";
},parse:function(p){this.set("time",i.parse(p));return this;},isValid:function(p){return !!(p||this).valueOf();},format:function(p){if(!this.isValid()){return"invalid date";
}p=p||"%x %X";p=k[p.toLowerCase()]||p;var q=this;return p.replace(/%([a-z%])/gi,function(s,r){switch(r){case"a":return i.getMsg("days")[q.get("day")].substr(0,3);
case"A":return i.getMsg("days")[q.get("day")];case"b":return i.getMsg("months")[q.get("month")].substr(0,3);case"B":return i.getMsg("months")[q.get("month")];
case"c":return q.toString();case"d":return d(q.get("date"),2);case"H":return d(q.get("hr"),2);case"I":return((q.get("hr")%12)||12);case"j":return d(q.get("dayofyear"),3);
case"m":return d((q.get("mo")+1),2);case"M":return d(q.get("min"),2);case"o":return q.get("ordinal");case"p":return i.getMsg(q.get("ampm"));case"S":return d(q.get("seconds"),2);
case"U":return d(q.get("week"),2);case"w":return q.get("day");case"x":return q.format(i.getMsg("shortDate"));case"X":return q.format(i.getMsg("shortTime"));
case"y":return q.get("year").toString().substr(2);case"Y":return q.get("year");case"T":return q.get("GMTOffset");case"Z":return q.get("Timezone");}return r;
});},toISOString:function(){return this.format("iso8601");}});i.alias("toISOString","toJSON");i.alias("diff","compare");i.alias("format","strftime");var k={db:"%Y-%m-%d %H:%M:%S",compact:"%Y%m%dT%H%M%S",iso8601:"%Y-%m-%dT%H:%M:%S%T",rfc822:"%a, %d %b %Y %H:%M:%S %Z","short":"%d %b %H:%M","long":"%B %d, %Y %H:%M"};
var g=[];var e=i.parse;var n=function(s,u,r){var q=-1;var t=i.getMsg(s+"s");switch($type(u)){case"object":q=t[u.get(s)];break;case"number":q=t[month-1];
if(!q){throw new Error("Invalid "+s+" index: "+index);}break;case"string":var p=t.filter(function(v){return this.test(v);},new RegExp("^"+u,"i"));if(!p.length){throw new Error("Invalid "+s+" string");
}if(p.length>1){throw new Error("Ambiguous "+s);}q=p[0];}return(r)?t.indexOf(q):q;};i.extend({getMsg:function(q,p){return MooTools.lang.get("Date",q,p);
},units:{ms:$lambda(1),second:$lambda(1000),minute:$lambda(60000),hour:$lambda(3600000),day:$lambda(86400000),week:$lambda(608400000),month:function(q,p){var r=new i;
return i.daysInMonth($pick(q,r.get("mo")),$pick(p,r.get("year")))*86400000;},year:function(p){p=p||new i().get("year");return i.isLeapYear(p)?31622400000:31536000000;
}},daysInMonth:function(q,p){return[31,i.isLeapYear(p)?29:28,31,30,31,30,31,31,30,31,30,31][q];},isLeapYear:function(p){return((p%4===0)&&(p%100!==0))||(p%400===0);
},parse:function(r){var q=$type(r);if(q=="number"){return new i(r);}if(q!="string"){return r;}r=r.clean();if(!r.length){return null;}var p;g.some(function(t){var s=t.re.exec(r);
return(s)?(p=t.handler(s)):false;});return p||new i(e(r));},parseDay:function(p,q){return n("day",p,q);},parseMonth:function(q,p){return n("month",q,p);
},parseUTC:function(q){var p=new i(q);var r=i.UTC(p.get("year"),p.get("mo"),p.get("date"),p.get("hr"),p.get("min"),p.get("sec"));return new i(r);},orderIndex:function(p){return i.getMsg("dateOrder").indexOf(p)+1;
},defineFormat:function(p,q){k[p]=q;},defineFormats:function(p){for(var q in p){i.defineFormat(q,p[q]);}},parsePatterns:g,defineParser:function(p){g.push((p.re&&p.handler)?p:l(p));
},defineParsers:function(){Array.flatten(arguments).each(i.defineParser);},define2DigitYearStart:function(p){h=p%100;m=p-h;}});var m=1900;var h=70;var j=function(p){return new RegExp("(?:"+i.getMsg(p).map(function(q){return q.substr(0,3);
}).join("|")+")[a-z]*");};var a=function(p){switch(p){case"x":return((i.orderIndex("month")==1)?"%m[.-/]%d":"%d[.-/]%m")+"([.-/]%y)?";case"X":return"%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%T?";
}return null;};var o={d:/[0-2]?[0-9]|3[01]/,H:/[01]?[0-9]|2[0-3]/,I:/0?[1-9]|1[0-2]/,M:/[0-5]?\d/,s:/\d+/,o:/[a-z]*/,p:/[ap]\.?m\.?/,y:/\d{2}|\d{4}/,Y:/\d{4}/,T:/Z|[+-]\d{2}(?::?\d{2})?/};
o.m=o.I;o.S=o.M;var c;var b=function(p){c=p;o.a=o.A=j("days");o.b=o.B=j("months");g.each(function(r,q){if(r.format){g[q]=l(r.format);}});};var l=function(r){if(!c){return{format:r};
}var p=[];var q=(r.source||r).replace(/%([a-z])/gi,function(t,s){return a(s)||t;}).replace(/\((?!\?)/g,"(?:").replace(/ (?!\?|\*)/g,",? ").replace(/%([a-z%])/gi,function(t,s){var u=o[s];
if(!u){return s;}p.push(s);return"("+u.source+")";}).replace(/\[a-z\]/gi,"[a-z\\u00c0-\\uffff]");return{format:r,re:new RegExp("^"+q+"$","i"),handler:function(u){u=u.slice(1).associate(p);
var s=new i().clearTime();if("d" in u){f.call(s,"d",1);}if("m" in u||"b" in u||"B" in u){f.call(s,"m",1);}for(var t in u){f.call(s,t,u[t]);}return s;}};
};var f=function(p,q){if(!q){return this;}switch(p){case"a":case"A":return this.set("day",i.parseDay(q,true));case"b":case"B":return this.set("mo",i.parseMonth(q,true));
case"d":return this.set("date",q);case"H":case"I":return this.set("hr",q);case"m":return this.set("mo",q-1);case"M":return this.set("min",q);case"p":return this.set("ampm",q.replace(/\./g,""));
case"S":return this.set("sec",q);case"s":return this.set("ms",("0."+q)*1000);case"w":return this.set("day",q);case"Y":return this.set("year",q);case"y":q=+q;
if(q<100){q+=m+(q<h?100:0);}return this.set("year",q);case"T":if(q=="Z"){q="+00";}var r=q.match(/([+-])(\d{2}):?(\d{2})?/);r=(r[1]+"1")*(r[2]*60+(+r[3]||0))+this.getTimezoneOffset();
return this.set("time",this-r*60000);}return this;};i.defineParsers("%Y([-./]%m([-./]%d((T| )%X)?)?)?","%Y%m%d(T%H(%M%S?)?)?","%x( %X)?","%d%o( %b( %Y)?)?( %X)?","%b( %d%o)?( %Y)?( %X)?","%Y %b( %d%o( %X)?)?","%o %b %d %X %T %Y");
MooTools.lang.addEvent("langChange",function(p){if(MooTools.lang.get("Date")){b(p);}}).fireEvent("langChange",MooTools.lang.getCurrentLanguage());})();
Date.implement({timeDiffInWords:function(a){return Date.distanceOfTimeInWords(this,a||new Date);},timeDiff:function(g,b){if(g==null){g=new Date;}var f=((g-this)/1000).toInt();
if(!f){return"0s";}var a={s:60,m:60,h:24,d:365,y:0};var e,d=[];for(var c in a){if(!f){break;}if((e=a[c])){d.unshift((f%e)+c);f=(f/e).toInt();}else{d.unshift(f+c);
}}return d.join(b||":");}});Date.alias("timeDiffInWords","timeAgoInWords");Date.extend({distanceOfTimeInWords:function(b,a){return Date.getTimePhrase(((a-b)/1000).toInt());
},getTimePhrase:function(f){var d=(f<0)?"Until":"Ago";if(f<0){f*=-1;}var b={minute:60,hour:60,day:24,week:7,month:52/12,year:12,eon:Infinity};var e="lessThanMinute";
for(var c in b){var a=b[c];if(f<1.5*a){if(f>0.75*a){e=c;}break;}f/=a;e=c+"s";}return Date.getMsg(e+d).substitute({delta:f.round()});}});Date.defineParsers({re:/^(?:tod|tom|yes)/i,handler:function(a){var b=new Date().clearTime();
switch(a[0]){case"tom":return b.increment();case"yes":return b.decrement();default:return b;}}},{re:/^(next|last) ([a-z]+)$/i,handler:function(e){var f=new Date().clearTime();
var b=f.getDay();var c=Date.parseDay(e[2],true);var a=c-b;if(c<=b){a+=7;}if(e[1]=="last"){a-=7;}return f.set("date",f.getDate()+a);}});Element.implement({tidy:function(){this.set("value",this.get("value").tidy());
},getTextInRange:function(b,a){return this.get("value").substring(b,a);},getSelectedText:function(){if(this.setSelectionRange){return this.getTextInRange(this.getSelectionStart(),this.getSelectionEnd());
}return document.selection.createRange().text;},getSelectedRange:function(){if($defined(this.selectionStart)){return{start:this.selectionStart,end:this.selectionEnd};
}var e={start:0,end:0};var a=this.getDocument().selection.createRange();if(!a||a.parentElement()!=this){return e;}var c=a.duplicate();if(this.type=="text"){e.start=0-c.moveStart("character",-100000);
e.end=e.start+a.text.length;}else{var b=this.get("value");var d=b.length;c.moveToElementText(this);c.setEndPoint("StartToEnd",a);if(c.text.length){d-=b.match(/[\n\r]*$/)[0].length;
}e.end=d-c.text.length;c.setEndPoint("StartToStart",a);e.start=d-c.text.length;}return e;},getSelectionStart:function(){return this.getSelectedRange().start;
},getSelectionEnd:function(){return this.getSelectedRange().end;},setCaretPosition:function(a){if(a=="end"){a=this.get("value").length;}this.selectRange(a,a);
return this;},getCaretPosition:function(){return this.getSelectedRange().start;},selectRange:function(e,a){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,a);
}else{var c=this.get("value");var d=c.substr(e,a-e).replace(/\r/g,"").length;e=c.substr(0,e).replace(/\r/g,"").length;var b=this.createTextRange();b.collapse(true);
b.moveEnd("character",e+d);b.moveStart("character",e);b.select();}return this;},insertAtCursor:function(b,a){var d=this.getSelectedRange();var c=this.get("value");
this.set("value",c.substring(0,d.start)+b+c.substring(d.end,c.length));if($pick(a,true)){this.selectRange(d.start,d.start+b.length);}else{this.setCaretPosition(d.start+b.length);
}return this;},insertAroundCursor:function(b,a){b=$extend({before:"",defaultMiddle:"",after:""},b);var c=this.getSelectedText()||b.defaultMiddle;var g=this.getSelectedRange();
var f=this.get("value");if(g.start==g.end){this.set("value",f.substring(0,g.start)+b.before+c+b.after+f.substring(g.end,f.length));this.selectRange(g.start+b.before.length,g.end+b.before.length+c.length);
}else{var d=f.substring(g.start,g.end);this.set("value",f.substring(0,g.start)+b.before+d+b.after+f.substring(g.end,f.length));var e=g.start+b.before.length;
if($pick(a,true)){this.selectRange(e,e+d.length);}else{this.setCaretPosition(e+f.length);}}return this;}});Element.implement({measure:function(e){var g=function(h){return !!(!h||h.offsetHeight||h.offsetWidth);
};if(g(this)){return e.apply(this);}var d=this.getParent(),f=[],b=[];while(!g(d)&&d!=document.body){b.push(d.expose());d=d.getParent();}var c=this.expose();
var a=e.apply(this);c();b.each(function(h){h();});return a;},expose:function(){if(this.getStyle("display")!="none"){return $empty;}var a=this.style.cssText;
this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=a;}.bind(this);},getDimensions:function(a){a=$merge({computeSize:false},a);
var f={};var d=function(g,e){return(e.computeSize)?g.getComputedSize(e):g.getSize();};var b=this.getParent("body");if(b&&this.getStyle("display")=="none"){f=this.measure(function(){return d(this,a);
});}else{if(b){try{f=d(this,a);}catch(c){}}else{f={x:0,y:0};}}return $chk(f.x)?$extend(f,{width:f.x,height:f.y}):$extend(f,{x:f.width,y:f.height});},getComputedSize:function(a){a=$merge({styles:["padding","border"],plains:{height:["top","bottom"],width:["left","right"]},mode:"both"},a);
var c={width:0,height:0};switch(a.mode){case"vertical":delete c.width;delete a.plains.width;break;case"horizontal":delete c.height;delete a.plains.height;
break;}var b=[];$each(a.plains,function(g,f){g.each(function(h){a.styles.each(function(i){b.push((i=="border")?i+"-"+h+"-width":i+"-"+h);});});});var e={};
b.each(function(f){e[f]=this.getComputedStyle(f);},this);var d=[];$each(a.plains,function(g,f){var h=f.capitalize();c["total"+h]=c["computed"+h]=0;g.each(function(i){c["computed"+i.capitalize()]=0;
b.each(function(k,j){if(k.test(i)){e[k]=e[k].toInt()||0;c["total"+h]=c["total"+h]+e[k];c["computed"+i.capitalize()]=c["computed"+i.capitalize()]+e[k];}if(k.test(i)&&f!=k&&(k.test("border")||k.test("padding"))&&!d.contains(k)){d.push(k);
c["computed"+h]=c["computed"+h]-e[k];}});});});["Width","Height"].each(function(g){var f=g.toLowerCase();if(!$chk(c[f])){return;}c[f]=c[f]+this["offset"+g]+c["computed"+g];
c["total"+g]=c[f]+c["total"+g];delete c["computed"+g];},this);return $extend(e,c);}});(function(){var a=Element.prototype.position;Element.implement({position:function(g){if(g&&($defined(g.x)||$defined(g.y))){return a?a.apply(this,arguments):this;
}$each(g||{},function(u,t){if(!$defined(u)){delete g[t];}});g=$merge({relativeTo:document.body,position:{x:"center",y:"center"},edge:false,offset:{x:0,y:0},returnPos:false,relFixedPosition:false,ignoreMargins:false,ignoreScroll:false,allowNegative:false},g);
var r={x:0,y:0},e=false;var c=this.measure(function(){return document.id(this.getOffsetParent());});if(c&&c!=this.getDocument().body){r=c.measure(function(){return this.getPosition();
});e=c!=document.id(g.relativeTo);g.offset.x=g.offset.x-r.x;g.offset.y=g.offset.y-r.y;}var s=function(t){if($type(t)!="string"){return t;}t=t.toLowerCase();
var u={};if(t.test("left")){u.x="left";}else{if(t.test("right")){u.x="right";}else{u.x="center";}}if(t.test("upper")||t.test("top")){u.y="top";}else{if(t.test("bottom")){u.y="bottom";
}else{u.y="center";}}return u;};g.edge=s(g.edge);g.position=s(g.position);if(!g.edge){if(g.position.x=="center"&&g.position.y=="center"){g.edge={x:"center",y:"center"};
}else{g.edge={x:"left",y:"top"};}}this.setStyle("position","absolute");var f=document.id(g.relativeTo)||document.body,d=f==document.body?window.getScroll():f.getPosition(),l=d.y,h=d.x;
var n=this.getDimensions({computeSize:true,styles:["padding","border","margin"]});var j={},o=g.offset.y,q=g.offset.x,k=window.getSize();switch(g.position.x){case"left":j.x=h+q;
break;case"right":j.x=h+q+f.offsetWidth;break;default:j.x=h+((f==document.body?k.x:f.offsetWidth)/2)+q;break;}switch(g.position.y){case"top":j.y=l+o;break;
case"bottom":j.y=l+o+f.offsetHeight;break;default:j.y=l+((f==document.body?k.y:f.offsetHeight)/2)+o;break;}if(g.edge){var b={};switch(g.edge.x){case"left":b.x=0;
break;case"right":b.x=-n.x-n.computedRight-n.computedLeft;break;default:b.x=-(n.totalWidth/2);break;}switch(g.edge.y){case"top":b.y=0;break;case"bottom":b.y=-n.y-n.computedTop-n.computedBottom;
break;default:b.y=-(n.totalHeight/2);break;}j.x+=b.x;j.y+=b.y;}j={left:((j.x>=0||e||g.allowNegative)?j.x:0).toInt(),top:((j.y>=0||e||g.allowNegative)?j.y:0).toInt()};
var i={left:"x",top:"y"};["minimum","maximum"].each(function(t){["left","top"].each(function(u){var v=g[t]?g[t][i[u]]:null;if(v!=null&&j[u]<v){j[u]=v;}});
});if(f.getStyle("position")=="fixed"||g.relFixedPosition){var m=window.getScroll();j.top+=m.y;j.left+=m.x;}if(g.ignoreScroll){var p=f.getScroll();j.top-=p.y;
j.left-=p.x;}if(g.ignoreMargins){j.left+=(g.edge.x=="right"?n["margin-right"]:g.edge.x=="center"?-n["margin-left"]+((n["margin-right"]+n["margin-left"])/2):-n["margin-left"]);
j.top+=(g.edge.y=="bottom"?n["margin-bottom"]:g.edge.y=="center"?-n["margin-top"]+((n["margin-bottom"]+n["margin-top"])/2):-n["margin-top"]);}j.left=Math.ceil(j.left);
j.top=Math.ceil(j.top);if(g.returnPos){return j;}else{this.setStyles(j);}return this;}});})();Element.implement({isDisplayed:function(){return this.getStyle("display")!="none";
},isVisible:function(){var a=this.offsetWidth,b=this.offsetHeight;return(a==0&&b==0)?false:(a>0&&b>0)?true:this.isDisplayed();},toggle:function(){return this[this.isDisplayed()?"hide":"show"]();
},hide:function(){var b;try{b=this.getStyle("display");}catch(a){}return this.store("originalDisplay",b||"").setStyle("display","none");},show:function(a){a=a||this.retrieve("originalDisplay")||"block";
return this.setStyle("display",(a=="none")?"block":a);},swapClass:function(a,b){return this.removeClass(a).addClass(b);}});Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b);
this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c;
},set:function(b){for(var c in b){var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);}}return this;},start:function(c){if(!this.check(c)){return this;
}var h={},j={};for(var d in c){var f=c[d],a=h[d]={},g=j[d]={};for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);a[b]=e.from;g[b]=e.to;}}return this.parent(h,j);
}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,returnHeightToAuto:true},initialize:function(){var c=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined});
this.parent(c.elements,c.options);this.togglers=$$(c.togglers);this.previous=-1;this.internalChain=new Chain();if(this.options.alwaysHide){this.options.wait=true;
}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;
}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";
}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var b=0,a=this.togglers.length;b<a;b++){this.addSection(this.togglers[b],this.elements[b]);
}this.elements.each(function(e,d){if(this.options.show===d){this.fireEvent("active",[this.togglers[d],e]);}else{for(var f in this.effects){e.setStyle(f,0);
}}},this);if($chk(this.options.display)||this.options.initialDisplayFx===false){this.display(this.options.display,this.options.initialDisplayFx);}if(this.options.fixedHeight!==false){this.options.returnHeightToAuto=false;
}this.addEvent("complete",this.internalChain.callChain.bind(this.internalChain));},addSection:function(e,c){e=document.id(e);c=document.id(c);var f=this.togglers.contains(e);
this.togglers.include(e);this.elements.include(c);var a=this.togglers.indexOf(e);var b=this.display.bind(this,a);e.store("accordion:display",b);e.addEvent(this.options.trigger,b);
if(this.options.height){c.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(this.options.width){c.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
}c.fullOpacity=1;if(this.options.fixedWidth){c.fullWidth=this.options.fixedWidth;}if(this.options.fixedHeight){c.fullHeight=this.options.fixedHeight;}c.setStyle("overflow","hidden");
if(!f){for(var d in this.effects){c.setStyle(d,0);}}return this;},detach:function(){this.togglers.each(function(a){a.removeEvent(this.options.trigger,a.retrieve("accordion:display"));
},this);},display:function(a,b){if(!this.check(a,b)){return this;}b=$pick(b,true);if(this.options.returnHeightToAuto){var d=this.elements[this.previous];
if(d&&!this.selfHidden){for(var c in this.effects){d.setStyle(c,d[this.effects[c]]);}}}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 e={};this.elements.each(function(h,g){e[g]={};var f;if(g!=a){f=true;}else{if(this.options.alwaysHide&&((h.offsetHeight>0&&this.options.height)||h.offsetWidth>0&&this.options.width)){f=true;
this.selfHidden=true;}}this.fireEvent(f?"background":"active",[this.togglers[g],h]);for(var j in this.effects){e[g][j]=f?0:h[this.effects[j]];}},this);
this.internalChain.chain(function(){if(this.options.returnHeightToAuto&&!this.selfHidden){var f=this.elements[a];if(f){f.setStyle("height","auto");}}}.bind(this));
return b?this.start(e):this.set(e);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);var a=Array.link(arguments,{container:Element.type});
this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);var a=this.togglers.length;if(a&&(!d||e)){e=$pick(e,a-1);
c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);b.inject(this.container);}}return this.parent.apply(this,arguments);
}});Fx.Move=new Class({Extends:Fx.Morph,options:{relativeTo:document.body,position:"center",edge:false,offset:{x:0,y:0}},start:function(a){return this.parent(this.element.position($merge(this.options,a,{returnPos:true})));
}});Element.Properties.move={set:function(a){var b=this.retrieve("move");if(b){b.cancel();}return this.eliminate("move").store("move:options",$extend({link:"cancel"},a));
},get:function(a){if(a||!this.retrieve("move")){if(a||!this.retrieve("move:options")){this.set("move",a);}this.store("move",new Fx.Move(this,this.retrieve("move:options")));
}return this.retrieve("move");}};Element.implement({move:function(a){this.get("move").start(a);return this;}});Fx.Reveal=new Class({Extends:Fx.Morph,options:{link:"cancel",styles:["padding","border","margin"],transitionOpacity:!Browser.Engine.trident4,mode:"vertical",display:"block",hideInputs:Browser.Engine.trident?"select, input, textarea, object, embed":false},dissolve:function(){try{if(!this.hiding&&!this.showing){if(this.element.getStyle("display")!="none"){this.hiding=true;
this.showing=false;this.hidden=true;this.cssText=this.element.style.cssText;var d=this.element.getComputedSize({styles:this.options.styles,mode:this.options.mode});
this.element.setStyle("display",this.options.display);if(this.options.transitionOpacity){d.opacity=1;}var b={};$each(d,function(f,e){b[e]=[f,0];},this);
this.element.setStyle("overflow","hidden");var a=this.options.hideInputs?this.element.getElements(this.options.hideInputs):null;this.$chain.unshift(function(){if(this.hidden){this.hiding=false;
$each(d,function(f,e){d[e]=f;},this);this.element.style.cssText=this.cssText;this.element.setStyle("display","none");if(a){a.setStyle("visibility","visible");
}}this.fireEvent("hide",this.element);this.callChain();}.bind(this));if(a){a.setStyle("visibility","hidden");}this.start(b);}else{this.callChain.delay(10,this);
this.fireEvent("complete",this.element);this.fireEvent("hide",this.element);}}else{if(this.options.link=="chain"){this.chain(this.dissolve.bind(this));
}else{if(this.options.link=="cancel"&&!this.hiding){this.cancel();this.dissolve();}}}}catch(c){this.hiding=false;this.element.setStyle("display","none");
this.callChain.delay(10,this);this.fireEvent("complete",this.element);this.fireEvent("hide",this.element);}return this;},reveal:function(){try{if(!this.showing&&!this.hiding){if(this.element.getStyle("display")=="none"||this.element.getStyle("visiblity")=="hidden"||this.element.getStyle("opacity")==0){this.showing=true;
this.hiding=this.hidden=false;var d;this.cssText=this.element.style.cssText;this.element.measure(function(){d=this.element.getComputedSize({styles:this.options.styles,mode:this.options.mode});
}.bind(this));$each(d,function(f,e){d[e]=f;});if($chk(this.options.heightOverride)){d.height=this.options.heightOverride.toInt();}if($chk(this.options.widthOverride)){d.width=this.options.widthOverride.toInt();
}if(this.options.transitionOpacity){this.element.setStyle("opacity",0);d.opacity=1;}var b={height:0,display:this.options.display};$each(d,function(f,e){b[e]=0;
});this.element.setStyles($merge(b,{overflow:"hidden"}));var a=this.options.hideInputs?this.element.getElements(this.options.hideInputs):null;if(a){a.setStyle("visibility","hidden");
}this.start(d);this.$chain.unshift(function(){this.element.style.cssText=this.cssText;this.element.setStyle("display",this.options.display);if(!this.hidden){this.showing=false;
}if(a){a.setStyle("visibility","visible");}this.callChain();this.fireEvent("show",this.element);}.bind(this));}else{this.callChain();this.fireEvent("complete",this.element);
this.fireEvent("show",this.element);}}else{if(this.options.link=="chain"){this.chain(this.reveal.bind(this));}else{if(this.options.link=="cancel"&&!this.showing){this.cancel();
this.reveal();}}}}catch(c){this.element.setStyles({display:this.options.display,visiblity:"visible",opacity:1});this.showing=false;this.callChain.delay(10,this);
this.fireEvent("complete",this.element);this.fireEvent("show",this.element);}return this;},toggle:function(){if(this.element.getStyle("display")=="none"||this.element.getStyle("visiblity")=="hidden"||this.element.getStyle("opacity")==0){this.reveal();
}else{this.dissolve();}return this;},cancel:function(){this.parent.apply(this,arguments);this.element.style.cssText=this.cssText;this.hidding=false;this.showing=false;
}});Element.Properties.reveal={set:function(a){var b=this.retrieve("reveal");if(b){b.cancel();}return this.eliminate("reveal").store("reveal:options",a);
},get:function(a){if(a||!this.retrieve("reveal")){if(a||!this.retrieve("reveal:options")){this.set("reveal",a);}this.store("reveal",new Fx.Reveal(this,this.retrieve("reveal:options")));
}return this.retrieve("reveal");}};Element.Properties.dissolve=Element.Properties.reveal;Element.implement({reveal:function(a){this.get("reveal",a).reveal();
return this;},dissolve:function(a){this.get("reveal",a).dissolve();return this;},nix:function(){var a=Array.link(arguments,{destroy:Boolean.type,options:Object.type});
this.get("reveal",a.options).dissolve().chain(function(){this[a.destroy?"destroy":"dispose"]();}.bind(this));return this;},wink:function(){var b=Array.link(arguments,{duration:Number.type,options:Object.type});
var a=this.get("reveal",b.options);a.reveal().chain(function(){(function(){a.dissolve();}).delay(b.duration||2000);});}});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.element=this.subject=document.id(b);
this.parent(a);var d=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=document.id(this.element.getDocument().body);}var c=this.element;
if(this.options.wheelStops){this.addEvent("start",function(){c.addEvent("mousewheel",d);},true);this.addEvent("complete",function(){c.removeEvent("mousewheel",d);
},true);}},set:function(){var a=Array.flatten(arguments);if(Browser.Engine.gecko){a=[Math.round(a[0]),Math.round(a[1])];}this.element.scrollTo(a[0],a[1]);
},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(c,g){if(!this.check(c,g)){return this;}var e=this.element.getScrollSize(),b=this.element.getScroll(),d={x:c,y:g};
for(var f in d){var a=e[f];if($chk(d[f])){d[f]=($type(d[f])=="number")?d[f]:a;}else{d[f]=b[f];}d[f]+=this.options.offset[f];}return this.parent([b.x,b.y],[d.x,d.y]);
},toTop:function(){return this.start(false,0);},toLeft:function(){return this.start(0,false);},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom");
},toElement:function(b){var a=document.id(b).getPosition(this.element);return this.start(a.x,a.y);},scrollIntoView:function(c,e,d){e=e?$splat(e):["x","y"];
var h={};c=document.id(c);var f=c.getPosition(this.element);var i=c.getSize();var g=this.element.getScroll();var a=this.element.getSize();var b={x:f.x+i.x,y:f.y+i.y};
["x","y"].each(function(j){if(e.contains(j)){if(b[j]>g[j]+a[j]){h[j]=b[j]-a[j];}if(f[j]<g[j]){h[j]=f[j];}}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];
}},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);}return this;},scrollToCenter:function(c,e,d){e=e?$splat(e):["x","y"];c=$(c);var h={},f=c.getPosition(this.element),i=c.getSize(),g=this.element.getScroll(),a=this.element.getSize(),b={x:f.x+i.x,y:f.y+i.y};
["x","y"].each(function(j){if(e.contains(j)){h[j]=f[j]-(a[j]-i[j])/2;}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];}},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);
}return this;}});Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical",wrapper:false,hideOverflow:true},initialize:function(b,a){this.addEvent("complete",function(){this.open=(this.wrapper["offset"+this.layout.capitalize()]!=0);
if(this.open){this.wrapper.setStyle("height","");}if(this.open&&Browser.Engine.webkit419){this.element.dispose().inject(this.wrapper);}},true);this.element=this.subject=document.id(b);
this.parent(a);var d=this.element.retrieve("wrapper");var c=this.element.getStyles("margin","position","overflow");if(this.options.hideOverflow){c=$extend(c,{overflow:"hidden"});
}if(this.options.wrapper){d=document.id(this.options.wrapper).setStyles(c);}this.wrapper=d||new Element("div",{styles:c}).wraps(this.element);this.element.store("wrapper",this.wrapper).setStyle("margin",0);
this.now=[];this.open=true;},vertical:function(){this.margin="margin-top";this.layout="height";this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";
this.layout="width";this.offset=this.element.offsetWidth;},set:function(a){this.element.setStyle(this.margin,a[0]);this.wrapper.setStyle(this.layout,a[1]);
return this;},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(b,e){if(!this.check(b,e)){return this;
}this[e||this.options.mode]();var d=this.element.getStyle(this.margin).toInt();var c=this.wrapper.getStyle(this.layout).toInt();var a=[[d,c],[0,this.offset]];
var g=[[d,c],[-this.offset,0]];var f;switch(b){case"in":f=a;break;case"out":f=g;break;case"toggle":f=(c==0)?a:g;}return this.parent(f[0],f[1]);},slideIn:function(a){return this.start("in",a);
},slideOut:function(a){return this.start("out",a);},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0]);},show:function(a){this[a||this.options.mode]();
this.open=true;return this.set([0,this.offset]);},toggle:function(a){return this.start("toggle",a);}});Element.Properties.slide={set:function(b){var a=this.retrieve("slide");
if(a){a.cancel();}return this.eliminate("slide").store("slide:options",$extend({link:"cancel"},b));},get:function(a){if(a||!this.retrieve("slide")){if(a||!this.retrieve("slide:options")){this.set("slide",a);
}this.store("slide",new Fx.Slide(this,this.retrieve("slide:options")));}return this.retrieve("slide");}};Element.implement({slide:function(d,e){d=d||"toggle";
var b=this.get("slide"),a;switch(d){case"hide":b.hide(e);break;case"show":b.show(e);break;case"toggle":var c=this.retrieve("slide:flag",b.open);b[c?"slideOut":"slideIn"](e);
this.store("slide:flag",!c);a=true;break;default:b.start(d,e);}if(!a){this.eliminate("slide:flag");}return this;}});var SmoothScroll=Fx.SmoothScroll=new Class({Extends:Fx.Scroll,initialize:function(b,c){c=c||document;
this.doc=c.getDocument();var d=c.getWindow();this.parent(this.doc,b);this.links=$$(this.options.links||this.doc.links);var a=d.location.href.match(/^[^#]*/)[0]+"#";
this.links.each(function(f){if(f.href.indexOf(a)!=0){return;}var e=f.href.substr(a.length);if(e){this.useLink(f,e);}},this);if(!Browser.Engine.webkit419){this.addEvent("complete",function(){d.location.hash=this.anchor;
},true);}},useLink:function(c,a){var b;c.addEvent("click",function(d){if(b!==false&&!b){b=document.id(a)||this.doc.getElement("a[name="+a+"]");}if(b){d.preventDefault();
this.anchor=a;this.toElement(b).chain(function(){this.fireEvent("scrolledTo",[c,b]);}.bind(this));c.blur();}}.bind(this));}});Fx.Sort=new Class({Extends:Fx.Elements,options:{mode:"vertical"},initialize:function(b,a){this.parent(b,a);
this.elements.each(function(c){if(c.getStyle("position")=="static"){c.setStyle("position","relative");}});this.setDefaultOrder();},setDefaultOrder:function(){this.currentOrder=this.elements.map(function(b,a){return a;
});},sort:function(e){if($type(e)!="array"){return false;}var i=0,a=0,c={},h={},d=this.options.mode=="vertical";var f=this.elements.map(function(m,j){var l=m.getComputedSize({styles:["border","padding","margin"]});
var n;if(d){n={top:i,margin:l["margin-top"],height:l.totalHeight};i+=n.height-l["margin-top"];}else{n={left:a,margin:l["margin-left"],width:l.totalWidth};
a+=n.width;}var k=d?"top":"left";h[j]={};var o=m.getStyle(k).toInt();h[j][k]=o||0;return n;},this);this.set(h);e=e.map(function(j){return j.toInt();});
if(e.length!=this.elements.length){this.currentOrder.each(function(j){if(!e.contains(j)){e.push(j);}});if(e.length>this.elements.length){e.splice(this.elements.length-1,e.length-this.elements.length);
}}var b=i=a=0;e.each(function(l,j){var k={};if(d){k.top=i-f[l].top-b;i+=f[l].height;}else{k.left=a-f[l].left;a+=f[l].width;}b=b+f[l].margin;c[l]=k;},this);
var g={};$A(e).sort().each(function(j){g[j]=c[j];});this.start(g);this.currentOrder=e;return this;},rearrangeDOM:function(a){a=a||this.currentOrder;var b=this.elements[0].getParent();
var c=[];this.elements.setStyle("opacity",0);a.each(function(d){c.push(this.elements[d].inject(b).setStyles({top:0,left:0}));},this);this.elements.setStyle("opacity",1);
this.elements=$$(c);this.setDefaultOrder();return this;},getDefaultOrder:function(){return this.elements.map(function(b,a){return a;});},forward:function(){return this.sort(this.getDefaultOrder());
},backward:function(){return this.sort(this.getDefaultOrder().reverse());},reverse:function(){return this.sort(this.currentOrder.reverse());},sortByElements:function(a){return this.sort(a.map(function(b){return this.elements.indexOf(b);
},this));},swap:function(c,b){if($type(c)=="element"){c=this.elements.indexOf(c);}if($type(b)=="element"){b=this.elements.indexOf(b);}var a=$A(this.currentOrder);
a[this.currentOrder.indexOf(c)]=b;a[this.currentOrder.indexOf(b)]=c;return this.sort(a);}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Object.type,element:$defined});
this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=$type(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
return this;},start:function(c){var t=$type(this.handles);var ta=$(c.target);if(t=='array'||t=='collection'){if(!this.handles.contains(ta)){return;}}if(t=='element'&&this.handles!=ta){return;}if(c.rightClick){return;}if(this.options.preventDefault){c.preventDefault();}if(this.options.stopPropagation){c.stopPropagation();
}this.mouse.start=c.page;this.fireEvent("beforeStart",this.element);var a=this.options.limit;this.limit={x:[],y:[]};for(var d in this.options.modifiers){if(!this.options.modifiers[d]){continue;
}if(this.options.style){this.value.now[d]=this.element.getStyle(this.options.modifiers[d]).toInt();}else{this.value.now[d]=this.element[this.options.modifiers[d]];
}if(this.options.invert){this.value.now[d]*=-1;}this.mouse.pos[d]=c.page[d]-this.value.now[d];if(a&&a[d]){for(var b=2;b--;b){if($chk(a[d][b])){this.limit[d][b]=$lambda(a[d][b])();
}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});
this.document.addEvent(this.selection,this.bound.eventStop);},check:function(a){if(this.options.preventDefault){a.preventDefault();}var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));
if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);
}},drag:function(a){if(this.options.preventDefault){a.preventDefault();}this.mouse.now=a.page;for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue;
}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.options.invert){this.value.now[b]*=-1;}if(this.options.limit&&this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1];
}else{if($chk(this.limit[b][0])&&(this.value.now[b]<this.limit[b][0])){this.value.now[b]=this.limit[b][0];}}}if(this.options.grid[b]){this.value.now[b]-=((this.value.now[b]-(this.limit[b][0]||0))%this.options.grid[b]);
}if(this.options.style){this.element.setStyle(this.options.modifiers[b],this.value.now[b]+this.options.unit);}else{this.element[this.options.modifiers[b]]=this.value.now[b];
}}this.fireEvent("drag",[this.element,a]);},cancel:function(a){this.document.removeEvent("mousemove",this.bound.check);this.document.removeEvent("mouseup",this.bound.cancel);
if(a){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("cancel",this.element);}},stop:function(a){this.document.removeEvent(this.selection,this.bound.eventStop);
this.document.removeEvent("mousemove",this.bound.drag);this.document.removeEvent("mouseup",this.bound.stop);if(a){this.fireEvent("complete",[this.element,a]);
}}});Element.implement({makeResizable:function(a){var b=new Drag(this,$merge({modifiers:{x:"width",y:"height"}},a));this.store("resizer",b);return b.addEvent("drag",function(){this.fireEvent("resize",b);
}.bind(this));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false,precalculate:false,includeMargins:true,checkDroppables:true},initialize:function(b,a){this.parent(b,a);
b=this.element;this.droppables=$$(this.options.droppables);this.container=document.id(this.options.container);if(this.container&&$type(this.container)!="element"){this.container=document.id(this.container.getDocument().body);
}var c=b.getStyles("left","top","position");if(c.left=="auto"||c.top=="auto"){b.setPosition(b.getPosition(b.getOffsetParent()));}if(c.position=="static"){b.setStyle("position","absolute");
}this.addEvent("start",this.checkDroppables,true);this.overed=null;},start:function(a){if(this.container){this.options.limit=this.calculateLimit();}if(this.options.precalculate){this.positions=this.droppables.map(function(b){return b.getCoordinates();
});}this.parent(a);},calculateLimit:function(){var d=this.element.getOffsetParent(),g=this.container.getCoordinates(d),f={},c={},b={},i={},k={};["top","right","bottom","left"].each(function(o){f[o]=this.container.getStyle("border-"+o).toInt();
b[o]=this.element.getStyle("border-"+o).toInt();c[o]=this.element.getStyle("margin-"+o).toInt();i[o]=this.container.getStyle("margin-"+o).toInt();k[o]=d.getStyle("padding-"+o).toInt();
},this);var e=this.element.offsetWidth+c.left+c.right,n=this.element.offsetHeight+c.top+c.bottom,h=0,j=0,m=g.right-f.right-e,a=g.bottom-f.bottom-n;if(this.options.includeMargins){h+=c.left;
j+=c.top;}else{m+=c.right;a+=c.bottom;}if(this.element.getStyle("position")=="relative"){var l=this.element.getCoordinates(d);l.left-=this.element.getStyle("left").toInt();
l.top-=this.element.getStyle("top").toInt();h+=f.left-l.left;j+=f.top-l.top;m+=c.left-l.left;a+=c.top-l.top;if(this.container!=d){h+=i.left+k.left;j+=(Browser.Engine.trident4?0:i.top)+k.top;
}}else{h-=c.left;j-=c.top;if(this.container==d){m-=f.left;a-=f.top;}else{h+=g.left+f.left;j+=g.top+f.top;}}return{x:[h,m],y:[j,a]};},checkAgainst:function(c,b){c=(this.positions)?this.positions[b]:c.getCoordinates();
var a=this.mouse.now;return(a.x>c.left&&a.x<c.right&&a.y<c.bottom&&a.y>c.top);},checkDroppables:function(){var a=this.droppables.filter(this.checkAgainst,this).getLast();
if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a);
if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]);
this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);this.store("dragger",b);return b;}});
var Slider=new Class({Implements:[Events,Options],Binds:["clickedElement","draggedKnob","scrolledElement"],options:{onTick:function(a){if(this.options.snap){a=this.toPosition(this.step);
}this.knob.setStyle(this.property,a);},initialStep:0,snap:false,offset:0,range:false,wheel:false,steps:100,mode:"horizontal"},initialize:function(f,a,e){this.setOptions(e);
this.element=document.id(f);this.knob=document.id(a);this.previousChange=this.previousEnd=this.step=-1;var g,b={},d={x:false,y:false};switch(this.options.mode){case"vertical":this.axis="y";
this.property="top";g="offsetHeight";break;case"horizontal":this.axis="x";this.property="left";g="offsetWidth";}this.full=this.element.measure(function(){this.half=this.knob[g]/2;
return this.element[g]-this.knob[g]+(this.options.offset*2);}.bind(this));this.min=$chk(this.options.range[0])?this.options.range[0]:0;this.max=$chk(this.options.range[1])?this.options.range[1]:this.options.steps;
this.range=this.max-this.min;this.steps=this.options.steps||this.full;this.stepSize=Math.abs(this.range)/this.steps;this.stepWidth=this.stepSize*this.full/Math.abs(this.range);
this.knob.setStyle("position","relative").setStyle(this.property,this.options.initialStep?this.toPosition(this.options.initialStep):-this.options.offset);
d[this.axis]=this.property;b[this.axis]=[-this.options.offset,this.full-this.options.offset];var c={snap:0,limit:b,modifiers:d,onDrag:this.draggedKnob,onStart:this.draggedKnob,onBeforeStart:(function(){this.isDragging=true;
}).bind(this),onCancel:function(){this.isDragging=false;}.bind(this),onComplete:function(){this.isDragging=false;this.draggedKnob();this.end();}.bind(this)};
if(this.options.snap){c.grid=Math.ceil(this.stepWidth);c.limit[this.axis][1]=this.full;}this.drag=new Drag(this.knob,c);this.attach();},attach:function(){this.element.addEvent("mousedown",this.clickedElement);
if(this.options.wheel){this.element.addEvent("mousewheel",this.scrolledElement);}this.drag.attach();return this;},detach:function(){this.element.removeEvent("mousedown",this.clickedElement);
this.element.removeEvent("mousewheel",this.scrolledElement);this.drag.detach();return this;},set:function(a){if(!((this.range>0)^(a<this.min))){a=this.min;
}if(!((this.range>0)^(a>this.max))){a=this.max;}this.step=Math.round(a);this.checkStep();this.fireEvent("tick",this.toPosition(this.step));this.end();return this;
},clickedElement:function(c){if(this.isDragging||c.target==this.knob){return;}var b=this.range<0?-1:1;var a=c.page[this.axis]-this.element.getPosition()[this.axis]-this.half;
a=a.limit(-this.options.offset,this.full-this.options.offset);this.step=Math.round(this.min+b*this.toStep(a));this.checkStep();this.fireEvent("tick",a);
this.end();},scrolledElement:function(a){var b=(this.options.mode=="horizontal")?(a.wheel<0):(a.wheel>0);this.set(b?this.step-this.stepSize:this.step+this.stepSize);
a.stop();},draggedKnob:function(){var b=this.range<0?-1:1;var a=this.drag.value.now[this.axis];a=a.limit(-this.options.offset,this.full-this.options.offset);
this.step=Math.round(this.min+b*this.toStep(a));this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;
this.fireEvent("change",this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("complete",this.step+"");
}},toStep:function(a){var b=(a+this.options.offset)*this.stepSize/this.full*this.steps;return this.options.steps?Math.round(b-=b%this.stepSize):b;},toPosition:function(a){return(this.full*Math.abs(this.min-a))/(this.steps*this.stepSize)-this.options.offset;
}});var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false},initialize:function(a,b){this.setOptions(b);
this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(a)||a));if(!this.options.clone){this.options.revert=false;}if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert));
}},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(a){this.elements.push(a);
var b=a.retrieve("sortables:start",this.start.bindWithEvent(this,a));(this.options.handle?a.getElement(this.options.handle)||a:a).addEvent("mousedown",b);
},this);return this;},addLists:function(){Array.flatten(arguments).each(function(a){this.lists.push(a);this.addItems(a.getChildren());},this);return this;
},removeItems:function(){return $$(Array.flatten(arguments).map(function(a){this.elements.erase(a);var b=a.retrieve("sortables:start");(this.options.handle?a.getElement(this.options.handle)||a:a).removeEvent("mousedown",b);
return a;},this));},removeLists:function(){return $$(Array.flatten(arguments).map(function(a){this.lists.erase(a);this.removeItems(a.getChildren());return a;
},this));},getClone:function(b,a){if(!this.options.clone){return new Element("div").inject(document.body);}if($type(this.options.clone)=="function"){return this.options.clone.call(this,b,a,this.list);
}var c=a.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden",width:a.getStyle("width")});if(c.get("html").test("radio")){c.getElements("input[type=radio]").each(function(d,e){d.set("name","clone_"+e);
});}return c.inject(this.list).setPosition(a.getPosition(a.getOffsetParent()));},getDroppables:function(){var a=this.list.getChildren();if(!this.options.constrain){a=this.lists.concat(a).erase(this.list);
}return a.erase(this.clone).erase(this.element);},insert:function(c,b){var a="inside";if(this.lists.contains(b)){this.list=b;this.drag.droppables=this.getDroppables();
}else{a=this.element.getAllPrevious().contains(b)?"before":"after";}this.element.inject(b,a);this.fireEvent("sort",[this.element,this.clone]);},start:function(b,a){if(!this.idle){return;
}this.idle=false;this.element=a;this.opacity=a.get("opacity");this.list=a.getParent();this.clone=this.getClone(b,a);this.drag=new Drag.Move(this.clone,{snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){b.stop();
this.clone.setStyle("visibility","visible");this.element.set("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});
this.clone.inject(this.element,"before");this.drag.start(b);},end:function(){this.drag.detach();this.element.set("opacity",this.opacity);if(this.effect){var a=this.element.getStyles("width","height");
var b=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));this.effect.element=this.clone;this.effect.start({top:b.top,left:b.left,width:a.width,height:a.height,opacity:0.25}).chain(this.reset.bind(this));
}else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("complete",this.element);},serialize:function(){var c=Array.link(arguments,{modifier:Function.type,index:$defined});
var b=this.lists.map(function(d){return d.getChildren().map(c.modifier||function(e){return e.get("id");},this);},this);var a=c.index;if(this.lists.length==1){a=0;
}return $chk(a)&&a>=0&&a<this.lists.length?b[a]:b;}});var Asset={javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);
if(d.onLoad){d.onload=d.onLoad;}var b=new Element("script",{src:f,type:"text/javascript"});var e=d.onload.bind(b),a=d.check,g=d.document;delete d.onload;
delete d.check;delete d.document;b.addEvents({load:e,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){e();}}}).set(d);if(Browser.Engine.webkit419){var c=(function(){if(!$try(a)){return;
}$clear(c);e();}).periodical(50);}return b.inject(g.head);},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head);
},image:function(c,b){b=$merge({onload:$empty,onabort:$empty,onerror:$empty},b);var d=new Image();var a=document.id(d)||new Element("img");["load","abort","error"].each(function(e){var g="on"+e;
var f=e.capitalize();if(b["on"+f]){b[g]=b["on"+f];}var h=b[g];delete b[g];d[g]=function(){if(!d){return;}if(!a.parentNode){a.width=d.width;a.height=d.height;
}d=d.onload=d.onabort=d.onerror=null;h.delay(1,a,a);a.fireEvent(e,a,1);};});d.src=a.src=c;if(d&&d.complete){d.onload.delay(1);}return a.set(b);},images:function(d,c){c=$merge({onComplete:$empty,onProgress:$empty,onError:$empty,properties:{}},c);
d=$splat(d);var a=[];var b=0;return new Elements(d.map(function(e){return Asset.image(e,$extend(c.properties,{onload:function(){c.onProgress.call(this,b,d.indexOf(e));
b++;if(b==d.length){c.onComplete();}},onerror:function(){c.onError.call(this,b,d.indexOf(e));b++;if(b==d.length){c.onComplete();}}}));}));}};var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(a,b){this.element.scrollTo(a,b);
},fps:50},initialize:function(b,a){this.setOptions(a);this.element=document.id(b);this.docBody=document.id(this.element.getDocument().body);this.listener=($type(this.element)!="element")?this.docBody:this.element;
this.timer=null;this.bound={attach:this.attach.bind(this),detach:this.detach.bind(this),getCoords:this.getCoords.bind(this)};},start:function(){this.listener.addEvents({mouseover:this.bound.attach,mouseout:this.bound.detach});
},stop:function(){this.listener.removeEvents({mouseover:this.bound.attach,mouseout:this.bound.detach});this.detach();this.timer=$clear(this.timer);},attach:function(){this.listener.addEvent("mousemove",this.bound.getCoords);
},detach:function(){this.listener.removeEvent("mousemove",this.bound.getCoords);this.timer=$clear(this.timer);},getCoords:function(a){this.page=(this.listener.get("tag")=="body")?a.client:a.page;
if(!this.timer){this.timer=this.scroll.periodical(Math.round(1000/this.options.fps),this);}},scroll:function(){var b=this.element.getSize(),a=this.element.getScroll(),f=this.element!=this.docBody?this.element.getOffsets():{x:0,y:0},c=this.element.getScrollSize(),e={x:0,y:0};
for(var d in this.page){if(this.page[d]<(this.options.area+f[d])&&a[d]!=0){e[d]=(this.page[d]-this.options.area-f[d])*this.options.velocity;}else{if(this.page[d]+this.options.area>(b[d]+f[d])&&a[d]+b[d]!=c[d]){e[d]=(this.page[d]-b[d]+this.options.area-f[d])*this.options.velocity;
}}}if(e.y||e.x){this.fireEvent("change",[a.x+e.x,a.y+e.y]);}}});(function(){var a=function(c,b){return(c)?($type(c)=="function"?c(b):b.get(c)):"";};this.Tips=new Class({Implements:[Events,Options],options:{onShow:function(){this.tip.setStyle("display","block");
},onHide:function(){this.tip.setStyle("display","none");},title:"title",text:function(b){return b.get("rel")||b.get("href");},showDelay:100,hideDelay:100,className:"tip-wrap",offset:{x:16,y:16},windowPadding:{x:0,y:0},fixed:false},initialize:function(){var b=Array.link(arguments,{options:Object.type,elements:$defined});
this.setOptions(b.options);if(b.elements){this.attach(b.elements);}this.container=new Element("div",{"class":"tip"});},toElement:function(){if(this.tip){return this.tip;
}return this.tip=new Element("div",{"class":this.options.className,styles:{position:"absolute",top:0,left:0}}).adopt(new Element("div",{"class":"tip-top"}),this.container,new Element("div",{"class":"tip-bottom"})).inject(document.body);
},attach:function(b){$$(b).each(function(d){var f=a(this.options.title,d),e=a(this.options.text,d);d.erase("title").store("tip:native",f).retrieve("tip:title",f);
d.retrieve("tip:text",e);this.fireEvent("attach",[d]);var c=["enter","leave"];if(!this.options.fixed){c.push("move");}c.each(function(h){var g=d.retrieve("tip:"+h);
if(!g){g=this["element"+h.capitalize()].bindWithEvent(this,d);}d.store("tip:"+h,g).addEvent("mouse"+h,g);},this);},this);return this;},detach:function(b){$$(b).each(function(d){["enter","leave","move"].each(function(e){d.removeEvent("mouse"+e,d.retrieve("tip:"+e)).eliminate("tip:"+e);
});this.fireEvent("detach",[d]);if(this.options.title=="title"){var c=d.retrieve("tip:native");if(c){d.set("title",c);}}},this);return this;},elementEnter:function(c,b){this.container.empty();
["title","text"].each(function(e){var d=b.retrieve("tip:"+e);if(d){this.fill(new Element("div",{"class":"tip-"+e}).inject(this.container),d);}},this);$clear(this.timer);
this.timer=(function(){this.show(this,b);this.position((this.options.fixed)?{page:b.getPosition()}:c);}).delay(this.options.showDelay,this);},elementLeave:function(c,b){$clear(this.timer);
this.timer=this.hide.delay(this.options.hideDelay,this,b);this.fireForParent(c,b);},fireForParent:function(c,b){b=b.getParent();if(!b||b==document.body){return;
}if(b.retrieve("tip:enter")){b.fireEvent("mouseenter",c);}else{this.fireForParent(c,b);}},elementMove:function(c,b){this.position(c);},position:function(e){if(!this.tip){document.id(this);
}var c=window.getSize(),b=window.getScroll(),f={x:this.tip.offsetWidth,y:this.tip.offsetHeight},d={x:"left",y:"top"},g={};for(var h in d){g[d[h]]=e.page[h]+this.options.offset[h];
if((g[d[h]]+f[h]-b[h])>c[h]-this.options.windowPadding[h]){g[d[h]]=e.page[h]-this.options.offset[h]-f[h];}}this.tip.setStyles(g);},fill:function(b,c){if(typeof c=="string"){b.set("html",c);
}else{b.adopt(c);}},show:function(b){if(!this.tip){document.id(this);}this.fireEvent("show",[this.tip,b]);},hide:function(b){if(!this.tip){document.id(this);
}this.fireEvent("hide",[this.tip,b]);}});})();MooTools.lang.set("en-US","Date",{months:["January","February","March","April","May","June","July","August","September","October","November","December"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dateOrder:["month","date","year"],shortDate:"%m/%d/%Y",shortTime:"%I:%M%p",AM:"AM",PM:"PM",ordinal:function(a){return(a>3&&a<21)?"th":["th","st","nd","rd","th"][Math.min(a%10,4)];
},lessThanMinuteAgo:"less than a minute ago",minuteAgo:"about a minute ago",minutesAgo:"{delta} minutes ago",hourAgo:"about an hour ago",hoursAgo:"about {delta} hours ago",dayAgo:"1 day ago",daysAgo:"{delta} days ago",weekAgo:"1 week ago",weeksAgo:"{delta} weeks ago",monthAgo:"1 month ago",monthsAgo:"{delta} months ago",yearAgo:"1 year ago",yearsAgo:"{delta} years ago",lessThanMinuteUntil:"less than a minute from now",minuteUntil:"about a minute from now",minutesUntil:"{delta} minutes from now",hourUntil:"about an hour from now",hoursUntil:"about {delta} hours from now",dayUntil:"1 day from now",daysUntil:"{delta} days from now",weekUntil:"1 week from now",weeksUntil:"{delta} weeks from now",monthUntil:"1 month from now",monthsUntil:"{delta} months from now",yearUntil:"1 year from now",yearsUntil:"{delta} years from now"});


$type.element = function(element) {
	return $type(element) == 'element';
}
$type.textnode = function(element) {
	return $type(element) == 'textnode';
}
$type.whitespace = function(element) {
	return $type(element) == 'whitespace';
}
$type.arguments = function(element) {
	return $type(element) == 'arguments';
}
$type.array = function(element) {
	return $type(element) == 'array';
}
$type.object = function(element) {
	return $type(element) == 'object';
}
$type.string = function(element) {
	return $type(element) == 'string';
}
$type.number = function(element) {
	return $type(element) == 'number';
}
$type.date = function(element) {
	return $type(element) == 'date';
}
$type.bool = function(element) {
	return $type(element) == 'boolean';
}
$type.func = function(element) {
	return $type(element) == 'function';
}
$type.regexp = function(element) {
	return $type(element) == 'regexp';
}
$type.Class = function(element) {
	return $type(element) == 'class';
}
$type.collection = function(element) {
	return $type(element) == 'collection';
}

Array.implement({
			/**
			 * Функция, создания диапазона целых чисел
			 * 
			 * @return {Array}
			 */
			range : function() {
				if (this.length < 2)
					return false;
				var start = this[0];
				var stop = this[1];
				var nw = [];
				--start;
				while (++start <= stop) {
					nw.include(start);
				}
				return nw;
			},

			/**
			 * Находит наибольшее значение массива чисел
			 * 
			 * @return {Number} максимальное значение массива натуральных чисел
			 */
			getMax : function() {
				var max_value;
				for (var i = 0; i < this.length; i++) {
					if (!$chk(max_value)) {
						max_value = this[i].toInt();
					}
					if (this[i].toInt() > max_value) {
						max_value = this[i].toInt();
					}
				}
				return max_value;
			},

			/**
			 * Находит наименьшее значение массива чисел
			 * 
			 * @return {Number} минимальное занчение массива натуральных чисел
			 */
			getMin : function() {
				var min_value;
				for (var i = 0; i < this.length; i++) {
					if (!$chk(min_value)) {
						min_value = this[i].toInt();
					}
					if (this[i].toInt() < min_value) {
						min_value = this[i].toInt();
					}
				}
				return min_value;
			},

			/**
			 * @description Находит разницу массивов
			 * 
			 * @param {Array}
			 *            v вычитаемый массив
			 * @param {Boolean}
			 *            m в случае если тру, то возвращается только индекс
			 *            базового массива
			 * @return {Array} разницу массивов
			 */
			diff : function(v, m) {
				if (v.length) {
					var d = [], e = -1, h, i, j, k;
					for (i = this.length, k = v.length; i--;) {
						for (j = k; j && (h = this[i] !== v[--j]););
						h && (d[++e] = m ? i : this[i]);
					}
					return d;
				}
				return this;
			},

			/**
			 * @description Из массива объектов типа checkbox или radio находит
			 *              выделенные и возвращает в виде массива элементов
			 * 
			 * @return {Array} Выделенные элементы
			 */
			getChecked : function() {
				var chkd = [];
				for (var i = 0, len = this.length; i < len; i++) {
					if (this[i].get('tag') == 'input'
							&& (this[i].getProperty('type') == 'radio' || this[i]
									.getProperty('type') == 'checkbox')) {
						if (this[i].checked) {
							chkd.push(this[i]);
						}
					} else {
						break;
					}
				}
				return chkd;
			},
			
			intersect : function(a, m) {
			    var s = this;
			    var l = this.length;
			    var int = [];
			    
			    for (var i = 0; i < l; i++) {
			        if (a.contains(this[i])) {
			            if (m) {
			                int.push(i);
			            } else {
			                int.push(this[i]);
			            }
			        };
			    };
			    
			    return int;
			}
		});

Element.implement({

	/**
	 * Функция переключает класс hide - то есть переключает видимость элемента
	 * Нетрудно понять, что в стиля должен быть прописан стиль .hide { display:
	 * none; }
	 */
	toggle : function() {
		if (this.hasClass('hide')) {
			this.removeClass('hide');
		} else {
			this.addClass('hide');
		}
		return this;
	},

	/**
	 * Открывает элемент
	 */
	show : function(animated) {
	    if (this.hasClass('hide')) {
	        if (arguments.length && animated) {
	            var fx = this.retrieve('fx');
    		    if (!fx) {
    		        fx = this.get('tween');
    		        fx.options.duration = 150;
    		        this.store('fx', fx);
    		    };
    		    
    		    this.setStyle('opacity', 0).removeClass('hide');
    		    fx.cancel();
    		    fx.start('opacity', 1);
    		} else {
    		    this.removeClass('hide');
    		};
	    };
		
		return this;
	},
	
	showAt : function(x, y, animated) {
	    this.setStyles({
	        top: y,
	        left: x
	    }).show({}, animated);
	    
	    return this;
	},

	/**
	 * @description Скрывает элемент (добавляет класс hide)
	 */
	hide : function(animated) {
	    var self = this;
	    var fx = this.retrieve('fx');
        if (!fx) {
	        fx = this.get('tween');
	        fx.options.duration = 150;
	        this.store('fx', fx);
	    };
	    var onHideComplete = function() {
	        self.addClass('hide').setStyle('opacity', 1);
	        fx.removeEvent('complete', onHideComplete);
	    };
	    
		if (!this.hasClass('hide')) {
		    if (arguments.length && animated) {
		        fx.addEvent('complete', onHideComplete);
    		    fx.cancel();
    		    fx.start('opacity', 0);
    		} else {
    		    this.addClass('hide')
    		};
		};
		
		return this;
	},

	/**
	 * @description Скрыт элемент или нет
	 */
	isVisible : function() {
		return !this.hasClass('hide');
	},

	/**
	 * Функция переключает элементу значение указанного аттрибута
	 * 
	 * @param {String}
	 *            attr атрибут, с которым работаем
	 * @param {Array}
	 *            values Значения атрибута, которые нужно менять
	 */
	toggleAttributes : function(attr, values) {
		if (attr == 'class') {
			if (this.hasClass(values[0])) {
				this.removeClass(values[0]);
				this.addClass(values[1]);
				return;
			}
			if (this.hasClass(values[1])) {
				this.removeClass(values[1]);
				this.addClass(values[0]);
				return;
			}
		} else {
			if ($(this).get(attr) == values[0]) {
				$(this).set(attr, values[1]);
			} else {
				$(this).set(attr, values[0]);
			}
		}
		return this;
	},

	/**
	 * Функция ресетает форму, в которой жестко прописаны <code>value</code>
	 * 
	 * @param {Element|String}
	 *            frm элемент формы, либо его идентфикатор
	 */
	resetForm : function() {
		if (this.get('tag') !== 'form') {
			// если это не форма, то получается косяк
			return;
		}
		var control_elements = this.getElements('input, select, textarea');
		for (var i = 0, len = control_elements.length; i < len; i++) {
			if (control_elements[i].get('tag') == 'input'
					&& control_elements[i].getProperty('type') != 'reset'
					&& control_elements[i].getProperty('type') != 'submit') {
				if ((control_elements[i].getProperty('type') == 'radio' || control_elements[i]
						.getProperty('type') == 'checkbox')
						&& control_elements[i].checked) {
					control_elements[i].checked = false;
				}
				if (control_elements[i].getProperty('type') == 'text') {
					control_elements[i].value = '';
				}
			}
			if (control_elements[i].get('tag') == 'select') {
				if (control_elements[i].getProperty('multiple')) {
					for (var j = 0; j < control_elements[i].options.length; j++) {
						control_elements[i].options[j].selected = false;
					}
				} else {
					control_elements[i].options[0].selected = true;
				}
			}
			if (control_elements[i].get('tag') == 'textarea') {
				control_elements[i].value = '';
			}
		}
		return this;
	},
	/**
	 * Проверяем, является ли значение поля числом с плавающей запятой
	 * 
	 * @return {Boolean} правда, если значение поля - число в плавающей запятой;
	 *         ложь - в обратном случае
	 */
	isFloat : function() {
		var val = this.get('text');
		if (/^[-+]?[0-9]+(\.[0-9]+)?$/.test(val)) {
			return true;
		}
		return false;
	},
	
	emphasize : function(c, a) {
		if (!a) {
			a = this.retrieve("highlight:original", this
							.getStyle("color"));
			a = (a == "transparent") ? "#fff" : a;
		}
		var b = this.get("tween");
		b.start("color", c || "#ffff88", a).chain(
				function() {
					this.setStyle("color", this
									.retrieve("highlight:original"));
					b.callChain();
				}.bind(this));
		return this;
	},
	
	twitch: function() {
	    var timer = null;
	    var offset = 1;
	    var el = this;
	    var times = 5;
	    var currentIteration = 0;
	    var speed = 50;
	    el.setStyle('position', 'relative');
	    var t = function() {
	        if (currentIteration == times) {
	            $clear(timer);
	            timer = null;
	            el.setStyles({
	                'position': '',
	                'left': ''
	            });
	        } else {
	            if (offset > 0) {
	                offset = -1;
	            } else {
	                offset = 1;
	            }
	            el.setStyle('left', offset);
	            currentIteration++;
	        }
	    }
	    timer = t.periodical(speed);
	},

    hasEvent: function(eventType,fn) {
        //get the element's events
        var myEvents = this.retrieve('events');
        //can we shoot this down?
        return myEvents && myEvents[eventType] && (fn == undefined || myEvents[eventType].keys.contains(fn));
    },
    
    // Плавный переход значений в инпуте
    // to — integer
    // from — integer | '' | пропущено
    // format — [2, ',', ' ']
    transposeTo: function(to, from, format) {
        input = this;

        var timer;
        var values = [];
        var pointer = 0;
        var valuesFormat = [0, '', ''];
        
        var c = function() {
            input.set('value', values[pointer]);
            pointer++;
            if (pointer == values.length) {
                $clear(timer);
                input.disabled = false;
            };
        };
        
        if (arguments.length > 2) {
            valuesFormat = format;
        };
        
        var f = (arguments.length > 1 && $type.number(from)) ? from.toInt() : (function() {
            var v = input.get('value');
            if (!v.length) return 0;
            v = v.substr(0, v.length - (valuesFormat[0] + valuesFormat[1].length));
            v = v.replace(new RegExp(valuesFormat[2], 'g'), '');
            return v.toInt();
        })();
        if (!f) f = 0;
        var t = to.toInt();
        
        var diff = t - f;
        var intermediateVal;

        if (Math.abs(diff) >= 10) {
            for (var i = 1; i < 10; i++) {
                intermediateVal = f + Math.floor(diff * (i / 10));
                values.push(intermediateVal.formatMoney.apply(intermediateVal, valuesFormat));
            };
        } else {
            var l = (f + '').length;
            var factor = '1';
            for (var i = 0; i < l; i++) {
                factor += '0';
            };
            factor = factor.toInt();
            for (i = 0; i < 9; i++) {
                intermediateVal = Math.floor(Math.random() * factor);
                values.push(intermediateVal.formatMoney.apply(intermediateVal, valuesFormat));
            }
        };
        
        values.push(t.formatMoney.apply(t, valuesFormat));
        
        input.disabled = true;
        timer = c.periodical(30);
    }
});

Document.implement({
    hasEvent: function(eventType,fn) {
        //get the element's events
        var myEvents = this.retrieve('events');
        //can we shoot this down?
        return myEvents && myEvents[eventType] && (fn == undefined || myEvents[eventType].keys.contains(fn));
    }
});

String.implement({
			/**
			 * Проверяем, является ли значение поля числом с плавающей запятой
			 * 
			 * @return {Boolean} правда, если значение поля - число в плавающей
			 *         запятой; ложь - в обратном случае
			 */
			isFloat : function() {
				var val = this;
				val += '';
				if (/^[-+]?[0-9]+(\.[0-9]+)?$/.test(val)) {
					return true;
				}
				return false;
			},
			/**
			 * Смотрим, четное ли число
			 * 
			 * @return {Boolean} правда, если значение поля - четное; ложь - в
			 *         обратном случае
			 */
			isOdd : function() {
				var num = this.toInt();
				return (num % 2) ? true : false;
			},
			/**
			 * Фукнция-транслитератор
			 * 
			 * @param {String}
			 *            string строка, которую нужно транслитирировать
			 * @return {String}
			 */
			transliterate : function(string) {
				string = this.trim();
				var cyr = ["Щ", "Ш", "Ч", "Ц", "Ю", "Я", "Ж", "А", "Б", "В",
						"Г", "Д", "Е", "Ё", "З", "И", "Й", "К", "Л", "М", "Н",
						"О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ь", "Ы", "Ъ",
						"Э", "Є", "Ї", "щ", "ш", "ч", "ц", "ю", "я", "ж", "а",
						"б", "в", "г", "д", "е", "ё", "з", "и", "й", "к", "л",
						"м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ь",
						"ы", "ъ", "э", "є", "ї"];
				var lat = ["Shh", "Sh", "Ch", "C", "Ju", "Ja", "Zh", "A", "B",
						"V", "G", "D", "Je", "Jo", "Z", "I", "J", "K", "L",
						"M", "N", "O", "P", "R", "S", "T", "U", "F", "Kh", "'",
						"Y", "`", "E", "Je", "Ji", "shh", "sh", "ch", "c",
						"ju", "ja", "zh", "a", "b", "v", "g", "d", "je", "jo",
						"z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s",
						"t", "u", "f", "kh", "'", "y", "'", "e", "je", "ji"];

				for (var i = 0, len = cyr.length; i < len; i++) {
					string = string.replace(new RegExp(cyr[i], 'g'), lat[i]);
				}
				string = string.replace(
						/([qwrtpsdfghklzxcvbnmQWRTPSDFGHKLZXCVBNM]+)[jJ]e/g,
						"$1e");
				string = string.replace(
						/([qwrtpsdfghklzxcvbnmQWRTPSDFGHKLZXCVBNM]+)[jJ]/g,
						"$1'");
				string = string.replace(/([eyuioaEYUIOA]+)[Kk]h/g, "$1h");
				string = string.replace(/^kh/g, "h");
				string = string.replace(/^Kh/g, "H");
				string = string.replace(/[^a-zA-Z0-9_\.!?&']/g, "_");
				string = string.replace(/\n+/g, "_");

				return string;
			},
			
			decline : function(original_num, ends_with_zero_five_six_seven_eight_nine, eleven_hundred_eleven, one, twelve_thirteen_fourteen_hundred_twelve_hundred_thirteen_hundred_fourteen, two_three_four) {
			    var prefix = this;
            	var suffix = '';
            	var num = original_num + '';
            	var last = num.substr(num.length - 1, num.length).toInt();
            	var twolast = num.substr(num.length - 2, num.length).toInt();
            	switch (last) {
            		case 0 :
            		case 5 :
            		case 6 :
            		case 7 :
            		case 8 :
            		case 9 :
            		    // все, что заканчивается на 0, 5, 6, 7, 8, 9
            			suffix = ends_with_zero_five_six_seven_eight_nine;
            			break;
            		case 1 :
            			if (twolast > 10 && twolast <= 14) {
            			    // 11, 111...
            				suffix = eleven_hundred_eleven;
            			} else {
            			    // 1
            				suffix = one;
            			}
            			break;
            		case 2 :
            		case 3 :
            		case 4 :
            			if (twolast > 10 && twolast <= 14) {
            			    // 12, 13, 14, 112, 113, 114...
            				suffix = twelve_thirteen_fourteen_hundred_twelve_hundred_thirteen_hundred_fourteen;
            			} else {
            			    // 2, 3, 4
            				suffix = two_three_four;
            			}
            			break;
            	}
            	return prefix + suffix;
			}
		});

Function.implement({
			/**
			 * @description Debounces function
			 * @param {Number}
			 *            threshold
			 * @param {Boolean}
			 *            execAsap
			 * @return {Function}
			 */
			debounce : function(threshold, execAsap) {
				var func = this, timeout;

				return function debounced() {
					var obj = this, args = arguments;
					function delayed() {
						if (!execAsap) {
							func.run(args, obj);
						}
						timeout = null;
					}

					if (timeout) {
						$clear(timeout);
					} else if (execAsap) {
						func.run(args, obj);
					}

					timeout = delayed.delay(threshold || 100);
				}
			}
		});

Number.implement({
	/**
	 * 
	 * @param {String}
	 *            c количество знаком после запятой
	 * @param {String}
	 *            d десятичный разделитель (запятая, например)
	 * @param {String}
	 *            t тысячный разделитель 100 000 000
	 * @return {String} форматированное число
	 */
	formatMoney : function(c, d, t) {
		var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined
				? ","
				: d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math
				.abs(+n || 0).toFixed(c))
				+ "", j = (j = i.length) > 3 ? j % 3 : 0;
		return s + (j ? i.substr(0, j) + t : "")
				+ i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t)
				+ (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
	}
});

function $get(key, url) {
	if (arguments.length < 2)
		url = location.href;
	if (arguments.length > 0 && $type.string(key) && key != "") {
		if (key == "#") {
			var regex = new RegExp("[#]([^$]*)");
		} else if (key == "?") {
			var regex = new RegExp("[?]([^#$]*)");
		} else {
			var regex = new RegExp("[?&]" + key + "=([^&#]*)");
		}
		var results = regex.exec(url);
		return (results == null) ? "" : results[1];
	} else {
		url = url.split("?");
		var results = {};
		if (url.length > 1) {
			url = url[1].split("#");
			if (url.length > 1)
				results["hash"] = url[1];
			url[0].split("&").each(function(item, index) {
						item = item.split("=");
						results[item[0]] = item[1];
					});
		}
		return results;
	}
}

/**
 * @description Обработчик событий вешается на элемент управления формой и
 *              запрещает вводить ничего, кроме цифр
 * 
 * @param {Event}
 *            e Событие
 */
function justNumber(e) {
	var event = new Event(e);
	// коды клавиш, печатающих цифры
	var number_key_codes = [48, 57].range().extend([96, 105].range()).extend([
			8, 9, 13, 17, 18, 37, 39, 46, 116]);

	if (!number_key_codes.contains(event.code) && !event.meta) {
		event.stop();
	}
}

/**
 * @description Активирует и деактивирует все сабмиты
 * 
 * @param {Boolean}
 *            pos Активировать все сабмиты или деактивировать
 */

var disableSubmits = null;

// скроллер окошка
var windowScroller;

window.addEvent('domready', function() {
			var forms = $$('form');
			var submits = $$('input[type=submit], button[type=submit], input[type=image]');
			disableSubmits = (function() {
				return function(pos) {
					$each(submits, function(subm) {
						if (pos) {
							subm.disabled = true;
						} else {
							subm.disabled = false;
						}
					});
				};
			})();

			
			forms.addEvent('submit', function() {
			    if (!this.hasClass('always-submit')) {
			        disableSubmits(true);
			    };
			});

			// скролл страницы
			if (Fx.Scroll) {
				windowScroller = new Fx.Scroll($(window), {
					duration: 200
				});
			} else {
				windowScroller = {
					start: function() {
						alert('Подключи mootools.more!');
					}
				};
			};
	
			// класс disabled
			$each($$('.disabled'), function(item){
				item.disabled = true;
			});

			// добавляем валидатор динамически
			if ($$('.vform').length) {
				var script = new Element('script', {
					type: 'text/javascript',
					src: '/js/lib/form.validator.js'
				}).inject($(document.body));
			};

		});

/**
 * При выгрузке страницы енэйблим сабмиты обратно, чтобы нажатие "назад" не
 * приводило к показу страниц с отсутствующими сабмитами
 */
window.addEvent('unload', function() {
			disableSubmits(false);
		});

// заглушка на консоль
if (!window.console) {
    window.console = {
        log: function(){}
    };
}

(function(global) {

	var $ = global.document.id || global.$;
	var isIE6 = Browser.Engine.trident4; // better compression and faster

	var BgIframe = new Class({
		Implements : Options,
		options : {
			top : 'auto',
			left : 'auto',
			width : 'auto',
			height : 'auto',
			opacity : true,
			src : 'javascript:false;'
		},
		initialize : function(element, options) {
			if (!isIE6)
				return;
			this.setOptions(options);
			this.element = $(element);
			var firstChild = this.element.getFirst();
			if (!(firstChild && firstChild.hasClass('bgiframe')))
				this.element.grab(document.createElement(this.render()), 'top');
		},
		toPx : function(n) {
			return isFinite(n) ? n + 'px' : n;
		},
		render : function() {
			var options = this.options;
			return '<iframe class="bgiframe" frameborder="0" tabindex="-1" src="'
					+ options.src
					+ '" '
					+ 'style="display:block;position:absolute;z-index:-1;'
					+ (options.opacity !== false
							? 'filter:alpha(opacity=\'0\');'
							: '')
					+ 'top:'
					+ (options.top == 'auto'
							? 'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')'
							: this.toPx(options.top))
					+ ';'
					+ 'left:'
					+ (options.left == 'auto'
							? 'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')'
							: this.toPx(options.left))
					+ ';'
					+ 'width:'
					+ (options.width == 'auto'
							? 'expression(this.parentNode.offsetWidth+\'px\')'
							: this.toPx(options.width))
					+ ';'
					+ 'height:'
					+ (options.height == 'auto'
							? 'expression(this.parentNode.offsetHeight+\'px\')'
							: this.toPx(options.height)) + ';' + '"/>';
		}
	});

	Element.implement('bgiframe', function(options) {
				if (isIE6)
					new BgIframe(this, options);
				return this;
			});

})(this);

Element.implement({

	tidy : function() {
		this.set('value', this.get('value').tidy());
	},

	getTextInRange : function(start, end) {
		return this.get('value').substring(start, end);
	},

	getSelectedText : function() {
		if (this.setSelectionRange)
			return this.getTextInRange(this.getSelectionStart(), this
							.getSelectionEnd());
		return document.selection.createRange().text;
	},

	getSelectedRange : function() {
		if ($defined(this.selectionStart))
			return {
				start : this.selectionStart,
				end : this.selectionEnd
			};
		var pos = {
			start : 0,
			end : 0
		};
		var range = this.getDocument().selection.createRange();
		if (!range || range.parentElement() != this)
			return pos;
		var dup = range.duplicate();
		if (this.type == 'text') {
			pos.start = 0 - dup.moveStart('character', -100000);
			pos.end = pos.start + range.text.length;
		} else {
			var value = this.get('value');
			var offset = value.length;
			dup.moveToElementText(this);
			dup.setEndPoint('StartToEnd', range);
			if (dup.text.length)
				offset -= value.match(/[\n\r]*$/)[0].length;
			pos.end = offset - dup.text.length;
			dup.setEndPoint('StartToStart', range);
			pos.start = offset - dup.text.length;
		}
		return pos;
	},

	getSelectionStart : function() {
		return this.getSelectedRange().start;
	},

	getSelectionEnd : function() {
		return this.getSelectedRange().end;
	},

	setCaretPosition : function(pos) {
		if (pos == 'end')
			pos = this.get('value').length;
		this.selectRange(pos, pos);
		return this;
	},

	getCaretPosition : function() {
		return this.getSelectedRange().start;
	},

	selectRange : function(start, end) {
		if (this.setSelectionRange) {
			this.focus();
			this.setSelectionRange(start, end);
		} else {
			var value = this.get('value');
			var diff = value.substr(start, end - start).replace(/\r/g, '').length;
			start = value.substr(0, start).replace(/\r/g, '').length;
			var range = this.createTextRange();
			range.collapse(true);
			range.moveEnd('character', start + diff);
			range.moveStart('character', start);
			range.select();
		}
		return this;
	},

	insertAtCursor : function(value, select) {
		var pos = this.getSelectedRange();
		var text = this.get('value');
		this.set('value', text.substring(0, pos.start) + value
						+ text.substring(pos.end, text.length));
		if ($pick(select, true))
			this.selectRange(pos.start, pos.start + value.length);
		else
			this.setCaretPosition(pos.start + value.length);
		return this;
	},

	insertAroundCursor : function(options, select) {
		options = $extend({
					before : '',
					defaultMiddle : '',
					after : ''
				}, options);
		var value = this.getSelectedText() || options.defaultMiddle;
		var pos = this.getSelectedRange();
		var text = this.get('value');
		if (pos.start == pos.end) {
			this.set('value', text.substring(0, pos.start) + options.before
							+ value + options.after
							+ text.substring(pos.end, text.length));
			this.selectRange(pos.start + options.before.length, pos.end
							+ options.before.length + value.length);
		} else {
			var current = text.substring(pos.start, pos.end);
			this.set('value', text.substring(0, pos.start) + options.before
							+ current + options.after
							+ text.substring(pos.end, text.length));
			var selStart = pos.start + options.before.length;
			if ($pick(select, true))
				this.selectRange(selStart, selStart + current.length);
			else
				this.setCaretPosition(selStart + text.length);
		}
		return this;
	}

});

/*
 * ---
 * 
 * description: A plugin for enabling autocomplete of a text input or textarea.
 * 
 * authors: - Fábio Miranda Costa
 * 
 * requires: - core/1.2.4: [Class.Extras, Element.Event, Element.Style] -
 * more/1.2.3.1: Element.Forms
 * 
 * license: MIT-style license
 * 
 * provides: [Meio.Autocomplete]
 * 
 * ...
 */

(function(global) {

	var $ = global.document.id || global.$;
	var browserEngine = Browser.Engine; // better compression and faster

	// Custom Events

	// thanks Jan Kassens
	$extend(Element.NativeEvents, {
				'paste' : 2,
				'input' : 2
			});
	Element.Events.paste = {
		base : (browserEngine.presto || (browserEngine.gecko && browserEngine.version < 19))
				? 'input'
				: 'paste',
		condition : function(e) {
			this.fireEvent('paste', e, 1);
			return false;
		}
	};

	// the key event that repeats
	Element.Events.keyrepeat = {
		base : (browserEngine.gecko || browserEngine.presto)
				? 'keypress'
				: 'keydown',
		condition : $lambda(true)
	};

	// Autocomplete itself

	var Meio = {};
	var globalCache;

	var keysThatDontChangeValueOnKeyUp = {
		9 : 1, // tab
		16 : 1, // shift
		17 : 1, // control
		18 : 1, // alt
		224 : 1, // command (meta onkeypress)
		91 : 1, // command (meta onkeydown)
		37 : 1, // left
		38 : 1, // up
		39 : 1, // right
		40 : 1
		// down
	};

	var encode = function(str) {
	    if (!str) {
	        return '';
	    };
		return str.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
	};

	// Temporary thing
	// more on Docs/todo.txt

	Meio.Widget = new Class({

				initialize : function() {
					this.elements = {};
				},

				addElement : function(name, obj) {
					this.elements[name] = obj;
				},

				addEventToElement : function(name, eventName, event) {
					this.elements[name].addEvent(eventName, event
									.bindWithEvent(this));
				},

				addEventsToElement : function(name, events) {
					for (eventName in events) {
						this.addEventToElement(name, eventName,
								events[eventName]);
					};
				},

				attach : function() {
					for (element in this.elements) {
						this.elements[element].attach();
					}
				},

				detach : function() {
					for (element in this.elements) {
						this.elements[element].detach();
					}
				},

				destroy : function() {
					for (element in this.elements) {
						this.elements[element]
								&& this.elements[element].destroy();
					}
				}
			});

	Meio.Autocomplete = new Class({

		Extends : Meio.Widget,

		Implements : [Options, Events],

		options : {

			delay : 200,
			minChars : 0,
			cacheLength : 20,
			selectOnTab : true,
			maxVisibleItems : 10,
			cacheType : 'shared', // 'shared' or 'own'

			filter : {
	/*
	 * its posible to pass the filters directly or by passing a type and
	 * optionaly a path.
	 * 
	 * filter: function(text, data){} formatMatch: function(text, data, i){}
	 * formatItem: function(text, data){}
	 * 
	 * or
	 * 
	 * type: 'startswith' or 'contains' // can be any defined on the
	 * Meio.Autocomplete.Filter object path: 'a.b.c' // path to the text value
	 * on each object thats contained on the data array
	 */
	}		,

			/*
			 * onNoItemToList: function(elements){}, onSelect:
			 * function(elements, value){}, onDeselect: function(elements){}, on
			 */

			fieldOptions : {}, // see Element options
			listOptions : {}, // see List options
			requestOptions : {}, // see DataRequest options
			urlOptions : {}
			// see URL options

		},

		initialize : function(input, data, options, listInstance) {
			this.parent();
			this.setOptions(options);
			this.active = 0;

			this.filters = Meio.Autocomplete.Filter.get(this.options.filter);

			this.addElement('list', listInstance
							|| new Meio.Element.List(this.options.listOptions));
			this.addListEvents();

			this.addElement('field', new Meio.Element.Field(input,
							this.options.fieldOptions));
			this.addFieldEvents();

			this.addSelectEvents();

			this.attach();
			this.initCache();
			this.initData(data);
		},

		addFieldEvents : function() {
			this.addEventsToElement('field', {
						'beforeKeyrepeat' : function(e) {
							this.active = 1;
							var e_key = e.key, list = this.elements.list;
							if (e_key == 'up' || e_key == 'down'
									|| (e_key == 'enter' && list.showing))
								e.preventDefault();
						},
						'delayedKeyrepeat' : function(e) {
							var e_key = e.key, field = this.elements.field;
							field.keyPressControl[e_key] = true;
							switch (e_key) {
								case 'up' :
								case 'down' :
									this.focusItem(e_key);
									break;
								case 'enter' :
									this.setInputValue();
									break;
								case 'tab' :
									if (this.options.selectOnTab)
										this.setInputValue();
									field.keyPressControl[e_key] = false; // tab
									// blurs
									// the
									// input
									// so
									// the
									// keyup
									// event
									// wont
									// happen
									// at
									// the
									// same
									// input
									// you
									// made
									// a
									// keydown
									break;
								case 'esc' :
									this.elements.list.hide();
									break;
								default :
									this.setupList();
							}
							this.oldInputedText = field.node.get('value');
						},
						'keyup' : function(e) {
							var field = this.elements.field;
							if (!keysThatDontChangeValueOnKeyUp[e.code]) {
								if (!field.keyPressControl[e.key])
									this.setupList();
								field.keyPressControl[e.key] = false;
							}
						},
						'focus' : function() {
							this.active = 1;
							var list = this.elements.list;
							list.focusedItem = null;
							list.positionNextTo(this.elements.field.node);
						},
						'click' : function() {
							if (/*this.active++ > 1 && */!this.elements.list.showing) {
								this.forceSetupList();
							}
						},
						'blur' : function(e) {
							this.active = 0;
							var list = this.elements.list;
							if (list.shouldNotBlur) {
								this.elements.field.node
										.setCaretPosition('end');
								list.shouldNotBlur = false;
								if (list.focusedItem)
									list.hide();
							} else {
								list.hide();
							}
						},
						'paste' : function() {
							return this.setupList();
						}
					});
		},

		addListEvents : function() {
			this.addEventsToElement('list', {
						'mousedown' : function(e) {
							if (this.active && !e.dontHide)
								this.setInputValue();
						}
					});
		},

		update : function() {
			var text = this.inputedText, data = this.data, options = this.options, list = this.elements.list;
			var filter = this.filters.filter, formatMatch = this.filters.formatMatch, formatItem = this.filters.formatItem;
			var cacheKey = data.getKey(), cached = this.cache.get(cacheKey), html;
			if (cached) {
				html = cached.html;
				this.itemsData = cached.data;
			} else {
				data = data.get();
				var itemsHtml = [], itemsData = [], classes = list.options.classes;
				for (var row, i = 0, n = 0; row = data[i++];) {
					if (filter.call(this, text, row)) {
						itemsHtml.push('<li title="', encode(formatMatch.call(
										this, text, row)), '" data-index="', n,
								'" class="', (n % 2
										? classes.even
										: classes.odd), '">', formatItem.call(
										this, text, row, n), '</li>');
						itemsData.push(row);
						n++;
					}
				}
				html = itemsHtml.join('');
				this.cache.set(cacheKey, {
							html : html,
							data : itemsData
						});
				this.itemsData = itemsData;
			}
			list.focusedItem = null;
			this.fireEvent('deselect', [this.elements]);
			list.list.set('html', html);
			if (this.options.maxVisibleItems)
				list.applyMaxHeight(this.options.maxVisibleItems);
		},

		setupList : function() {
			this.inputedText = this.elements.field.node.get('value');
			if (this.inputedText !== this.oldInputedText) {
				this.forceSetupList(this.inputedText);
			} else {
				this.elements.list.hide();
			}
			return true;
		},

		forceSetupList : function(inputedText) {
			inputedText = inputedText || this.elements.field.node.get('value');
			if (inputedText.length >= this.options.minChars) {
				$clear(this.prepareTimer);
				this.prepareTimer = this.data.prepare.delay(this.options.delay,
						this.data, this.inputedText);
			}
		},

		dataReady : function() {
			this.update();
			if (this.onUpdate) {
				this.onUpdate();
				this.onUpdate = null;
			}
			var list = this.elements.list;
			if (list.list.get('html')) {
				if (this.active)
					list.show();
			} else {
				this.fireEvent('noItemToList', [this.elements]);
				list.hide();
			}
			this.fireEvent('success');
		},

		setInputValue : function() {
			var list = this.elements.list;
			if (list.focusedItem) {
				var text = list.focusedItem.get('title');
				this.elements.field.node.set('value', text);
				var index = list.focusedItem.get('data-index');
				this.fireEvent('select', [this.elements, this.itemsData[index],
								text, index]);
			}
			list.hide();
		},

		focusItem : function(direction) {
			var list = this.elements.list;
			if (list.showing) {
				list.focusItem(direction);
			} else {
				this.forceSetupList();
				this.onUpdate = function() {
					list.focusItem(direction);
				};
			}
		},

		addSelectEvents : function() {
			this.addEvents({
						select : function(elements) {
							elements.field.addSelectedClass();
						},
						deselect : function(elements) {
							elements.field.removeSelectedClass();
						}
					});
		},

		initData : function(data) {
			this.data = ($type(data) == 'string')
					? new Meio.Autocomplete.Data.Request(data, this.cache,
							this.elements.field, this.options.requestOptions,
							this.options.urlOptions)
					: new Meio.Autocomplete.Data(data, this.cache);
			this.data.addEvent('ready', this.dataReady.bind(this));
			this.data.addEvent('start', this.requestStart.bind(this));
			this.data.addEvent('beforerequest', this.requestBeforerequest.bind(this));
		},
		
		requestBeforerequest : function() {
		    this.fireEvent('beforerequest');
		},

		requestStart : function() {
			this.fireEvent('request');
		},

		initCache : function() {
			var cacheLength = this.options.cacheLength;
			if (this.options.cacheType == 'shared') {
				this.cache = globalCache;
				this.cache.setMaxLength(cacheLength);
			} else { // 'own'
				this.cache = new Meio.Autocomplete.Cache(cacheLength);
			}
		},

		refreshCache : function(cacheLength) {
			this.cache.refresh();
			this.cache.setMaxLength(cacheLength || this.options.cacheLength);
		},

		refreshAll : function(cacheLength, urlOptions) {
			// TODO, do you really need to refresh the url? see a better way of
			// doing this
			this.refreshCache(cacheLength);
			this.data.refreshKey(urlOptions);
		}

	});

	// This is the same autocomplete class but it acts like a normal select
	// element.
	// When you select an option from the autocomplete it will set the value of
	// a given element (valueField)
	// with the return of the valueFilter.
	// if the syncAtInit option is set to true, it will synchonize the value of
	// the autocomplete with the corresponding data
	// from the valueField's value.
	// to understand better see the user specs.

	Meio.Autocomplete.Select = new Class({

		Extends : Meio.Autocomplete,

		options : {
			syncName : 'id', // if falsy it wont sync at start
			valueField : null,
			valueFilter : function(data) {
				return data.id;
			}
		},

		firstCall : true,

		// overwritten
		initialize : function(input, data, options, listInstance) {
			this.parent(input, data, options, listInstance);
			this.valueField = $(this.options.valueField);

			if (!this.valueField)
				return;

			if (this.options.syncName) {
				this.syncWithValueField(data);
			}

			this.addValueFieldEvents();
		},

		addValueFieldEvents : function() {
			var obj = this;
			this.addEvents({
						'select' : function(elements, data) {
							this.valueField.set('value',
									this.options.valueFilter.call(this, data));
						},
						'deselect' : function(elements) {
							if (!obj.firstCall) {
								this.valueField.set('value', '');
							} else {
								obj.firstCall = false;
							}
						}
					});
		},

		syncWithValueField : function(data) {
			var value = this.getValueFromValueField();

			if (!value)
				return;

			this.addParameter(data);
			this.addDataReadyEvent(value);

			this.data.prepare(this.elements.field.node.get('value'));
		},

		addParameter : function(data) {
			this.parameter = {
				name : this.options.syncName,
				value : function() {
					return this.valueField.value;
				}.bind(this)
			};
			if (this.data.url)
				this.data.url.addParameter(this.parameter);
		},

		addDataReadyEvent : function(value) {
			var self = this;
			this.data.addEvent('ready', function runOnce() {
				var values = this.get();
				for (var i = values.length; i--;) {
					if (self.options.valueFilter.call(self, values[i]) == value) {
						self.elements.field.node.set('value',
								self.filters.formatMatch.call(self, '',
										values[i], 0));
					}
				}
				if (this.url)
					this.url.removeParameter(self.parameter);
				this.removeEvent('ready', runOnce);
			});
		},

		getValueFromValueField : function() {
			return this.valueField.get('value');
		}

	});

	// Transforms a select on an autocomplete field

	Meio.Autocomplete.Select.One = new Class({

		Extends : Meio.Autocomplete.Select,

		options : {
			filter : {
				path : 'text' // path to the text value on each object thats
				// contained on the data array
			}
		},

		// overwritten
		initialize : function(select, options, listInstance) {
			this.select = $(select);
			this.replaceSelect();
			this.parent(this.field, this.createDataArray(), $merge(options, {
								valueField : this.select,
								valueFilter : function(data) {
									return data.value;
								}
							}), listInstance);
		},

		replaceSelect : function() {
			var selectedOption = this.select.getSelected()[0];
			this.field = new Element('input', {
						type : 'text'
					});
			var optionValue = selectedOption.get('value');
			if ($chk(optionValue))
				this.field.set('value', selectedOption.get('html'));
			this.select.setStyle('display', 'none');
			this.field.inject(this.select, 'after');
		},

		createDataArray : function() {
			var selectOptions = this.select.options, data = [];
			for (var i = 0, selectOption, optionValue; selectOption = selectOptions[i++];) {
				optionValue = selectOption.value;
				if ($chk(optionValue))
					data.push({
								value : optionValue,
								text : selectOption.innerHTML
							});
			}
			return data;
		},

		addValueFieldEvents : function() {
			this.addEvents({
				'select' : function(elements, data, text, index) {
					var option = this.valueField.getElement('option[value="'
							+ this.options.valueFilter.call(this, data) + '"]');
					if (option)
						option.selected = true;
				},
				'deselect' : function(elements) {
					var option = this.valueField.getSelected()[0];
					if (option)
						option.selected = false;
				}
			});
		},

		getValueFromValueField : function() {
			return this.valueField.getSelected()[0].get('value');
		}

	});

	Meio.Element = new Class({

				Implements : [Events],

				initialize : function(node) {
					this.setNode(node);
					this.createBoundEvents();
					this.attach();
				},

				setNode : function(node) {
					this.node = node ? $(node) || $$(node)[0] : this.render();
				},

				createBoundEvents : function() {
					this.bound = {};
					this.boundEvents.each(function(evt) {
								this.bound[evt] = function(e) {
									this.fireEvent('before' + evt.capitalize(),
											e);
									this[evt] && this[evt](e);
									this.fireEvent(evt, e);
									return true;
								}.bindWithEvent(this);
							}, this);
				},

				attach : function() {
					for (e in this.bound) {
						this.node.addEvent(e, this.bound[e]);
					}
				},

				detach : function() {
					for (e in this.bound) {
						this.node.removeEvent(e, this.bound[e]);
					}
				},

				toElement : function() {
					this.node;
				},

				render : $empty

			});

	Meio.Element.Field = new Class({

				Extends : Meio.Element,

				Implements : [Options],

				options : {
					classes : {
						loading : 'ma-loading',
						selected : 'ma-selected'
					}
				},

				initialize : function(field, options) {
					this.keyPressControl = {};
					this.boundEvents = ['paste', 'focus', 'blur', 'click',
							'keyup', 'keyrepeat'];
					if (browserEngine.trident4)
						this.boundEvents.push('keypress'); // yeah super ugly,
					// but what can be
					// awesome with ie?
					this.setOptions(options);
					this.parent(field);

					$(global).addEvent('unload', function() {
						if (this.node)
							this.node.set('autocomplete', 'on'); // if
							// autocomplete
							// is
							// off
							// when
							// you
							// reload
							// the
							// page
							// the
							// input
							// value
							// gets
							// erased
						}.bind(this));
				},

				setNode : function(element) {
					this.parent(element);
					this.node.set('autocomplete', 'off');
				},

				// this let me get the value of the input on keydown and
				// keypress
				keyrepeat : function(e) {
					$clear(this.keyrepeatTimer);
					this.keyrepeatTimer = this._keyrepeat.delay(1, this, e);
				},

				_keyrepeat : function(e) {
					this.fireEvent('delayedKeyrepeat', e);
				},

				destroy : function() {
					this.detach();
					this.node.removeAttribute('autocomplete');
				},

				addLoadingClass : function() {
					this.node.addClass(this.options.classes.loading);
				},

				removeLoadingClass : function() {
					this.node.removeClass(this.options.classes.loading);
				},

				addSelectedClass : function() {
					this.node.addClass(this.options.classes.selected);
				},

				removeSelectedClass : function() {
					this.node.removeClass(this.options.classes.selected);
				},

				// ie6 only, uglyness
				// this fix the form being submited on the press of the enter
				// key
				keypress : function(e) {
					if (e.key == 'enter')
						this.bound.keyrepeat(e);
				}

			});

	Meio.Element.List = new Class({

		Extends : Meio.Element,

		Implements : [Options],

		options : {
			width : 'field', // you can pass any other value settable by
			// set('width') to the list container
			classes : {
				container : 'ma-container',
				hover : 'ma-hover',
				odd : 'ma-odd',
				even : 'ma-even'
			}
		},

		initialize : function(options) {
			this.boundEvents = ['mousedown', 'mouseover'];
			this.setOptions(options);
			this.parent();
			this.focusedItem = null;
		},

		applyMaxHeight : function(maxVisibleItems) {
			var listChildren = this.list.childNodes;
			var node = listChildren[maxVisibleItems - 1]
					|| (listChildren.length ? listChildren[listChildren.length
							- 1] : null);
			if (!node)
				return;
			node = $(node);
			// uggly hack to fix the height of the autocomplete list
			// TODO rethink about it
			for (var i = 2; i--;)
				this.node.setStyle('height',
						node.getCoordinates(this.list).bottom);
		},

		mouseover : function(e) {
			var item = this.getItemFromEvent(e), hoverClass = this.options.classes.hover;
			if (!item)
				return true;
			if (this.focusedItem)
				this.focusedItem.removeClass(hoverClass);
			item.addClass(hoverClass);
			this.focusedItem = item;
			this.fireEvent('focusItem', [this.focusedItem]);
		},

		mousedown : function(e) {
			e.preventDefault();
			this.shouldNotBlur = true;
			if (!(this.focusedItem = this.getItemFromEvent(e))) {
				e.dontHide = true;
				return true;
			}
			this.focusedItem.removeClass(this.options.classes.hover);
		},

		focusItem : function(direction) {
			var hoverClass = this.options.classes.hover, newFocusedItem;
			if (this.focusedItem) {
				if ((newFocusedItem = this.focusedItem[direction == 'up'
						? 'getPrevious'
						: 'getNext']())) {
					this.focusedItem.removeClass(hoverClass);
					newFocusedItem.addClass(hoverClass);
					this.focusedItem = newFocusedItem;
					this.scrollFocusedItem(direction);
				}
			} else {
				if ((newFocusedItem = this.list.getFirst())) {
					newFocusedItem.addClass(hoverClass);
					this.focusedItem = newFocusedItem;
				}
			}
		},

		scrollFocusedItem : function(direction) {
			var focusedItemCoordinates = this.focusedItem
					.getCoordinates(this.list), scrollTop = this.node.scrollTop;
			if (direction == 'down') {
				var delta = focusedItemCoordinates.bottom
						- this.node.getStyle('height').toInt();
				if ((delta - scrollTop) > 0) {
					this.node.scrollTop = delta;
				}
			} else {
				var top = focusedItemCoordinates.top;
				if (scrollTop && scrollTop > top) {
					this.node.scrollTop = top;
				}
			}
		},

		getItemFromEvent : function(e) {
			var target = e.target;
			while (target && target.tagName != 'LI') {
				if (target === this.node)
					return null;
				target = target.parentNode;
			}
			return $(target);
		},

		render : function() {
			var node = new Element('div', {
						'class' : this.options.classes.container
					});
			if (node.bgiframe)
				node.bgiframe({
							top : 0,
							left : 0
						});
			this.list = new Element('ul').inject(node);
			$(document.body).grab(node);
			return node;
		},

		positionNextTo : function(fieldNode) {
			var width = this.options.width, listNode = this.node;
			var elPosition = fieldNode.getCoordinates();
			listNode.setStyle('width', width == 'field'
							? fieldNode.getWidth().toInt()
									- listNode.getStyle('border-left-width')
											.toInt()
									- listNode.getStyle('border-right-width')
											.toInt()
							: width);
			listNode.setPosition({
						x : elPosition.left,
						y : elPosition.bottom
					});
		},

		show : function() {
			this.node.scrollTop = 0;
			this.node.setStyle('visibility', 'visible');
			this.showing = true;
		},

		hide : function() {
			this.showing = false;
			this.node.setStyle('visibility', 'hidden');
		}

	});

	Meio.Autocomplete.Filter = {

		filters : {},

		get : function(options) {
			var type = options.type, keys = (options.path || '').split('.');
			var filters = (type && this.filters[type]) ? this.filters[type](
					this, keys) : options;
			return $merge(this.defaults(keys), filters);
		},

		define : function(name, options) {
			this.filters[name] = options;
		},

		defaults : function(keys) {
			var self = this;
			return {
				filter : function(text, data) {
					return text ? self._getValueFromKeys(data, keys)
							.test(new RegExp(text.escapeRegExp(), 'i')) : true;
				},
				formatMatch : function(text, data) {
					return self._getValueFromKeys(data, keys);
				},
				formatItem : function(text, data, i) {
					return text ? self._getValueFromKeys(data, keys).replace(
							new RegExp('(' + text.escapeRegExp() + ')', 'gi'),
							'<strong>$1</strong>') : self._getValueFromKeys(
							data, keys);
				}
			};
		},

		_getValueFromKeys : function(obj, keys) {
			var key, value = obj;
			for (var i = 0; key = keys[i++];)
				value = value[key];
			return value;
		}

	};

	Meio.Autocomplete.Filter.define('contains', function(self, keys) {
				return {};
			});
	Meio.Autocomplete.Filter.define('startswith', function(self, keys) {
				return {
					filter : function(text, data) {
						return text
								? self._getValueFromKeys(data, keys)
										.test(new RegExp('^'
														+ text.escapeRegExp(),
												'i'))
								: true;
					}
				};
			});

	Meio.Autocomplete.Data = new Class({

				Implements : [Options, Events],

				initialize : function(data, cache) {
					this._cache = cache;
					this.data = data;
					this.dataString = JSON.encode(this.data);
				},

				get : function() {
					return this.data;
				},

				getKey : function() {
					return this.cachedKey;
				},

				prepare : function(text) {
					this.cachedKey = this.dataString + (text || '');
					this.fireEvent('ready');
				},

				cache : function(key, data) {
					this._cache.set(key, data);
				},

				refreshKey : $empty

			});

	Meio.Autocomplete.Data.Request = new Class({

				Extends : Meio.Autocomplete.Data,

				options : {
					noCache : true
				},
				
				_class: 'Meio.Autocomplete.Data.Request',

				initialize : function(url, cache, element, options, urlOptions) {
					this.setOptions(options);
					this.rawUrl = url;
					this._cache = cache;
					this.element = element;
					this.urlOptions = urlOptions;
					this.refreshKey();
					this.createRequest();
				},

				prepare : function(text) {
				    this.fireEvent('beforerequest');
					this.cachedKey = this.url.evaluate(text);
					if (this._cache.has(this.cachedKey)) {
						this.fireEvent('ready');
					} else {
						this.request.send({
									url : this.cachedKey
								});
					}
				},

				createRequest : function() {
					var self = this;
					this.request = new Request.JSON(this.options);
					this.request.addEvents({
								request : function() {
									self.element.addLoadingClass();
									self.fireEvent('start');
								},
								complete : function() {
									self.element.removeLoadingClass();
								},
								success : function(jsonResponse) {
									self.data = jsonResponse.data.list;
									self.fireEvent('ready');
								}
							});
				},

				refreshKey : function(urlOptions) {
					urlOptions = $merge(this.urlOptions, {
								url : this.rawUrl
							}, urlOptions || {});
					this.url = new Meio.Autocomplete.Data.Request.URL(urlOptions.url, urlOptions);
				}

			});

	Meio.Autocomplete.Data.Request.URL = new Class({

				Implements : [Options],

				options : {
					extraParams : null,
					max : 20,
					namedParameters : {}
				},

				initialize : function(url, options) {
					this.setOptions(options);
					this.rawUrl = url;
					this.url = url;
					this.url += this.url.contains('?') ? '&' : '?';
					this.dynamicExtraParams = [];
					var params = $splat(this.options.extraParams);
					for (var i = params.length; i--;) {
						this.addParameter(params[i]);
					}
					if (this.options.max)
						this.addParameter('limit=' + this.options.max);
				},

				evaluate : function(text) {
					text = text || '';
					var params = this.dynamicExtraParams, url = [];
					url.push('q=' + encodeURIComponent(text));
					for (var i = params.length; i--;) {
						url.push(encodeURIComponent(params[i].name) + '=' + encodeURIComponent($lambda(params[i].value)()));
					}
					var namedUrl = '';
					for (var i in this.options.namedParameters) {
					    namedUrl += encodeURIComponent(i) + '=' + encodeURIComponent(this.options.namedParameters[i]) + '&';
					}
					return this.url + namedUrl + url.join('&');
				},

				addParameter : function(param) {
					if (isFinite(param.nodeType) || $type(param.value) == 'function') {
						this.dynamicExtraParams.push(param);
					} else {
						this.url += (($type(param) == 'string') ? param : encodeURIComponent(param.name) + '=' + encodeURIComponent(param.value)) + '&';
					}
				},

				// TODO remove non dynamic parameters
				removeParameter : function(param) {
					this.dynamicExtraParams.erase(param);
				},
                
                addNamedParameter : function(paramName, paramValue) {
                    this.options.namedParameters[paramName] = paramValue;
                },
                
                removeNamedParameter : function(paramName) {
                    delete this.options.namedParameters[paramName];
                }
			});

	Meio.Autocomplete.Cache = new Class({

				initialize : function(maxLength) {
					this.refresh();
					this.setMaxLength(maxLength);
				},

				set : function(key, value) {
					if (!this.cache[key]) {
						if (this.getLength() >= this.maxLength) {
							var keyToRemove = this.pos.shift();
							this.cache[keyToRemove] = null;
							delete this.cache[keyToRemove];
						}
						this.cache[key] = value;
						this.pos.push(key);
					}
					return this;
				},

				get : function(key) {
					return this.cache[key || ''] || null;
				},

				has : function(key) {
					return !!this.get(key);
				},

				getLength : function() {
					return this.pos.length;
				},

				refresh : function() {
					this.cache = {};
					this.pos = [];
				},

				setMaxLength : function(maxLength) {
					this.maxLength = Math.max(maxLength, 1);
				}

			});

	globalCache = new Meio.Autocomplete.Cache();

	if ($defined(global.Meio))
		$extend(global.Meio, Meio);
	else
		global.Meio = Meio;

})(this);

var current_order_id;

var OrderForm = function(id) {
    
    var container = $(id);
    var form = container.getElement('form.js-personal-form');
    var callbackForm = container.getElement('form.js-callback-form');
    var overlay = new Element('div');
    var title = container.getElement('h3');
    var logoTd = container.getElement('.logo');
    var logo = logoTd.getFirst();
    var percentTd = container.getElement('.percent');
    var percent = percentTd.getFirst();
    var fee = container.getElement('.sum');
    var hiddenField = container.getElement('input[name=calculator_data]');
    var ajax = container.getElement('.ajax');
    var submitButton = container.getElement('#order-order-order');
    var formTable = container.getElement('table.form');
    var successMessage = container.getElement('.order-success');
    
    // условия
    var carCostCondition = container.getElement('.price-c');
    var deductibleCondition = container.getElement('.franchise-c');
    var compensationCondition = container.getElement('.compensation-c');
    var avarcomCondition = container.getElement('.avarcom-c');
    var windshieldCondition = container.getElement('.windshield-c');
    var evacuatorCondition = container.getElement('.evacuator-c');
    var conditionBlocks = [carCostCondition, deductibleCondition, compensationCondition, avarcomCondition, windshieldCondition, evacuatorCondition];
    
    var companyTitle;
    var calculatorData = null;
    
    var nameField = container.getElement('#order-name');
    var nameLabel = nameField.getParent().getPrevious();
    var phoneField = container.getElement('#order-phone');
    var phoneLabel = phoneField.getParent().getPrevious();
    var osagoField = container.getElement('#order-company-field');
    
    if (window.Meio && Meio.Mask) {
        phoneField.meiomask('Fixed', 'Phone-us', {autoSetSize: true});
    };
    
    var orderCallLink = container.getElement('#order-call-link');
    var buyLink = container.getElement('td.button a');
    
    // главная форма, откуда дёргаются данные
    var sourceForm = null;
    
    // таблица условий
    var resultTable = container.getElement('.detailed-result');
    
    var self = this;
    this.$events = {};
    
    this.addEvent = function(type, fn, internal){
		type = Events.removeOn(type);
		if (fn != $empty){
			this.$events[type] = this.$events[type] || [];
			this.$events[type].include(fn);
			if (internal) fn.internal = true;
		}
		return this;
	};

    this.removeEvent = function(type, fn){
		type = Events.removeOn(type);
		if (!this.$events[type]) return this;
		if (!fn.internal) this.$events[type].erase(fn);
		return this;
	};
	
	var fireEvent = function(type, args, delay){
		type = Events.removeOn(type);
		if (!self.$events || !self.$events[type]) return this;
		self.$events[type].each(function(fn){
			fn.create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	};
    
    var overlayOffset = -28;
    
    var fx = new Fx.Elements([container, overlay], {
        duration: 150,
        onStart: function() {
            fxing = true;
        },
        onComplete: function() {
            hidden = !hidden;
            
            if (hidden) {
                fireEvent('close');
                //window.removeEvent('mousewheel', onWindowScrollStop);
                clear();
                middleTr.hide();
                inputs[0].set('value', '');
                inputs[1].set('value', '');
                submitButton.show();
                ajax.hide();
                formTable.show();
                successMessage.hide();
                /*conditionBlocks.each(function(cb) {
                    cb.hide().getLast().empty();
                });*/
            } else {
                fireEvent('open');
                //window.addEvent('mousewheel', onWindowScrollStop);
            };
            
            fxing = false;
        }
    });
    var fxing = false;
    var hidden = true;
    
    var closeLink = container.getElement('a.close');
    closeLink.addEvent('click', function(e) {
        var event = new Event(e);
        event.stop();
        self.hide();
    });
    
    var middleTr = container.getElement('tr.middle');
    var osagoTr = container.getElement('tr.osago')
    var inputs = middleTr.getElements('input[type=text]');
    
    function onCallLinkClick(e) {
        var event = new Event(e);
        event.stop();
            
        if (middleTr.isVisible()) {
            middleTr.hide();
            osagoTr.hide();
            osagoTr.getElement('select').disabled = true;
            inputs[0].set('value', '');
            inputs[1].set('value', '');
        } else {
            middleTr.show();
            inputs[0].focus();
            if (calculatorData.osago || calculatorData.only_osago) {
                osagoTr.getElement('select').disabled = false;
                osagoTr.show();
            };
        };
    };
    
    orderCallLink.addEvent('click', onCallLinkClick);
    buyLink.addEvent('click', function(e) {
        windowScroller.toElement(form);
        onCallLinkClick.call(this, e);
    });
    
    var request = new Request.JSON({
		method: 'post',
        url: form.get('action'),
        onRequest: function() {
            nameField.disabled = true;
            phoneField.disabled = true;
            requesting = true;
            _gaq.push(['_trackEvent', 'calc', 'forma_zakaza_nachala_otpravku']);
        },
        onSuccess: function(json) {
            if (json.success) {
                nameField.disabled = false;
                phoneField.disabled = false;
                formTable.hide();
                
                var when = (function() {
                    var d = new Date();
                    var minutes = d.getMinutes();
                    var hours = d.getHours();
                    
                    if ((hours >= 9 && hours <= 19) || (hours == 20 && minutes == 0)) {
                        return 'в течение 30-и минут.';
                    } else {
                        return 'утром.';
                    };
                    
                })();
                
                successMessage.getElement('.name').set('html', nameField.get('value').trim());
                successMessage.getElement('.when').set('html', when);
                successMessage.show();
                
                _gaq.push(['_trackEvent', 'calc', 'zakaz_uspewno_otpravlen_na_server', json.data.order_id]);
            } else {
                _gaq.push(['_trackEvent', 'calc', 'zakaz_ne_prinyat']);
            }
            requesting = false;
        }
    });
    var requesting = false;
    
    // отправка результатов на почту
    (function() {
        if (!callbackForm) return;
        
        var logtypeInput = callbackForm.getElement('[name=logtype]');
        var resultidInput = callbackForm.getElement('[name=resultId]');
        var emailInput = callbackForm.getElement('[name=email]');
        var label = callbackForm.getElement('label');
        var mAjaxing = callbackForm.getElement('.callback-ajaxing');
        var mOk = callbackForm.getElement('.callback-ok');
        var mFail = callbackForm.getElement('.callback-fail');
        
        var ring = false;
        var r = new Request.JSON({
            url: '/calc/api/sendresult/',
            onRequest: function() {
                ring = true;
                
                emailInput.disabled = true;
                mAjaxing.show();
                mOk.hide();
                mFail.hide();
            },
            onSuccess: function(json) {
                mAjaxing.hide();
                
                if (json.success) {
                    mOk.show();
                } else {
                    mFail.show();
                };
                
                (function() {
                    mOk.hide();
                    mFail.hide();
                    emailInput.disabled = false;
                }).delay(3000);
                
                ring = false;
            },
            onFailure: function() {
                mAjaxing.hide();
                mOk.show();
                mFail.show();
                
                (function() {
                    mOk.hide();
                    mFail.hide();
                    emailInput.disabled = false;
                }).delay(3000);
                
                ring = false;
            }
        });
        
        callbackForm.addEvent('submit', function(e){
            var event = new Event(e);
            event.stop();
            
            if (ring) return;
            
            var error = false;
            var email = emailInput.get('value').trim();
            
            if (!email.length || !email.match(/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i)) {
                error = true;
                label.setStyle('color', 'red');
            } else {
                label.setStyle('color', '');
            }
            
            resultidInput.set('value', calculatorData.resultId);
            
            if (!error) {
                r.send(callbackForm.toQueryString());
            };
        });
    })();
    
    form.addEvent('submit', function(e){
	
        var event = new Event(e).stop();
        var error = false;
        
        if (requesting) return;
        
        var name = nameField.get('value').trim();
        var phone = phoneField.get('value').trim();
        var osagoCompany = osagoField.get('value');
        
        if (!name.length) {
            var error = true;
            nameLabel.setStyle('color', 'red').twitch();
        } else {
            nameLabel.setStyle('color', '');
        };
        
        if (!phone.length) {
            var error = true;
            phoneLabel.setStyle('color', 'red').twitch();
        } else {
            phoneLabel.setStyle('color', '');
        };
        
        if (!error) {
            submitButton.hide();
            ajax.show();
            
            if (calculatorData['only_osago']) {
                var q  = encodeURIComponent('order[osago][resultid]') + '=' + calculatorData.resultId + '&';
                    q += encodeURIComponent('order[osago][company]')  + '=' + osagoCompany + '&';
            } else {
                var q  = encodeURIComponent('order[kasko][resultid]') + '=' + calculatorData.resultId + '&';
            }
            q += encodeURIComponent('order[user][name]')      + '=' + encodeURIComponent(name) + '&';
            q += encodeURIComponent('order[user][phone]')     + '=' + encodeURIComponent(phone) + '&';
            if (calculatorData.osago) {
                q += encodeURIComponent('order[osago][resultid]') + '=' + calculatorData.osago.resultId + '&';
                q += encodeURIComponent('order[osago][company]')  + '=' + osagoCompany;
            }
			
			request.send(q);
            // request.send(sourceForm.toQueryString() + '&' + form.toQueryString() + '&fee=' + getFee() + '&company=' + companyTitle + ((calculatorData.osago) ? '&osago_fee=' + calculatorData.osago.data.fee : '') + '&resultid=' + current_order_id);
        } else {
            _gaq.push(['_trackEvent', 'calc', 'forma_zakaza_ne_prowla_validation']);
        }
    });
    
    var onWindowScrollStop = function(e) {
        var event = new Event(e);
        event.stop();
    };
    
    var onOverlayClick = function(e) {
        var event = new Event(e);
        event.stop();
        this.hide();
    };
    
    var onContainerClick = function(e) {
        var event = new Event(e);
        var target = $(event.target);
        
        if (target === container) {
            this.hide();
        };
    };
    
    this.setOverlay = function(el) {
        overlay = $(el);
        fx.elements[1] = overlay;
        
        // скрыватие оверлея
        overlay.addEvent('click', onOverlayClick.bindWithEvent(this));
        container.addEvent('click', onContainerClick.bindWithEvent(this));
    };
    
    this.show = function(id, data, y) {
        if (fxing) {
            return;
        };
        
        companyTitle = id;
        
        // внимание. хак
        if (!data['serviceName']) {
            data['serviceName'] = data.service;
        };
        if (!data['companyColor']) {
            data['companyColor'] = data.company_logo_color;
        };
        if (!data['companyLogo']) {
            data['companyLogo'] = data.company_logo_medium;
        };
        if (!data['percent']) {
            data['percent'] = data.data.percent;
        };
        if (!data['fee']) {
            data['fee'] = data.data.fee;
        };
        
        calculatorData = data;
        
        // зафигачить значения
        setTitle(data.serviceName, data.companyColor);
        if (!data['only_osago']) {
            // если показываем результаты не только ОСАГИ
            setLogo(data.companyLogo);
            setPercent(data.percent, data.companyColor);
            logoTd.show();
            percentTd.show();
        } else {
            logoTd.hide();
            percentTd.hide();
        };
        if (data['osago']) {
            setFee(data.fee + data.osago.data.fee);
        } else {
            setFee(data.fee);
        };
        
        if (hidden) {
            overlay.setStyles({
                top: -$(window).getScroll().y,
                height: $(window).getScrollSize().y + $(window).getScroll().y,
                opacity: 0
            }).show();
            container.setStyles({
                //top: y + overlayOffset,
                opacity: 0
            }).show();
            windowScroller.toTop();
            fx.start({
                0: {
                    opacity: 1
                },
                1: {
                    opacity: .5
                }
            });
        } else {
            container.setStyle('top', y + overlayOffset);
        };
        
        var conditions;
        switch (calculatorData.col) {
            case 1:
                resultTable.getElements('div[class^=r-] > .c, div[class^=r-] > .r').hide();
                conditions = resultTable.getElements('.l').show();
                conditions.each(function(c) {
                    if (c.getParent().get('class').match(/r\-car\-cost/)) {
                        c.getParent().getPrevious().hide();
                        return;
                    };
                    if (c.getFirst().get('html').match(/^—$/)) {
                        c.hide();
                        c.getParent().getPrevious().hide();
                    } else {
                        c.show();
                        c.getParent().getPrevious().show();
                    };
                });
                break;
            case 2:
                resultTable.getElements('.l, .r').hide();
                conditions = resultTable.getElements('div[class^=r-] > .c').show();
                conditions.each(function(c) {
                    if (c.getParent().get('class').match(/r\-car\-cost/)) {
                        c.getParent().getPrevious().hide();
                        return;
                    };
                    if (c.getFirst().get('html').match(/^—$/)) {
                        c.hide();
                        c.getParent().getPrevious().hide();
                    } else {
                        c.show();
                        c.getParent().getPrevious().show();
                    };
                });
                break;
            case 3:
                resultTable.getElements('.l, div[class^=r-] > .c').hide();
                conditions = resultTable.getElements('div.r').show();
                conditions.each(function(c) {
                    if (c.getParent().get('class').match(/r\-car\-cost/)) {
                        c.getParent().getPrevious().hide();
                        return;
                    };
                    if (c.getFirst().get('html').match(/^—$/)) {
                        c.hide();
                        c.getParent().getPrevious().hide();
                    } else {
                        c.show();
                        c.getParent().getPrevious().show();
                    };
                });
                break;
        };
        
        if (!data['only_osago']) {
            resultTable.show();
        };
    };
    
    this.hide = function() {
        if (fxing) {
            return;
        };
        
        fx.start({
            0: {
                opacity: 0
            },
            1: {
                opacity: 0
            }
        });
        
        (function() {
            fireEvent('hide');
        }).delay(150);
    };

    this.setSourceForm = function(f) {
        sourceForm = $(f);
    };

    var setTitle = function(v, c) {
        title.setStyle('color', '#' + c);
        title.set('html', v);
    };
    
    var setLogo = function(l) {
        logo.set('src', l.replace(/company/, 'company/large'));
    };
    
    var setPercent = function(p, c) {
        percent.setStyle('backgroundColor', '#' + c);
        percent.set('html', p.formatMoney(1, ',', ' ') + '%');
    };
    
    var setFee = function(f) {
        fee.set('html', f.formatMoney(0, '', ' ') + ' руб.' + ((calculatorData.osago) ? '<br /><span>(включая ОСАГО ' + calculatorData.osago.data.fee.formatMoney(0, '', ' ') + ' р.)</span>' : ''));
    };
    
    var getFee = function() {
        if (calculatorData) {
            if (calculatorData.osago) {
                return calculatorData.fee + calculatorData.osago.data.fee;
            };
            return calculatorData.fee;
        };
        return null;
    };
    
    var clear = function() {
        title.setStyle('color', '').set('html', '');
        logo.set('src', '');
        percent.setStyle('backgroundColor', '').set('html', '');
        fee.set('html', '');
        hiddenField.set('value', '');
    };

};

var Suggestive = function(i, d) {
    // событийная логика
    var self = this;
    this.$events = {};
    this.addEvent = function(type, fn, internal){
		type = Events.removeOn(type);
		if (fn != $empty){
			this.$events[type] = this.$events[type] || [];
			this.$events[type].include(fn);
			if (internal) fn.internal = true;
		};
		return this;
	};
	this.removeEvent = function(type, fn){
		type = Events.removeOn(type);
		if (!this.$events[type]) return this;
		if (!fn.internal) this.$events[type].erase(fn);
		return this;
	};
	var fireEvent = function(type, args, delay){
		type = Events.removeOn(type);
		if (!self.$events || !self.$events[type]) return this;
		self.$events[type].each(function(fn){
			fn.create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	};
	
	var input = $(i); input.set('autocomplete', 'off');
    var dropoutContainer = $(d);
    var links = dropoutContainer.getElements('a');
    var rel = '';
    var text = '';
    var alts = [];
    var containerFx = new Fx.Tween(dropoutContainer, {
        property: 'opacity',
        duration: 100
    });
    
    this.getValue = function() {
        return input.get('value').trim();
    };
    this.setValue = function(val) {
        input.set('value', val);
    };
    
    var brands = [];
    
    for (var i = 0; i < links.length; i++) {
        rel = links[i].get('rel');
        text = links[i].get('text');
        alts = [];
        if (rel) {
            alts = rel.split('|');
            alts = alts.map(function(name) {
                return name.toUpperCase();
            });
        };
        alts.push(text.toUpperCase());
        links[i].set('html', links[i].get('html') + '<span>' + text + '</span>');
        brands.push({
            element: links[i],
            names: alts,
            shadow: links[i].getFirst(),
            text: text
        });
        links[i].store('text', text);
        links[i].addEvent('click', function(e) {
            new Event(e).stop();
        });
        links[i].addEvent('mousedown', function(e) {
            new Event(e).stop();
            input.set('value', this.retrieve('text'));
            if (input.retrieve('emptytext')) {
                input.retrieve('emptytext').update();
            };
            fireEvent('change');
            containerFx.cancel();
            containerFx.start(0);
        });
    };
    
    var onInputKeyUp = function(e) {
        var val = input.get('value').trim().toUpperCase();
        var l = val.length;
        var got = false;
        var index;
        var originalName;
        var p1, p2, p3;
        var hasFullMatch = false;
        var fullMatchText = '';
        for (var i = 0; i < brands.length; i++) {
            got = brands[i].names.some(function(n) {
                var t = n.indexOf(val);
                if (t != -1 && n == val) {
                    hasFullMatch = true;
                    fullMatchText = n;
                };
                return (t != -1);
            });
            if (got) {
                originalName = brands[i].names.getLast();
                index = originalName.indexOf(val);
                if (l) {
                    if (index > -1) {
                        p1 = brands[i].text.substr(0, index);
                        p2 = brands[i].text.substr(index, l);
                        p3 = brands[i].text.substr(index + l, brands[i].text.length);
                        brands[i].shadow.set('html', p1 + '<i>' + p2 + '</i>' + p3);
                    } else {
                        brands[i].shadow.set('html', '<i>' + brands[i].text + '</i>');
                    };
                } else {
                    brands[i].shadow.set('html', '');
                };
                brands[i].element.removeClass('useless');
            } else {
                brands[i].shadow.set('html', '');
                brands[i].element.addClass('useless');
            };
        };
        
        // написали полное название и оно совпало
        if (hasFullMatch && arguments.length) {
            input.set('value', fullMatchText);
            if (input.retrieve('emptytext')) {
                input.retrieve('emptytext').update();
            };
            fireEvent('change');
            containerFx.cancel();
            containerFx.start(0);
        };
    };
    
    var onInputFocus = function(e) {
        onInputKeyUp();
        containerFx.cancel();
        containerFx.start(1);
    };
    
    var onInputBlur = function(e) {
        containerFx.cancel();
        containerFx.start(0);
    };
    
    var onDropoutContainerMouseDown = function(e) {
        var event = new Event(e);
        var target = $(event.target);
        
        if (target.get('tag').toLowerCase() != 'a') {
            input.removeEvent('blur', onInputBlur);
        };
    };
    
    var onDropoutContainerMouseUp = function(e) {
        var event = new Event(e);
        var target = $(event.target);
        
        if (target.get('tag').toLowerCase() != 'a') {
            input.focus();
            input.addEvent('blur', onInputBlur);
        };
    };
    
    containerFx.set(0);
    dropoutContainer.show();
    
    input.addEvent('keyup', onInputKeyUp.debounce(300, false));
    input.addEvent('focus', onInputFocus);
    input.addEvent('blur', onInputBlur);
    dropoutContainer.addEvent('mousedown', onDropoutContainerMouseDown);
    dropoutContainer.addEvent('mouseup', onDropoutContainerMouseUp);
};

var PopupStack = new function() {
    
    var body = null;
    
    var defaultOverlayColor = '#000000';
    var defaultOverlayOpacity = 0.7;
    var overlays = []; // {color: '#000000', opacity: 0.7, element: Element}
    var popups = {};
    
    var currentPopup = null;
    var currentPopupBelt = null;
    var currentPopupElement = null;
    var revealingPopup = null;
    var revealingPopupBelt = null;
    var revealingPopupElement = null;
    
    // обработчики события до и после перемещения попапов
    var beforeFunc = $empty;
    var afterFunc = $empty;
    
    // эффекты перехода попапов
    var revealFx = new Fx.Morph(null, {
        duration: 200,
        onStart: function() {
            revealingPopup.set('fxing', true);
        },
        onComplete: function() {
            currentPopup = revealingPopup;
            
            revealingPopup.set('hidden', false);
            revealingPopup.set('fxing', false);
            revealingPopup.onShow.call(revealingPopup);
            afterFunc();
            
            beforeFunc = $empty;
            afterFunc = $empty;
        }
    });
    var fadeFx = new Fx.Morph(null, {
        duration: 200,
        onStart: function() {
            currentPopup.set('fxing', true);
        },
        onComplete: function() {
            currentPopupBelt.hide();
            currentPopupElement.setStyles({
                top: '',
                opacity: 1
            });
            currentPopup.set('fxing', false);
            currentPopup.set('hidden', true);
            
            currentPopup.onHide.call(currentPopup);
            
            revealingPopupElement.setStyle('opacity', 0);
            revealingPopupBelt.setStyle('top', $(window).getScroll().y + revealingPopup.get('topOffset')).show();
            
            revealingPopup.onBeforeShow.call(revealingPopup);
            
            revealFx.start({
                top: [-30, 0],
                opacity: [0, 1]
            });
        }
    });
    
    // получаем попапчик
    this.getPopup = function(el) {
        var element = $(el);
        var id = element.get('id');
        
        if (!id || !id.length) {
            id = 'popup-' + $time();
            element.set('id', id);
        };
        
        var p = new popup(element);
        
        popups[id] = p;
        
        return p;
    };
    
    // получаем попап по айдишнику
    this.getPopupById = function(id) {
        return popups[id];
    };
    
    // переход в попап с другим айдишником
    // bFunc вызывается перед переходом
    // aFunc вызывается после перехода
    this.goTo = function(id, bFunc, aFunc) {
        if (!currentPopup) return;
        if (currentPopup.getId() == id) return;
        
        revealingPopup = PopupStack.getPopupById(id);
        
        if (currentPopup.get('overlay') != revealingPopup.get('overlay')) return;
        
        currentPopupBelt = currentPopup.get('elementBelt');
        currentPopupElement = currentPopup.get('element');
        revealingPopupBelt = revealingPopup.get('elementBelt');
        revealingPopupElement = revealingPopup.get('element');
        
        fadeFx.element = currentPopupElement;
        revealFx.element = revealingPopupElement;
        
        if (arguments.length >= 2) {
            beforeFunc = bFunc;
        };
        if (arguments.length == 3) {
            afterFunc = aFunc;
        };
        
        beforeFunc();
        currentPopup.onBeforeHide.call(currentPopup);
        fadeFx.start({
            top: [0, -30],
            opacity: 0
        });
    };
    
    // конструктор попапов
    var popup = function(el) {
        var self = this;
        
        
        // variables
        var overlay = null;
        var overlayOpacity;
        var element = el;
        var elementBelt = element.getParent('.popup-margins');
        var elementClosers = elementBelt.getElements('.popup-close') || [];
        var topOffset = 150;
        var fx = null;
        var fxing = false;
        var animated = false;
        var hidden = true;
        
        
        // public methods
        this.setOverlayColorAndOpacity = function(color, opacity) {
            // если уже был оверлей, то снимаем с него листенеры
            if (overlay) {
                overlay.removeEvent('click', onOverlayClick);
                overlay = null;
            };
            
            if (color.length == 3) {
                color = color + color;
            };
            if (!color.match(/^#/)) {
                color = '#' + color;
            };
            if ($type.string(opacity)) {
                opacity = opacity.toFloat();
                
            };
            overlayOpacity = opacity;
            
            overlay = getOverlayWithColorAndOpacity(color, opacity);
            if (fx) {
                fx.elements[0] = overlay;
            };
            
            initListeners();
            
            return this;
        };
        
        this.setHasAnimation = function(bool) {
            if (bool && Fx.Elements) {
                animated = true;
                if (!fx)
                    initFx();
                return this;
            };
            
            animated = false;
            
            return this;
        };
        
        this.show = function() {
            if (!elementBelt) {
                alert('Вы не указали элемент попапа!');
                return;
            };
            
            if (fxing) {
                return;
            };
            
            var config = countOverlaySize();
            overlay.setStyles(config);
            
            // расчет верхней координаты для попапа
            var y = (function() {
                
                var py = 0;
                
                var popupTopY = topOffset;
                elementBelt.setStyle('opacity', 0).setStyle('height', 0).show();
                var popupHeight = elementBelt.getFirst().getSize().y;
                var viewportHeight = window.getSize().y;
                var scrollHeight = window.getScroll().y;
                var windowHeight = window.getScrollSize().y;
                elementBelt.hide().setStyle('height', '').setStyle('opacity', '1');
                
                if ((scrollHeight + popupTopY + popupHeight) >= windowHeight) {
                    py = windowHeight - popupHeight - 5;
                    if (windowScroller) {
                        windowScroller.start(0, py - popupTopY);
                    };
                } else {
                    py = scrollHeight + popupTopY;
                };
                
                return py;
            })();
            
            elementBelt.setStyle('top', y);
            
            if (animated) {
                overlay.setStyle('opacity', 0).show();
                elementBelt.setStyle('opacity', 0).show();
                fx.start({
                    0: {
                        opacity: overlayOpacity
                    },
                    1: {
                        opacity: 1
                    }
                });
            } else {
                self.onBeforeShow.call(self);
                overlay.show();
                elementBelt.show();
                self.onShow.call(self);
            };
            
            hidden = false;
            currentPopup = self;
            
            return this;
        };
        
        this.hide = function() {
            if (!elementBelt) {
                alert('Вы не указали элемент попапа!');
                return;
            };
            
            if (fxing) {
                return;
            };
            
            if (animated) {
                fx.start({
                    0: {
                        opacity: 0
                    },
                    1: {
                        opacity: 0
                    }
                });
            } else {
                self.onBeforeHide.call(self);
                elementBelt.hide();
                overlay.hide();
                self.onHide.call(self);
            };
            
            hidden = true;
            currentPopup = null;
            
            return this;
        };
        
        this.isHidden = function() {
            return hidden;
        };
        
        this.setTopOffset = function(offset) {
            topOffset = offset;
            return this;
        };
        
        this.getId = function() {
            return element.get('id');
        };
        
        // event listeners
        this.onBeforeHide = this.onHide = this.onBeforeShow = this.onShow = $empty;
        
        // friendly methods
        this.get = function(property) {
            //if (checkFriendlyMethod(arguments.callee.caller)) {
                switch (property) {
                    case 'overlay':
                        return overlay;
                    case 'fxing':
                        return fxing;
                    case 'element':
                        return element;
                    case 'elementBelt':
                        return elementBelt;
                    case 'hidden':
                        return hidden;
                    case 'topOffset':
                        return topOffset;
                };
            //};
            
            return null;
        };
        
        this.set = function(property, value) {
            //if (checkFriendlyMethod(arguments.callee.caller)) {
                switch (property) {
                    case 'fxing':
                        fxing = value;
                        break;
                    case 'hidden':
                        hidden = value;
                        break;
                };
            //};
        };
        
        // private methods
        var initListeners = function() {
            // нажание esc
            if (!($(document).hasEvent('keyup', onKeyUp))) {
                $(document).addEvent('keyup', onKeyUp);
            };
            
            // клик по оверлею
            if (overlay && !(overlay.hasEvent('click', onOverlayClick))) {
                overlay.addEvent('click', onOverlayClick);
            };
            
            // клик по ремню
            if (elementBelt && !(elementBelt.hasEvent('click', onBeltClick))) {
                elementBelt.addEvent('click', onBeltClick);
            };
            
            // клик по закрывателям
            for (var i = elementClosers.length; i--;) {
                if (!(elementClosers[i].hasEvent('click', onElementCloserClick))) {
                    elementClosers[i].addEvent('click', onElementCloserClick);
                };
            };
        };
        
        var onKeyUp = function(e) {
            var event = new Event(e);
            if (event.key == 'esc') {
                self.hide();
            };
        };
        
        var onOverlayClick = function(e) {
            self.hide();
        };
        
        var onBeltClick = function(e) {
            var event = new Event(e);
            var target = $(event.target);
            
            if (target == element)
                return;
            
            var p = target.getParent('.popup-container');
            if (!p || p != element) {
                self.hide();
            };
        };
        
        var onElementCloserClick = function(e) {
            new Event(e).stop();
            self.hide();
        };
        
        var countOverlaySize = function() {
            return {
                top    : -$(window).getScroll().y,
                height :  $(window).getScrollSize().y + $(window).getScroll().y
            };
        };
        
        var initFx = function() {
            fx = new Fx.Elements([overlay, elementBelt], {
                duration: 100,
                onStart: function() {
                    if (hidden) {
                        self.onBeforeShow.call(self);
                    } else {
                        self.onBeforeHide.call(self);
                    };
                    fxing = true;
                },
                onComplete: function() {
                    if (hidden) {
                        overlay.hide().setStyle('opacity', 1);
                        elementBelt.hide().setStyle('opacity', 1);
                        self.onHide.call(self);
                    } else {
                        self.onShow.call(self);
                    }
                    fxing = false;
                }
            });
        };
        
        var checkFriendlyMethod = function(f) {
            for (var i in PopupStack) {
                if (PopupStack[i] == f)
                    return true;
            };
            
            return false;
        };
        
        this.setOverlayColorAndOpacity('000000', 0.7);
    };
    
    var getOverlayWithColorAndOpacity = function(color, opacity) {
        var index = (function() {
            for (var i = overlays.length; i--;) {
                if (overlays[i].color == color && overlays[i].opacity == opacity) {
                    return i;
                };
            };
            return -1;
        })();
        
        if (index < 0) {
            var element = constructOverlayWithColorAndOpacity(color, opacity);
            
            overlays.push({
                color   : color,
                opacity : opacity,
                element : element
            });
            
            return element;
        };
        
        return overlays[index].element;
    };
    
    var constructOverlayWithColorAndOpacity = function(color, opacity) {
        if (!body) {
            body = $(document.body);
        };
        
        var o = new Element('div', {
            'class': 'popup-overlay hide'
        }).inject(body, 'top');
        
        if (color != defaultOverlayColor) {
            o.setStyle('backgroundColor', color);
        };
        if (opacity != defaultOverlayOpacity) {
            o.setStyle('opacity', opacity);
        };
        
        return o;
    };
};

var DigitBoard = function(input) {
    var self = this;
    var input = $(input);
    var digitLinks = {};
    
    var board = buildBoard();
	document.body.appendChild(board);
	
    var mouseOverBoard = false;
    var maxlength = (function() {
        var ml = input.get('maxlength')
        
        if (ml) {
            return ml.toInt();
        } else {
            return -1;
        }
    })();
    
    var prevInputKey = null;
    var range = {};
    
    input.set('autocomplete', 'off').store('digitboardhidden', true);
    
    this.onChange = function() {};
    
    function buildBoard() {
		var container = new Element('div', {
			'class': 'digit-board hide'
		});
		
		var table = new Element('table').inject(container);
		var tbody = new Element('tbody').inject(table);
        
        var tmpTr;
        var tmpTd;
        var tmpA;
        var tmpIndex;
		
        for (var i = 0; i < 5; i++) {
            tmpTr = new Element('tr').inject(tbody);
            
            for (var j = 0; j < 2; j++) {
                tmpIndex = ((i * 2) - 1) + (j + 1);
                tmpTd = new Element('td').inject(tmpTr);
                tmpA = new Element('a', {href:tmpIndex,text:tmpIndex}).inject(tmpTd);
                digitLinks[tmpIndex] = tmpA;
                
                tmpA.addEvent('click', onDigitClick);
                tmpA.addEvent('mousedown', onDigitMousedown);
                tmpA.addEvent('mouseup', onDigitMouseup);
            };
        };
		
        return container;
    };
    
    function hideBoard() {
        board.hide(true);
        input.store('digitboardhidden', true).fireEvent('change').blur();
        prevInputKey = null;
    };
    
    function isDigit(v) {
        return v.match(v.match(/\d/));
    };
    
    function onInputClick() {
        
        if (!input.retrieve('digitboardhidden')) return;
        
        var coords = input.getCoordinates();
        board.setStyles({
            top: coords.top + coords.height + 7,
            left: coords.left + (coords.width / 2) - 30
        }).show(true);
		
		input.store('digitboardhidden', false);
        (function() {
			input.selectRange(0, 1000000);
        }).delay(150);
    };
    
    function onInputBlur() {
	
        if (!mouseOverBoard || prevInputKey === 'tab') {
            hideBoard();
        };
    };
    
    function onDigitClick(e) {
        new Event(e).stop();
        setDigit(this.get('href'));
        self.onChange();
    };
    
    function onDigitMousedown() {
        range = input.getSelectedRange();
        this.addClass('mousedown');
    };
    
    function onDigitMouseup() {
        this.removeClass('mousedown');
    };
    
    function onBoardMouseover() {
        mouseOverBoard = true;
    };
    
    function onMouseMouseout() {
        mouseOverBoard = false;
    };
    
    function onInputKeydown(e) {
        var event = new Event(e);
        var key = event.key;
        
        prevInputKey = key;
        
        if (isDigit(key)) digitLinks[key].addClass('mousedown');
    };
    
    function onInputKeyup(e) {
        var event = new Event(e);
        var key = event.key;
        if (isDigit(key)) {
            var val = input.get('value');
            var valLength = val.trim().length;
            
            if (maxlength > -1 && valLength >= maxlength) {
                input.set('value', val.substr(0, maxlength));
                // если мы ввели последнюю цифру, то скрываем боард
                if (valLength == maxlength) {
                    hideBoard();
                };
            };
            
            digitLinks[key].removeClass('mousedown');
        };
        
        self.onChange();
    };
    
    function setDigit(d) {
        var oldVal = input.get('value').trim();
        
        //var range = input.getSelectedRange();
        var startText = oldVal.substr(0, range.start);
        var endText = oldVal.substr(range.end, oldVal.length);
        var resultVal = startText + d + endText;
        
        if (maxlength > -1 && resultVal.length > maxlength) {
            input.selectRange(range.start, range.end).focus();
        } else {
            input.set('value', resultVal);
            if (resultVal.length == maxlength) {
                // если ввели последнюю цифру, то скрываем боард
                hideBoard();
            } else {
                input.setCaretPosition(range.start + 1);
            };
        };
        
        if (input.retrieve('caser')) input.retrieve('caser').doCase();
    };
    
    input.addEvent('click', onInputClick);
    input.addEvent('blur', onInputBlur);
    input.addEvent('keydown', justNumber);
    input.addEvent('keydown', onInputKeydown);
    input.addEvent('focus', onInputClick);
    input.addEvent('keyup', onInputKeyup);
    board.addEvent('mouseenter', onBoardMouseover);
    board.addEvent('mouseleave', onMouseMouseout);
    
    input.store('digitboard', this);
};

var YearCaser = function(input, placeholder) {
    var input = $(input);
    var placeholder = $(placeholder);
    
    var caser = function() {
        var rawVal = input.get('value').trim();
        var intVal = rawVal.toInt();

        if (placeholder) {
            if (!rawVal.length) {
                placeholder.set('html', 'лет');
            } else {
                if (intVal >= 11 && intVal <= 14) {
                    placeholder.set('html', 'лет');
                } else {
                    if (rawVal.match(/(?:1|2|3|4)$/)) {
                        if (rawVal.match(/1$/)) {
                            placeholder.set('html', 'год');
                        } else {
                            placeholder.set('html', 'года');
                        };
                    } else {
                        placeholder.set('html', 'лет');
                    };
                };
            };
        };
        
    };
    
    input.addEvent('keyup', caser.debounce(150, false));
    
    this.doCase = function() {
        caser();
    };
    
    input.store('caser', this);
};


var IntegerInputMask = function(input) {
    input = $(input);
    var valueArray = [];
    var shiftDown = false;
    
    input.set('autocomplete', 'off');
    
    function prepareValueArray() {
        var val = input.get('value').trim().replace(/\s/g, '').toInt();
        val = val.formatMoney(0, '', ' ');
        input.set('value', val);
        
        valueArray = val.split('');
    };
    
    function onBackspace() {
        var position = input.getCaretPosition(); if (!position) return;
        var beginLength = valueArray.length;
        var prevSpace = (valueArray[position - 1] === ' ');
        
        if (prevSpace) {
            valueArray.splice(position - 2, 2);
        } else {
            valueArray.splice(position - 1, 1);
        };
        var v = format();
        var endLength = valueArray.length;
        
        input.set('value', v);
        
        position = position - ((beginLength - endLength) + +prevSpace);
        input.setCaretPosition(position);
    };
    
    function onDelete() {
        var position = input.getCaretPosition(); if (position === valueArray.length + 1) return;
        var beginLength = valueArray.length;
        var nextSpace = (valueArray[position] === ' ');
        
        if (nextSpace) {
            valueArray.splice(position, 2);
        } else {
            valueArray.splice(position, 1);
        };
        var v = format();
        var endLength = valueArray.length;
        
        input.set('value', v);
        
        position = position + ((+nextSpace) + 1 - (beginLength - endLength));
        input.setCaretPosition(position);
    };
    
    function onType(d) {
        var position = input.getCaretPosition();
        var beginLength = valueArray.length;
        var begin = valueArray.slice(0, position).filter(function(v) {
            return !(v === ' ');
        }).join('');
        var end = valueArray.slice(position, 1000).filter(function(v) {
            return !(v === ' ');
        }).join('');
        
        var val = (begin + d + end).toInt().formatMoney(0, '', ' ');
        input.set('value', val);
        valueArray = val.split('');
        var endLength = valueArray.length
        input.setCaretPosition(position + (endLength - beginLength));
    };
    
    function format() {
        var tmpArray = valueArray.filter(function(v) {
            return !(v === ' ');
        });
        var val = tmpArray.join('').toInt().formatMoney(0, '', ' ');
        valueArray = val.split('');
        return val;
    };
    
    function onInputKeydown(e) {
        var event = new Event(e);
        
        if (shiftDown) {
            event.stop();
            return;
        };
        
        // backspace
        if (event.key === 'backspace') {
            event.stop();
            onBackspace();
        };
        
        // delete
        if (event.key === 'delete') {
            event.stop();
            onDelete();
        };
        
        // shift
        if (event.code === 16) {
            shiftDown = true;
        };
        
        // digit
        if (event.key.match(/^\d$/)) {
            event.stop();
            onType(event.key);
        };
    };
    
    function onInputKeyup(e) {
        var event = new Event(e);
        
        if (event.code === 16) {
            shiftDown = false;
        };
    };
    
    input.addEvent('focus', prepareValueArray);
    input.addEvent('keydown', justNumber);
    input.addEvent('keydown', onInputKeydown);
    input.addEvent('keyup', onInputKeyup);
    
    prepareValueArray();
};

var EmptyText = function(c) {
    var self = this;
    var container = $(c);
    var input = container.getElement('input');
    var size = input.getSize();
    var overDiv = container.getFirst();
    var paddingTop = input.getStyle('paddingTop').toInt();
    var paddingRight = input.getStyle('paddingRight').toInt();
    var paddingBottom = input.getStyle('paddingBottom').toInt();
    var paddingLeft = input.getStyle('paddingLeft').toInt();
    var fontFamily = input.getStyle('fontFamily');
    var fontSize = input.getStyle('fontSize');
    
    size.x -= (paddingLeft + paddingRight);
    size.y -= (paddingTop + paddingBottom);
    
    container.setStyle('position', 'relative');
    overDiv.setStyles({
        padding: paddingTop + 'px ' + paddingRight + 'px ' + paddingBottom + 'px ' + paddingLeft + 'px',
        width: size.x,
        height: size.y,
        position: 'absolute',
        top: 0,
        left: 0,
        fontFamily: fontFamily,
        fontSize: fontSize,
        lineHeight: size.y,
        color: '#acacac'
    });
    
    this.update = function() {
        if (!input.get('value').trim().length) {
            overDiv.show();
        } else {
            overDiv.hide();
        };
    };
    
    if (!input.get('value').trim().length) {
        overDiv.show();
    };
    
    overDiv.addEvent('click', function() {
        overDiv.hide();
        input.focus();
    });
    
    input.addEvent('blur', function() {
        self.update();
    });
    
    input.addEvent('focus', function() {
        overDiv.hide();
        input.focus();
    });
    
    input.store('emptytext', this);
    
    this.update();
};

var saveData;

window.addEvent('domready', function() {
    
    /*$each($$('.empty-text'), function(et) {
        new EmptyText(et);
    });*/
    
    // сохраняем данные по производителю, чтобы автоматически подставлять стоимость
    var manufacturerData;
    
    var calculationForm = $('calculator-form');
    var submitButton = calculationForm.getElement('input[type=image]');
    var dropout = $$('.main-dropout')[0];
    
    // сюда запоминаются айдишник результата, чтобы потом отправить его на почту
    var resultIds = '';
    
    // подсказка про стоимость авто
    var priceTip = calculationForm.getElement('.price-tip');
	priceTip.setStyle('left', "862px");
    var priceTipY = priceTip.getStyle('left').toInt(); priceTip.setStyle('left', priceTipY + 10 +"px");
    var priceTipFx = priceTip.setStyle('opacity', 0).show().get('morph'); priceTipFx.options.duration = 100;
    var priceTipTimer;
    var priceTipShow = function() {
        var y = priceTip.getStyle('left');
        priceTipFx.cancel();
        $clear(priceTipTimer);
        priceTipFx.start({
            left: [y, priceTipY],
            opacity: 1
        });
        priceTipTimer = (function() {
            priceTipHide();
        }).delay(3000);
    };
    var priceTipHide = function() {
        var y = priceTip.getStyle('left');
        priceTipFx.cancel();
        priceTipFx.start({
            left: [y, priceTipY + 10],
            opacity: 0,
            onComplete: function() {
                priceTip.hide();
            }
        });
    };
    
    var modelsUrl = '/calc/api/update/';
    var modelsRequest = new Request.JSON({
        url: modelsUrl,
        onRequest: function() {
            carManufacturerField.disabled = true;
            yearSelect.disabled = true;
            modelsSelect.empty().disabled = true;
            modificationsSelect.disabled = true;
        },
        onSuccess: function(json) {
            if (!json.data['list']) {
                carManufacturerField.disabled = false;
                yearSelect.disabled = false;
                modelsSelect.empty();
                modificationsSelect.empty();
                return;
            }
            manufacturerData = json.data.list;
            
            constructModelSelect(manufacturerData);
            if (this.options['selectedModel']) {
                modelsSelect.set('value', this.options['selectedModel']);
                constructModificationsSelect(manufacturerData, modelsSelect.get('value'));
                if (this.options['selectedModification']) {
                    modificationsSelect.set('value', this.options['selectedModification']);
                    delete this.options['selectedModification'];
                };
                delete this.options['selectedModel'];
            } else {
                constructModificationsSelect(manufacturerData, modelsSelect.getFirst().get('value'));
                if (this.options['selectedModification']) {
                    modificationsSelect.set('value', this.options['selectedModification']);
                    delete this.options['selectedModification'];
                };
                priceTipShow();
            };
            
            yearSelect.disabled = false;
            modelsSelect.disabled = false;
            modificationsSelect.disabled = false;
            carManufacturerField.disabled = false;
            
            if (this.options.previousField) {
                if (this.options.previousField === carManufacturer) {
                    yearSelect.focus();
                };
                if (this.options.previousField === yearSelect) {
                    modelsSelect.focus();
                };
            };
            
            // меняем стоимость и мощность только в том случае, если
            // запрос моделей/модификаций/цен производился не из восстановления из кук
            if (this.options.restore) {
                delete this.options['restore'];
            } else {
                changePricePower();
            };
        }
    });
    var requireModels = function() {
        hideAllResultBlocks();
        modelsRequest.options.previousField = this;
        
        var selectedModel = modelsSelect.get('value');
        var selectedModification = modificationsSelect.get('value');
        
        if (selectedModel.length && selectedModification.length) {
            modelsRequest.options.selectedModel = selectedModel;
            modelsRequest.options.selectedModification = selectedModification;
        };
        
        modelsRequest.send('brand=' + encodeURIComponent(carManufacturer.getValue().trim()) + '&year=' + encodeURIComponent(yearSelect.get('value').trim()) + '&type=model');
    };
        
    var carManufacturerField = $$('.car-manufacturer')[0];
    var carManufacturer = new Suggestive(carManufacturerField, dropout);
    carManufacturer.addEvent('change', requireModels.bindWithEvent(carManufacturer));
    carManufacturerField.addEvent('focus', function() {
        if (!window.getScroll().y) {
            windowScroller.toElement(calculationForm);
        };
    });
    
    var constructModelSelect = function(data) {
        var c = '';
        for (var i = 0; i < data.length; i++) {
            c += '<option value="' + data[i].value + '">' + data[i].text + '</option>';
        };
        modelsSelect.set('html', c);
        modelsSelect.getFirst().selected = true;
    };
    var constructModificationsSelect = function(data, parent) {
        var d = data.filter(function(dd) {
            return (dd.value == parent);
        });
        if (!d.length) return; d = d[0].modifications;
        
        var c = '';
        for (var i = 0; i < d.length; i++) {
            c += '<option value="' + d[i].value + '">' + d[i].text + '</option>';
        };
        modificationsSelect.set('html', c);
        modificationsSelect.getFirst().selected = true;
    };
    var modelsSelect = $$('.car-model')[0];
    modelsSelect.addEvent('change', function() {
        constructModificationsSelect(manufacturerData, this.get('value'));
        modificationsSelect.focus();
        changePricePower();
        priceTipShow();
    });
    
    var modificationsSelect = $$('.car-model')[1];
    modificationsSelect.addEvent('change', function() {
        changePricePower();
		if (!priceField.disabled)
			priceField.focus();
        priceTipShow();
    });
    
    
    // выставляет дефолтные значения стоимости и мощности
    // в зависимости от производителя/модели/года
    var changePricePower = function() {
        var m  = modelsSelect.get('value').trim();
        var md = modificationsSelect.get('value').trim();
        var y  = yearSelect.get('value').trim();
        
        if (!manufacturerData) return;
        
        function updatePowerSelect(newPower) {
            newPower = newPower.toInt();
            
            var options = powerSelect.getElements('option');
            
            if (newPower <= 50) {
                options[0].selected = true;
            } else if (newPower > 50 && newPower <= 70) {
                options[1].selected = true;
            } else if (newPower > 70 && newPower <= 100) {
                options[2].selected = true;
            } else if (newPower > 100 && newPower <= 120) {
                options[3].selected = true;
            } else if (newPower > 120 && newPower <= 150) {
                options[4].selected = true;
            } else {
                options[5].selected = true;
            }
        };
        
        manufacturerData.each(function(d) {
            if (d.value == m) {
                d.modifications.each(function(mod) {
                    if (mod.value == md) {
                        for (var yy in mod.cost) {
                            if (yy == y) {
                                priceField.transposeTo(mod.cost[yy], '', [0, '', ' ']);
                            };
                        };
                        updatePowerSelect(mod.power);
                    }
                });
            };
        });
    };
    
    var kaskoLineTable = $$('.car-line')[0];
    var osagoLineTable = $$('.osago-line')[0];
    
    var iNeedKasko = $$('.ineed input')[0];
    var iNeedOsago = $$('.ineed input')[1];
    
    var iAmFiz     = $$('.ineed input')[2];
    var iAmUr      = $$('.ineed input')[3];
    
    var onWarranty = $$('.on-warranty input')[0];
    var refType    = $$('.on-warranty input')[1];
    
    var yearSelect = $$('.car-year')[0];
    var powerSelect = $$('.car-power')[0];
    var priceField = $$('.car-price')[0];
    var regionSelect = $$('.car-region')[0];
    var useSelect = $$('.use-period')[0];
    var crashSelect = $$('.crash-period')[0];
    
    onWarranty.addEvent('click', function(e) {
        if (this.checked) {
            refType.set('value', 'stoa_dealer');
        } else {
            refType.set('value', 'stoa_by_company');
        };
    });
    
    /*priceField.addEvents({
        focus: function() {
            var val = this.get('value').trim().replace(/\s/g, '');
            this.set('value', val);
            this.selectRange(0, 100);
        },
        blur: function() {
            var val = this.get('value').trim().toInt().formatMoney(0, '', ' ');
            this.set('value', val);
        },
        keydown: justNumber
    });*/
    new IntegerInputMask(priceField);
    
    yearSelect.addEvent('change', requireModels);
    regionSelect.addEvent('change', function(e) {
        powerSelect.focus();
    });
    powerSelect.addEvent('change', function() {
        useSelect.focus();
    });
    
    // сохранение в куку
    saveData = function() {
		
		try {
		    Cookie.write('form', calculationForm.toQueryString());
		} catch(e){
		}
		
    };

    var driversTable = $$('table.drivers')[0];
    var unlimDriversTable = $$('table.drivers')[1];
    var unlimLine = $$('.unlim')[0];
    var unlimCheckbox = $$('input[name=unlimited_drivers]')[1];

    var hideDriversTable = function(table) {
        table.hide();
        table.getElements('input, select').each(function(i){
            i.disabled = true;
        });
    };
    var showDriversTable = function(table) {
        table.getElements('input, select').each(function(i){
            i.disabled = false;
        });
        table.show();
    };

    // выбор нужной опции разблокирует сабмит формы
    var checkState = function() {
        if (iNeedKasko.checked || iNeedOsago.checked) {
            submitButton.removeClass('disabled');
            unlimLine.show();
        } else {
            submitButton.addClass('disabled');
            hideDriversTable(driversTable);
            hideDriversTable(unlimDriversTable);
            osagoLineTable.hide();
            kaskoLineTable.hide();
            unlimLine.hide();
            return;
        };
        
        if (iNeedOsago.checked) {
            osagoLineTable.getElements('input, select').each(function(t) {
                t.disabled = false;
            });
            osagoLineTable.show();
        } else {
            osagoLineTable.hide();
            osagoLineTable.getElements('input, select').each(function(t) {
                /*t.set('value', '')*/t.disabled = true;
            });
        };
        
        if (iNeedKasko.checked) {
            kaskoLineTable.getElements('input, select').each(function(t) {
                t.disabled = false;
            });
            kaskoLineTable.show();
        } else {
            kaskoLineTable.hide();
            kaskoLineTable.getElements('input, select').each(function(t) {
                /*t.set('value', '')*/t.disabled = true;
            });
        };
        
        if (unlimCheckbox.checked) {
            if (!(iNeedKasko.checked) && iNeedOsago.checked) {
                // скрываем все таблицы с водителями
                hideDriversTable(driversTable);
                hideDriversTable(unlimDriversTable);
            } else {
                hideDriversTable(driversTable);
                showDriversTable(unlimDriversTable);
            };
        } else {
            showDriversTable(driversTable);
            hideDriversTable(unlimDriversTable);
        };
    };
    (function() {
        iNeedKasko.addEvent('click', function(e){
            checkState();
        });
        iNeedOsago.addEvent('click', function(e){
            checkState();
        });
    
        checkState();
    })();

    // управление водителями
    var addTrWithData;
    (function() {
        var maxTrs = 5;
        var counter = 1;
        var trs = [];
        
        var addTr = function(e) {
            if (e) {
                new Event(e).stop();
            };
			
			
			trs.getLast().retrieve('addLink').hide();
			
            if (counter == maxTrs) return;
            counter++;
			
            var tr = buildTr();
            if (counter == maxTrs) {
                tr.retrieve('addLink').hide();
            };
            tr.inject(driversTable.getElement('tbody'), 'bottom');
            trs.push(tr);
        };
        
        addTrWithData = function(a, e) {
            addTr(false);
			
            var tr = trs.getLast();
            var af = tr.retrieve('ageField');
            var ef = tr.retrieve('experienceField');
            af.set('value', a);
            ef.set('value', e);
            af.retrieve('caser').doCase();
            ef.retrieve('caser').doCase();
        };
        
        var recountTrs = function() {
            for (var i = 0, j = 1; i < counter; i++, j++) {
                var dn = trs[i].retrieve('driverNum');
                if (dn) {
                    dn.set('html', j);
                };
                trs[i].retrieve('ageField').set('name', 'age[' + j + ']');
                trs[i].retrieve('experienceField').set('name', 'experience[' + j + ']');
                trs[i].retrieve('sexField').set('name', 'sex[' + j + ']');
                trs[i].retrieve('maritalStatusField').set('name', 'marital_status[' + j + ']');
                trs[i].retrieve('hasChildrenField').set('name', 'has_children[' + j + ']');
            };
			
            trs.getLast().retrieve('addLink').show();
        };
        
        var removeTr = function(e) {
            new Event(e).stop();
            
            if (counter == 1) return;
            
            var tr = this.getParent('tr');
            var i = trs.indexOf(tr);
            
            trs.splice(i, 1);
            tr.destroy();
            
            counter--;
            recountTrs();
        };
        
        // сразу проверяет введенные значения, чтобы они были в допустимых пределах
        var observeDriver = function(tr) {
            var af = tr.retrieve('ageField');
            var ef = tr.retrieve('experienceField');
            
            new DigitBoard(af);
            new DigitBoard(ef);
            
            var ac = new YearCaser(af, af.getNext());
            var ec = new YearCaser(ef, ef.getNext());
            
            af.addEvent('keydown', justNumber);
            ef.addEvent('keydown', justNumber);
            
            function checkAgeExperience() {
                var av = af.get('value').trim().toInt();
                var ev = ef.get('value').trim().toInt();
                var di = av - ev;
                
                if (di < 18) {
                    ef.set('value', av - 18);
                    ec.doCase();
                };
                
                // di может быть равен NaN, если пользователь оставил поле стажа незаполненным
                if (!di && di != 0) {
                    ef.set('value', '0');
                    ec.doCase();
                };
                
                //saveData();
            };
            
            af.addEvent('blur', function() {
                
                if (!this.retrieve('digitboardhidden')) return;
                
                var val = this.get('value').trim();
                
                if (!val) {
                    this.set('value', '26');
                    val = 26;
                };
                
                var intVal = val.toInt();
                if (val < 18) {
                    this.set('value', '18');
                    ac.doCase();
                };
                checkAgeExperience();
            });
            ef.addEvent('blur', function() {
                
                if (!this.retrieve('digitboardhidden')) return;
                
                checkAgeExperience();
            });
        };
        
        // если без параметров, то создает тр с водителем
        // если с параметром тр, то подключает добавлялку и удалялку
        var buildTr = function() {
            var tr, ageField, experienceField, sexField, maritalStatusField, hasChildrenField, deleteLink, addLink, driverNum;
            if (arguments.length) {
                tr = arguments[0];
            } else {
                tr = new Element('tr');
                var td1 = new Element('td', {'class':'driver-num','html':'<b>Водитель <i>' + counter + '</i>&nbsp;&nbsp;&nbsp;&nbsp;&mdash;&nbsp;&nbsp;&nbsp;&nbsp;</b>'});
                var td2 = new Element('td', {'html':'<label>Возраст</label>'});
                var td3 = new Element('td', {'class':'driver-age','html':'<div class="input-with-units"><input type="text" name="age[' + counter + ']" value="26" maxlength="2" /><div class="unit">лет</div></div>'});
                var td4 = new Element('td', {'html':'<label>Стаж вождения</label>'});
                var td5 = new Element('td', {'class':'driver-exp','html':'<div class="input-with-units"><input type="text" name="experience[' + counter + ']" value="6" maxlength="2" /><div class="unit">лет</div></div>'});
                var td6 = new Element('td', {'class':'driver-del','html':'<a href=""><img src="/images/main/driver-delete.png" alt="" /></a>'});
                var td7 = new Element('td', {'class':'driver-add','html':'<a href=""><img src="/images/main/driver-add.png" alt="" /></a><input type="hidden" name="sex[' + counter + ']" value="male" /><input type="hidden" name="marital_status[' + counter + ']" value="not_married" /><input type="hidden" name="has_children[' + counter + ']" value="0" />'});
                
                td1.inject(tr);
                td2.inject(tr);
                td3.inject(tr);
                td4.inject(tr);
                td5.inject(tr);
                td6.inject(tr);
                td7.inject(tr);
            };
            
            driverNum = tr.getElement('b i'); tr.store('driverNum', driverNum);
            ageField = tr.getElement('input[name^=age]'); tr.store('ageField', ageField);
            experienceField = tr.getElement('input[name^=experience]'); tr.store('experienceField', experienceField);
            sexField = tr.getElement('input[name^=sex]'); tr.store('sexField', sexField);
            maritalStatusField = tr.getElement('input[name^=marital_status]'); tr.store('maritalStatusField', maritalStatusField);
            hasChildrenField = tr.getElement('input[name^=has_children]'); tr.store('hasChildrenField', hasChildrenField);
            deleteLink = tr.getElement('.driver-del a'); tr.store('deleteLink', deleteLink);
            addLink = tr.getElement('.driver-add a'); tr.store('addLink', addLink);
            
            //ageField.addEvent('change', saveData);
            //experienceField.addEvent('change', saveData);
            
            deleteLink.addEvent('click', removeTr);
            addLink.addEvent('click', addTr);
            
            observeDriver(tr);
            return tr;
        };
        
        var firstTr = driversTable.getElement('tr');
        buildTr(firstTr);
        trs.push(firstTr);
                
        unlimCheckbox.addEvent('click', checkState);
        
        var unlimTr = (function() {
            var tr = unlimDriversTable.getElement('tr');
            tr.store('ageField', tr.getElement('input[name^=age]'));
            tr.store('experienceField', tr.getElement('input[name^=experience]'));
            return tr;
        })();
        observeDriver(unlimTr);
    })();
    
    var resultsBlock = $$('.results')[0];
    var wrongResultsBlock = $$('.wrong-results')[0];
    var osagoResultsBlock = $$('.osago-results')[0];
    var sendEmailBlock = $$('.email-send')[0];
    //var detailedResultsBlock = $$('.detailed-result')[0];
    var detailedResultsBlock = $$('.detailed-result');
    var compareResultsButtonBlock = $$('.compare-results-button')[0];
    var compareResultsButton = compareResultsButtonBlock.getFirst();
    var returnToCalculationBlock = $$('.recalculate-rect')[0];
    var returnToCalculationButton = returnToCalculationBlock.getElement('a');
    
    var r1Td = resultsBlock.getElement('td.l');
    var r1Order = $$([resultsBlock.getElement('td.l a.choose'), detailedResultsBlock.getElement('td.l a.buy')]);
    var r2Td = resultsBlock.getElement('td.c');
    var r2Order = $$([resultsBlock.getElement('td.c a.choose'), detailedResultsBlock.getElement('td.c a.buy')]);
    var r3Td = resultsBlock.getElement('td.r');
    var r3Order = $$([resultsBlock.getElement('td.r a.choose'), detailedResultsBlock.getElement('td.r a.buy')]);
    
    var rOOrder = osagoResultsBlock.getElement('a.choose');
    
    // отправка результатов по почте
    (function() {
        var emailForm = sendEmailBlock.getElement('form');
        var emailInput = sendEmailBlock.getElement('input[type=text]');
        var ajaxContainer = sendEmailBlock.getElement('.ajax-block');
        var ajaxOkContainer = sendEmailBlock.getElement('.ajax-block-ok');
        var emailRequest = new Request.JSON({ // ?resultId=
            url: emailForm.get('action'),
            onRequest: function() {
                emailing = true;
                ajaxOkContainer.hide();
                ajaxContainer.show();
            },
            onSuccess: function(json) {
                ajaxContainer.hide();
                ajaxOkContainer.show();
                emailing = false;
                (function() {
                    ajaxOkContainer.hide(true);
                }).delay(5000);
            }
        });
        var emailing = false;
        
        var fv = new FormValidator(emailForm);
        fv.setDelegate(function(event) {
            event.stop();
            
            if (this.formValid && !emailing) {
                emailRequest.send('email=' + encodeURIComponent(emailInput.get('value').trim()) + '&resultId=' + encodeURIComponent(resultIds) + '&' + calculationForm.toQueryString());
            };
        });
        
    })();
    
    // работа с таблицей результатов
    var updateDetailedResults;
    (function() {
        var carCostTr = detailedResultsBlock.getElement('.r-car-cost');
        var deductibleTr = detailedResultsBlock.getElement('.r-deductible');
        var commissarTr = detailedResultsBlock.getElement('.r-commissar'); // done
        var evacuationTr = detailedResultsBlock.getElement('.r-evacuation'); // done
        var personalManagerTr = detailedResultsBlock.getElement('.r-personal-manager'); // done
        var collectingDocumentsTr = detailedResultsBlock.getElement('.r-collecting-documents'); // done
        var replacementCarTr = detailedResultsBlock.getElement('.r-replacement-car'); // done
        var easyPaymentsTr = detailedResultsBlock.getElement('.r-easy-payments'); // done
        var refundTypeTr = detailedResultsBlock.getElement('.r-refund-type');
        var taxiTr = detailedResultsBlock.getElement('.r-taxi'); // done
        var consultantTr = detailedResultsBlock.getElement('.r-consultant'); // done
        var glassTr = detailedResultsBlock.getElement('.r-glass'); // done
        var supportTr = detailedResultsBlock.getElement('.r-support'); // done
        var emergencyTr = detailedResultsBlock.getElement('.r-emergency'); // done
        var referalTr = detailedResultsBlock.getElement('.r-referal'); // done
        var specialTr = detailedResultsBlock.getElement('.r-special'); // done
        
        detailedResultsBlock.addEvent('click', function(e) {
            var event = new Event(e);
            var target = $(event.target);
            
            if (target.get('tag').toLowerCase() === 'a' && target.get('class')) {
                event.stop();
                
                var description = target.getParent().getNext();
                if (description) {
                    if (description.isVisible()) {
                        description.hide();
                        target.set('text', 'подробнее');
                    } else {
                        description.show();
                        target.set('text', 'скрыть');
                    };
                };
            };
        });
        
        compareResultsButton.addEvent('click', function(e){
            var event = new Event(e);
            event.stop();
            
            compareResultsButtonBlock.hide();
            detailedResultsBlock[1].show();
        });
        
        function assignVar(line, pos, val) {
            line[0].getElement('div.' + pos + ' .c').set('html', val);
            line[1].getElement('td.' + pos + ' .c').set('html', val);
        };
        
        updateDetailedResults = function(r1, r2, r3) {
            /*carCostTr.getElement('div.l .r').set('html', r1.car_cost.formatMoney(0, '', ' '));
            carCostTr.getElement('div.c .r').set('html', r2.car_cost.formatMoney(0, '', ' '));
            carCostTr.getElement('div.r .r').set('html', r3.car_cost.formatMoney(0, '', ' '));*/

            if (r1.deductible) {
                assignVar(deductibleTr, 'l', '<span class="r">' + r1.deductible.toFloat().formatMoney(0, '', ' ') + '</span> р.');
            } else {
                assignVar(deductibleTr, 'l', '—');
            };
            if (r2.deductible) {
                assignVar(deductibleTr, 'c', '<span class="r">' + r1.deductible.toFloat().formatMoney(0, '', ' ') + '</span> р.');
            } else {
                assignVar(deductibleTr, 'c', '—');
            };
            if (r3.deductible) {
                assignVar(deductibleTr, 'r', '<span class="r">' + r3.deductible.toFloat().formatMoney(0, '', ' ') + '</span> р.');
            } else {
                assignVar(deductibleTr, 'r', '—');
            };
            
                if (!r1.deductible && !r2.deductible && !r3.deductible) {
                    deductibleTr.hide();
                } else {
                    deductibleTr.show();
                };


            if (r1.refund_type && r1.refund_type_text.length) {
                assignVar(refundTypeTr, 'l', '<p>' + r1.refund_type_text + '</p>');
            } else {
                assignVar(refundTypeTr, 'l', '—');
            };
            if (r2.refund_type && r2.refund_type_text.length) {
                assignVar(refundTypeTr, 'c', '<p>' + r2.refund_type_text + '</p>');
            } else {
                assignVar(refundTypeTr, 'c', '—');
            };
            if (r3.refund_type && r3.refund_type_text.length) {
                assignVar(refundTypeTr, 'r', '<p>' + r3.refund_type_text + '</p>');
            } else {
                assignVar(refundTypeTr, 'r', '—');
            };


            if (r1.commissar && r1.commissar_terms.length) {
                assignVar(commissarTr, 'l', '<p class="">' + r1.commissar_terms + '</p>');
            } else {
                assignVar(commissarTr, 'l', '—');
            };
            if (r2.commissar && r2.commissar_terms.length) {
                assignVar(commissarTr, 'c', '<p class="">' + r2.commissar_terms + '</p>');
            } else {
                assignVar(commissarTr, 'c', '—');
            };
            if (r3.commissar && r3.commissar_terms.length) {
                assignVar(commissarTr, 'r', '<p class="">' + r3.commissar_terms + '</p>');
            } else {
                assignVar(commissarTr, 'r', '—');
            };
            
                if (!r1.commissar.toInt() && !r2.commissar.toInt() && !r3.commissar.toInt()) {
                    commissarTr.hide();
                } else {
                    commissarTr.show();
                };


            if (r1.evacuation && r1.evacuation_terms.length) {
                assignVar(evacuationTr, 'l', '<p class="">' + r1.evacuation_terms + '</p>');
            } else {
                assignVar(evacuationTr, 'l', '—');
            };
            if (r2.evacuation && r2.evacuation_terms.length) {
                assignVar(evacuationTr, 'c', '<p class="">' + r2.evacuation_terms + '</p>');
            } else {
                assignVar(evacuationTr, 'c', '—');
            };
            if (r3.evacuation && r3.evacuation_terms.length) {
                assignVar(evacuationTr, 'r', '<p class="">' + r3.evacuation_terms + '</p>');
            } else {
                assignVar(evacuationTr, 'r', '—');
            };
            
                if (!r1.evacuation.toInt() && !r2.evacuation.toInt() && !r3.evacuation.toInt()) {
                    evacuationTr.hide();
                } else {
                    evacuationTr.show();
                };

            
            if (r1.personal_manager && r1.personal_manager_terms.length) {
                assignVar(personalManagerTr, 'l', '<p>' + r1.personal_manager_terms + '</p>');
            } else {
                assignVar(personalManagerTr, 'l', '—');
            };
            if (r2.personal_manager && r2.personal_manager_terms.length) {
                assignVar(personalManagerTr, 'c', '<p>' + r2.personal_manager_terms + '</p>');
            } else {
                assignVar(personalManagerTr, 'c', '—');
            };
            if (r3.personal_manager && r3.personal_manager_terms.length) {
                assignVar(personalManagerTr, 'r', '<p>' + r3.personal_manager_terms + '</p>');
            } else {
                assignVar(personalManagerTr, 'r', '—');
            };
            
                if (!r1.personal_manager.toInt() && !r2.personal_manager.toInt() && !r3.personal_manager.toInt()) {
                    personalManagerTr.hide();
                } else {
                    personalManagerTr.show();
                };

            
            if (r1.collecting_documents && r1.collecting_documents_terms.length) {
                assignVar(collectingDocumentsTr, 'l', '<p class="">' + r1.collecting_documents_terms + '</p>');
            } else {
                assignVar(collectingDocumentsTr, 'l', '—');
            };
            if (r2.collecting_documents && r2.collecting_documents_terms.length) {
                assignVar(collectingDocumentsTr, 'c', '<p class="">' + r2.collecting_documents_terms + '</p>');
            } else {
                assignVar(collectingDocumentsTr, 'c', '—');
            };
            if (r3.collecting_documents && r3.collecting_documents_terms.length) {
                assignVar(collectingDocumentsTr, 'r', '<p class="">' + r3.collecting_documents_terms + '</p>');
            } else {
                assignVar(collectingDocumentsTr, 'r', '—');
            };
            
                if (!r1.collecting_documents.toInt() && !r2.collecting_documents.toInt() && !r3.collecting_documents.toInt()) {
                    collectingDocumentsTr.hide();
                } else {
                    collectingDocumentsTr.show();
                };


            if (r1.replacement_car && r1.replacement_car_terms.length) {
                assignVar(replacementCarTr, 'l', '<p>' + r1.replacement_car_terms + '</p>');
            } else {
                assignVar(replacementCarTr, 'l', '—');
            };
            if (r2.replacement_car && r2.replacement_car_terms.length) {
                assignVar(replacementCarTr, 'c', '<p>' + r2.replacement_car_terms + '</p>');
            } else {
                assignVar(replacementCarTr, 'c', '—');
            };
            if (r3.replacement_car && r3.replacement_car_terms.length) {
                assignVar(replacementCarTr, 'r', '<p>' + r3.replacement_car_terms + '</p>');
            } else {
                assignVar(replacementCarTr, 'r', '—');
            };
            
                if (!r1.replacement_car.toInt() && !r2.replacement_car.toInt() && !r3.replacement_car.toInt()) {
                    replacementCarTr.hide();
                } else {
                    replacementCarTr.show();
                };
            

            if (r1.glass && r1.glass_terms.length) {
                assignVar(glassTr, 'l', '<p>' + r1.glass_terms + '</p>');
            } else {
                assignVar(glassTr, 'l', '—');
            };
            if (r2.glass && r2.glass_terms.length) {
                assignVar(glassTr, 'c', '<p>' + r2.glass_terms + '</p>');
            } else {
                assignVar(glassTr, 'c', '—');
            };
            if (r3.glass && r3.glass_terms.length) {
                assignVar(glassTr, 'r', '<p>' + r3.glass_terms + '</p>');
            } else {
                assignVar(glassTr, 'r', '—');
            };
            
                if (!r1.glass.toInt() && !r2.glass.toInt() && !r3.glass.toInt()) {
                    glassTr.hide();
                } else {
                    glassTr.show();
                };
            
            
            if (r1.support && r1.support_terms.length) {
                assignVar(supportTr, 'l', '<p>' + r1.support_terms + '</p>');
            } else {
                assignVar(supportTr, 'l', '—');
            };
            if (r2.support && r2.support_terms.length) {
                assignVar(supportTr, 'c', '<p>' + r2.support_terms + '</p>');
            } else {
                assignVar(supportTr, 'c', '—');
            };
            if (r3.support && r3.support_terms.length) {
                assignVar(supportTr, 'r', '<p>' + r3.support_terms + '</p>');
            } else {
                assignVar(supportTr, 'r', '—');
            };
            
                if (!r1.support.toInt() && !r2.support.toInt() && !r3.support.toInt()) {
                    supportTr.hide();
                } else {
                    supportTr.show();
                };
            

            if (r1.emergency && r1.emergency_terms.length) {
                assignVar(emergencyTr, 'l', '<p>' + r1.emergency_terms + '</p>');
            } else {
                assignVar(emergencyTr, 'l', '—');
            };
            if (r2.emergency && r2.emergency_terms.length) {
                assignVar(emergencyTr, 'c', '<p>' + r2.emergency_terms + '</p>');
            } else {
                assignVar(emergencyTr, 'c', '—');
            };
            if (r3.emergency && r3.emergency_terms.length) {
                assignVar(emergencyTr, 'r', '<p>' + r3.emergency_terms + '</p>');
            } else {
                assignVar(emergencyTr, 'r', '—');
            };
            
                if (!r1.emergency.toInt() && !r2.emergency.toInt() && !r3.emergency.toInt()) {
                    emergencyTr.hide();
                } else {
                    emergencyTr.show();
                };
            

            if (r1.referal && r1.referal_terms.length) {
                assignVar(referalTr, 'l', '<p>' + r1.referal_terms + '</p>');
            } else {
                assignVar(referalTr, 'l', '—');
            };
            if (r2.referal && r2.referal_terms.length) {
                assignVar(referalTr, 'c', '<p>' + r2.referal_terms + '</p>');
            } else {
                assignVar(referalTr, 'c', '—');
            };
            if (r3.referal && r3.referal_terms.length) {
                assignVar(referalTr, 'r', '<p>' + r3.referal_terms + '</p>');
            } else {
                assignVar(referalTr, 'r', '—');
            };
            
                if (!r1.referal.toInt() && !r2.referal.toInt() && !r3.referal.toInt()) {
                    referalTr.hide();
                } else {
                    referalTr.show();
                };
            
            
            if (r1.consultant && r1.consultant_terms.length) {
                assignVar(consultantTr, 'l', '<p>' + r1.consultant_terms + '</p>');
            } else {
                assignVar(consultantTr, 'l', '—');
            };
            if (r2.consultant && r2.consultant_terms.length) {
                assignVar(consultantTr, 'c', '<p>' + r2.consultant_terms + '</p>');
            } else {
                assignVar(consultantTr, 'c', '—');
            };
            if (r3.consultant && r3.consultant_terms.length) {
                assignVar(consultantTr, 'r', '<p>' + r3.consultant_terms + '</p>');
            } else {
                assignVar(consultantTr, 'r', '—');
            };
            
                if (!r1.consultant.toInt() && !r2.consultant.toInt() && !r3.consultant.toInt()) {
                    consultantTr.hide();
                } else {
                    consultantTr.show();
                };

          
            if (r1.easy_payments && r1.easy_payments_terms.length) {
                assignVar(easyPaymentsTr, 'l', '<p class="">' + r1.easy_payments_terms + '</p>');
            } else {
                assignVar(easyPaymentsTr, 'l', '—');
            };
            if (r2.easy_payments && r2.easy_payments_terms.length) {
                assignVar(easyPaymentsTr, 'c', '<p class="">' + r2.easy_payments_terms + '</p>');
            } else {
                assignVar(easyPaymentsTr, 'c', '—');
            };
            if (r3.easy_payments && r3.easy_payments_terms.length) {
                assignVar(easyPaymentsTr, 'r', '<p class="">' + r3.easy_payments_terms + '</p>');
            } else {
                assignVar(easyPaymentsTr, 'r', '—');
            };
            
                if (!r1.easy_payments.toInt() && !r2.easy_payments.toInt() && !r3.easy_payments.toInt()) {
                    easyPaymentsTr.hide();
                } else {
                    easyPaymentsTr.show();
                };
                
            if (r1.special && r1.special_terms.length) {
                assignVar(specialTr, 'l', '<p class="">' + r1.special_terms + '</p>');
            } else {
                assignVar(specialTr, 'l', '—');
            };
            if (r2.special && r2.special_terms.length) {
                assignVar(specialTr, 'c', '<p class="">' + r2.special_terms + '</p>');
            } else {
                assignVar(specialTr, 'c', '—');
            };
            if (r3.special && r3.special_terms.length) {
                assignVar(specialTr, 'r', '<p class="">' + r3.special_terms + '</p>');
            } else {
                assignVar(specialTr, 'r', '—');
            };
            
                if (typeof r1.special !== 'undefined' && !r1.special.toInt() && typeof r2.special !== 'undefined' && !r2.special.toInt() && typeof r3.special !== 'undefined' && !r3.special.toInt()) {
                    specialTr.hide();
                } else {
                    specialTr.show();
                };


            if (r1.taxi && r1.taxi_terms.length) {
                assignVar(taxiTr, 'l', '<p>' + r1.taxi_terms + '</p>');
            } else {
                assignVar(taxiTr, 'l', '—');
            };
            if (r2.taxi && r2.taxi_terms.length) {
                assignVar(taxiTr, 'c', '<p>' + r2.taxi_terms + '</p>');
            } else {
                assignVar(taxiTr, 'c', '—');
            };
            if (r3.taxi && r3.taxi_terms.length) {
                assignVar(taxiTr, 'r', '<p>' + r3.taxi_terms + '</p>');
            } else {
                assignVar(taxiTr, 'r', '—');
            };
            
                if (!r1.taxi.toInt() && !r2.taxi.toInt() && !r3.taxi.toInt()) {
                    taxiTr.hide();
                } else {
                    taxiTr.show();
                };

        };
    })();
    
    // сабмит формы
    var ring = false;
    (function() {
        var r1Title = resultsBlock.getElement('td.l h3');
        var r1P = resultsBlock.getElement('td.l p');
        var r1Logo  = resultsBlock.getElement('td.l .logo');
        var r1Price = resultsBlock.getElement('td.l .price i');
        var r1OsagoBlock = resultsBlock.getElement('td.l .osago');
        var r1Osago = resultsBlock.getElement('td.l .osago i');
        var r1KaskoPOsago = resultsBlock.getElement('td.l .kaskoOsago span');
        var r1Percent = resultsBlock.getElement('td.l .price .p');
        
        var r2Title = resultsBlock.getElement('td.c h3');
        var r2P = resultsBlock.getElement('td.c p');
        var r2Logo  = resultsBlock.getElement('td.c .logo');
        var r2Price = resultsBlock.getElement('td.c .price i');
        var r2OsagoBlock = resultsBlock.getElement('td.c .osago');
        var r2Osago = resultsBlock.getElement('td.c .osago i');
        var r2KaskoPOsago = resultsBlock.getElement('td.c .kaskoOsago span');
        var r2Percent = resultsBlock.getElement('td.c .price .p');
        
        var r3Title = resultsBlock.getElement('td.r h3');
        var r3P = resultsBlock.getElement('td.r p');
        var r3Logo  = resultsBlock.getElement('td.r .logo');
        var r3Price = resultsBlock.getElement('td.r .price i');
        var r3OsagoBlock = resultsBlock.getElement('td.r .osago');
        var r3Osago = resultsBlock.getElement('td.r .osago i');
        var r3KaskoPOsago = resultsBlock.getElement('td.r .kaskoOsago span');
        var r3Percent = resultsBlock.getElement('td.r .price .p');
        
        var rOPrice = osagoResultsBlock.getElement('i');
        
        var ajax = calculationForm.getElement('.ajax');
        var wrongText = $$('.error-fill')[0];

        var iNeedLabel = iNeedKasko.getParent().getPrevious('span');
        
        var offserKaskoForm = $$('.offer-your-kasko form');
        var offerKaskoField = $$('.offer-your-kasko input.text-field')[0];
        var offerKaskoSubmit = $$('.offer-your-kasko input[type=image]');
        var offerAjax = $$('.offer-your-kasko .ajax')[0];
        
        var enabledFields = [];
        var disableFields = function() {
            enabledFields = calculationForm.getElements('input:enabled, select:enabled');
            enabledFields.each(function(f) {
				f.disabled = true;
            });
        };
        var enableFields = function() {
            enabledFields.each(function(f) {
				f.disabled = false;
            });
			saveData();
        };
        
        // запрос на каско и, возможно, осаго
        var r = new Request.JSON({
            url: calculationForm.get('action'),
            onRequest: function() {
                ring = true;
                returnToCalculationBlock.hide();
                ajax.show();
                disableFields();
                hideAllResultBlocks();
            },
            onSuccess: function(json) {
                if (!json) return;
                var data = json.data;
                resultIds = '';
                
                if (iNeedKasko.checked) {
                    // каско и, возможно, осаго
                    if (data.result_1.length && data.result_2.length && data.result_3.length && data.result_osago.length) {
                        r1Logo.set('src', data.result_1[0].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r1Price.set('html', (data.result_1[0].data.fee + data.result_osago[0].data.fee).formatMoney(0, '', ' '));
                            data.result_1[0].osago = data.result_osago[0];
                        } else {
                            r1Price.set('html', (data.result_1[0].data.fee).formatMoney(0, '', ' '));
                        };
                        r1Order.store('id', data.result_1[0].id);
                        r1Order.store('data', data.result_1[0]);
                        r1Osago.set('html', data.result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r1Percent.set('html', '(' + data.result_1[0].data.percent.formatMoney(1, '.', '') + '%)');

                        r2Logo.set('src', data.result_2[0].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r2Price.set('html', (data.result_2[0].data.fee + data.result_osago[0].data.fee).formatMoney(0, '', ' '));
                            data.result_2[0].osago = data.result_osago[0];
                        } else {
                            r2Price.set('html', (data.result_2[0].data.fee).formatMoney(0, '', ' '));
                        };
                        r2Order.store('id', data.result_2[0].id);
                        r2Order.store('data', data.result_2[0]);
                        r2Osago.set('html', data.result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r2Percent.set('html', '(' + data.result_2[0].data.percent.formatMoney(1, '.', '') + '%)');

                        r3Logo.set('src', data.result_3[0].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r3Price.set('html', (data.result_3[0].data.fee + data.result_osago[0].data.fee).formatMoney(0, '', ' '));
                            data.result_3[0].osago = data.result_osago[0];
                        } else {
                            r3Price.set('html', (data.result_3[0].data.fee).formatMoney(0, '', ' '));
                        };
                        r3Order.store('id', data.result_3[0].id);
                        r3Order.store('data', data.result_3[0]);
                        r3Osago.set('html', data.result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r3Percent.set('html', '(' + data.result_3[0].data.percent.formatMoney(1, '.', '') + '%)');
                        
                        // заполняем таблицу детальных результатов
                        updateDetailedResults(data.result_1[0].data, data.result_2[0].data, data.result_3[0].data);

                        if (iNeedOsago.checked) {
                            r1OsagoBlock.show();
                            r1KaskoPOsago.show();
                            r2OsagoBlock.show();
                            r2KaskoPOsago.show();
                            r3OsagoBlock.show();
                            r3KaskoPOsago.show();
                        } else {
                            r1OsagoBlock.hide();
                            r1KaskoPOsago.hide();
                            r2OsagoBlock.hide();
                            r2KaskoPOsago.hide();
                            r3OsagoBlock.hide();
                            r3KaskoPOsago.hide();
                        };

                        resultsBlock.show();
                        compareResultsButtonBlock.show();
                        sendEmailBlock.show();
                        (function() {
                            windowScroller.toElement(resultsBlock);
                        }).delay(300);
                        r1Title.show();
                        r2Title.show();
                        r3Title.show();
                        r1P.setStyle('fontSize', '');
                        r2P.setStyle('fontSize', '');
                        r3P.setStyle('fontSize', '');
                        
                        // заполняем айдишниками результатов для отправки по почте
                        resultIds = data.result_1[0].resultId + '|' + data.result_2[0].resultId + '|' + data.result_3[0].resultId;
                    } else {
                        wrongResultsBlock.show();
                        (function() {
                            windowScroller.toElement(wrongResultsBlock);
                        }).delay(300);
                    };
                } else {
                    // только осаго
                    rOPrice.set('html', data.result_osago[0].data.fee.formatMoney(0, '', ' '));
                    data.result_osago[0].only_osago = true;
                    rOOrder.store('id', data.result_osago[0].id);
                    rOOrder.store('data', data.result_osago[0]);
                    
                    osagoResultsBlock.show();
                    sendEmailBlock.show();
                    (function() {
                        windowScroller.toElement(osagoResultsBlock);
                    }).delay(300);
                };
                
                resultIds += '|' + data.result_osago[0].resultId;
                
                enableFields();
                ajax.hide();
				$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', false);
                submitButton.disabled = false;
                ring = false;
            },
            onFailure: function() {
                hideAllResultBlocks();
                wrongResultsBlock.show();
                enableFields();
                submitButton.disabled = false;
                ajax.hide();
				$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', false);
                ring = false;
                (function() {
                    windowScroller.toElement(resultsBlock);
                }).delay(300);
            }
        });
        // запрос только на осаго
        var or = new Request.JSON({
            url: offserKaskoForm.get('action'),
            onRequest: function() {
                ring = true;
                returnToCalculationBlock.show();
                ajax.show();
                offerAjax.show();
                disableFields();
            },
            onSuccess: function(json) {
                var result = json.data.result;
                resultIds = '';
                if (result && result.length) {
                    var minPrice = (function() {
                        var tmp = 1000000;
                        for (var i = result.length; i--;) {
                            if (result[i].data.fee < tmp) {
                                tmp = result[i].data.fee;
                            };
                        };
                        return tmp;
                    })();
                    var wantedFee = this.wantedFee.toInt();
                    var result_osago = json.data.result_osago;
                    
                    // показываем блок о том, что не нашли лучшего предложения
                    if (minPrice > wantedFee) {
                        
                    };
                    
                    if (result[0]) {
                        //r1Title.hide();
                        //r1P.setStyle('fontSize', '15px');
                        r1Logo.set('src', result[0].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r1Price.set('html', (result[0].data.fee + result_osago[0].data.fee).formatMoney(0, '', ' '));
                            result[0].osago = result_osago[0];
                        } else {
                            r1Price.set('html', (result[0].data.fee).formatMoney(0, '', ' '));
                        };
                        r1Order.store('id', result[0].id);
                        result[0].fit = true;
                        r1Order.store('data', result[0]);
                        r1Osago.set('html', result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r1Percent.set('html', '(' + result[0].data.percent.formatMoney(1, '.', '') + '%)');
                        
                        resultIds += result[0].resultId;
                    };
                    
                    if (result[1]) {
                        //r2Title.hide();
                        //r2P.setStyle('fontSize', '15px');
						r2Title.set('html', r1Title.get('html'));
						r2P.set('html', r1P.get('html'));
                        r2Logo.set('src', result[1].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r2Price.set('html', (result[1].data.fee + result_osago[0].data.fee).formatMoney(0, '', ' '));
                            result[1].osago = result_osago[0];
                        } else {
                            r2Price.set('html', (result[1].data.fee).formatMoney(0, '', ' '));
                        };
                        r2Order.store('id', result[1].id);
                        result[1].fit = true;
                        r2Order.store('data', result[1]);
                        r2Osago.set('html', result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r2Percent.set('html', '(' + result[1].data.percent.formatMoney(1, '.', '') + '%)');
                        r2Td.show();
                        
                        resultIds += '|' +  result[1].resultId;
                    } else {
                        r2Td.hide();
                    };
                    
                    if (result[2]) {
                        //r3Title.hide();
                        //r3P.setStyle('fontSize', '15px');
						r3Title.set('html', r1Title.get('html'));
						r3P.set('html', r1P.get('html'));
                        r3Logo.set('src', result[2].company_logo_medium);
                        if (iNeedOsago.checked) {
                            r3Price.set('html', (result[2].data.fee + result_osago[0].data.fee).formatMoney(0, '', ' '));
                            result[2].osago = result_osago[0];
                        } else {
                            r3Price.set('html', (result[2].data.fee).formatMoney(0, '', ' '));
                        };
                        r3Order.store('id', result[2].id);
                        result[2].fit = true;
                        r3Order.store('data', result[2]);
                        r3Osago.set('html', result_osago[0].data.fee.formatMoney(0, '', ' '));
                        r3Percent.set('html', '(' + result[2].data.percent.formatMoney(1, '.', '') + '%)');
                        r3Td.show();
                        
                        resultIds += '|' + result[2].resultId;
                    } else {
                        r3Td.hide();
                    };
                    
                    resultIds += '|' + result_osago[0].resultId;
                    
                    // заполняем таблицу детальных результатов
                    if (result.length === 1) {
                        updateDetailedResults(result[0].data, {}, {});
                    } else if (result.length === 2) {
                        updateDetailedResults(result[0].data, result[1].data, {});
                    } else {
                        updateDetailedResults(result[0].data, result[1].data, result[2].data);
                    }
                    
                    if (iNeedOsago.checked) {
                        r1OsagoBlock.show();
                        r1KaskoPOsago.show();
                        r2OsagoBlock.show();
                        r2KaskoPOsago.show();
                        r3OsagoBlock.show();
                        r3KaskoPOsago.show();
                    } else {
                        r1OsagoBlock.hide();
                        r1KaskoPOsago.hide();
                        r2OsagoBlock.hide();
                        r2KaskoPOsago.hide();
                        r3OsagoBlock.hide();
                        r3KaskoPOsago.hide();
                    };

                    resultsBlock.show();
                    sendEmailBlock.show();
                    (function() {
                        windowScroller.toElement(resultsBlock);
                    }).delay(300);
                    
                } else {
                    hideAllResultBlocks();
                    wrongResultsBlock.show();
                    (function() {
                        windowScroller.toElement(wrongResultsBlock);
                    }).delay(300);
                };
                
                enableFields();
                submitButton.disabled = false;
                ajax.hide();
				$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', false);
                offerAjax.hide();
                ring = false;
            },
            onFailure: function() {
                hideAllResultBlocks();
                wrongResultsBlock.show();
                enableFields();
                submitButton.disabled = false;
                ajax.hide();
				$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', false);
                offerAjax.hide();
                ring = false;
                (function() {
                    windowScroller.toElement(wrongResultsBlock);
                }).delay(300);
            }
        });
        
        var validate = function() {
            var error = false;
            
            var manufacturer = carManufacturer.getValue().trim();
            var model = modelsSelect.get('value').trim();
            var year = yearSelect.get('value').trim();
            var price = priceField.get('value').trim().replace(/\s/g, '');
            
            var power = powerSelect.get('value').trim();
            var region = regionSelect.get('value').trim();
            var use = useSelect.get('value').trim();
            var crash = crashSelect.get('value').trim();
            
            var driversCorrect = (function() {
                var correct = true;
                if (driversTable.isVisible()) {
                    driversTable.getElements('input[type=text]').each(function(i) {
                        var v = i.get('value').trim();
                        if (!v.length || !v.match(/^\d+$/)) {
                            i.twitch();
                            correct = false;
                        };
                    });
                };
                if (unlimDriversTable.isVisible()) {
                    unlimDriversTable.getElements('input[type=text]').each(function(i) {
                        var v = i.get('value').trim();
                        if (!v.length || !v.match(/^\d+$/)) {
                            i.twitch();
                            correct = false;
                        };
                    });
                };
                return correct;
            })();
            
            if (!iNeedKasko.checked && !iNeedOsago.checked) {
                error = true;
                iNeedLabel.setStyle('color', 'red').twitch();
            } else {
                iNeedLabel.setStyle('color', '');
            };
            
            if (!driversCorrect) {
                error = true;
            };
            
            if (iNeedKasko.checked) {
                if (!manufacturer.length) {
                    error = true;
                    carManufacturerField.twitch();
                };

                if (!model.length) {
                    error = true;
                    modelsSelect.twitch();
                };

                if (!year.length) {
                    error = true;
                    yearSelect.twitch();
                };

                if (!price.length || !price.match(/^[-+]?[0-9]+(\.[0-9]+)?$/)) {
                    error = true;
                    priceField.twitch();
                };
            };
            
            if (iNeedOsago.checked) {
                if (!power.length) {
                    error = true;
                    powerSelect.twitch();
                };
                
                if (!region.length) {
                    error = true;
                    regionSelect.twitch();
                };
                
                if (!use.length) {
                    error = true;
                    useSelect.twitch();
                };
                
                if (!crash.length) {
                    error = true;
                    crashSelect.twitch();
                };
            };
            
            if (error) {
                wrongText.show();
            } else {
                wrongText.hide();
            };
            
            return !error;
        };
        
        var onCalculationFormSubmit = function(e) {
            if (arguments.length) {
                new Event(e).stop();
            };
			
            if (!ring && validate()) {
				$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', true);
                
                // Временно делаем переход на большой калькулятор
                if (iNeedOsago.checked && !iNeedKasko.checked) {
                    _gaq.push(['_trackEvent', 'mainpage', 'raschet_osago']);
                    r.send(calculationForm.toQueryString());
                } else {
                    _gaq.push(['_trackEvent', 'mainpage', 'perehod_na_preload']);
                    window.location = '/preload-page/';
                };
            } else {
                _gaq.push(['_trackEvent', 'mainpage', 'forma_zapolnena_neverno']);
                submitButton.disabled = false;
            };
        };
        
        calculationForm.addEvent('submit', onCalculationFormSubmit);
        
        // предложение своей цены каски
        (function() {
            offerKaskoField.addEvent('keydown', justNumber);
            offserKaskoForm.addEvent('submit', function(e){
                var event = new Event(e).stop();
                
                if (ring) return;
                
                var fee = offerKaskoField.get('value').trim();
                if (fee.length) {
                    or.wantedFee = fee;
					$$('input[type=checkbox][name=unlimited_drivers]')[0].set('disabled', true);
                    or.send(calculationForm.toQueryString() + '&fee=' + fee);
                } else {
                    offerKaskoField.twitch();
                };
            });
            returnToCalculationButton.addEvent('click', function(e){
                var event = new Event(e);
                event.stop();
                hideAllResultBlocks();
                windowScroller.start(0, 0);
                onCalculationFormSubmit();
            });
        })();
    })();

    // если показываются результаты и мы что-нибудь меняем, то результаты скрываются
    calculationForm.getElements('input, select').each(function(f) {
        f.addEvent('change', function() {
            hideAllResultBlocks();
        });
    });
    var hideAllResultBlocks = function() {
        resultsBlock.hide();
        osagoResultsBlock.hide();
        wrongResultsBlock.hide();
        sendEmailBlock.hide();
        detailedResultsBlock.hide();
        compareResultsButtonBlock.hide();
        
        r1Td.show();
        r2Td.show();
        r3Td.show();
    };

    // заказ
    var orderForm = new OrderForm('order-form-container');
    orderForm.setSourceForm(calculationForm);
    orderForm.setOverlay($(document.body).getElement('.overlay'));
	
    r1Order.addEvent('click', function(e){
        var event = new Event(e).stop();
        
        if (ring) return;
        
        var d = this.retrieve('data');
        d.col = 1;

		current_order_id = resultIds.split('|')[0];
        orderForm.show(this.retrieve('id'), d);
    });
    r2Order.addEvent('click', function(e){
        var event = new Event(e).stop();
        
        if (ring) return;
        
        var d = this.retrieve('data');
        d.col = 2;
        
		current_order_id = resultIds.split('|')[1];
        orderForm.show(this.retrieve('id'), d);
    });
    r3Order.addEvent('click', function(e){
        var event = new Event(e).stop();
        
        if (ring) return;
        
        var d = this.retrieve('data');
        d.col = 3;
        
		current_order_id = resultIds.split('|')[2];
        orderForm.show(this.retrieve('id'), d);
    });
    rOOrder.addEvent('click', function(e){
        var event = new Event(e).stop();
        var d = this.retrieve('data');
        orderForm.show(this.retrieve('id'), d);
    });

    // восстановление из куки
    (function() {
        
        if ($get('brand')) return;
        
        var data = Cookie.read('form'); if (!data) return;
        var restoreData = $get('b'); if (restoreData.length) data = decodeURIComponent(Base64.decode(restoreData).replace(/\+/g, ' '));
        var splitData = data.split('&');
        var splitDataLength = splitData.length;
        var keyArray = [];
        var valueArray = [];
        for (var i = 0; i < splitDataLength; i++) {
            var sp = splitData[i].split('=');
            keyArray.push(decodeURIComponent(sp[0]));
            valueArray.push(decodeURIComponent(sp[1]));
        };
        
        var kaskoChecked  = false;
        var osagoChecked  = false;
        var iAmFizChecked = false;
        var iAmUrChecked  = false;
        var unlimChecked  = false;
        
        var ages = [];
        var experiences = [];
        
        for (i = 0; i < splitDataLength; i++) {
            if (keyArray[i] == 'car_manufacturer') {
                carManufacturerField.set('value', valueArray[i]);
            };
            if (keyArray[i] == 'car_cost') {
                if (valueArray[i].indexOf(' ') != -1) {
                    priceField.set('value', valueArray[i]);
                } else {
                    priceField.set('value', valueArray[i].toInt().formatMoney(0, '', ' '));
                };
            };
            if (keyArray[i] == 'car_year') {
                yearSelect.set('value', valueArray[i]);
            };
            if (keyArray[i] == 'car_region') {
                regionSelect.set('value', valueArray[i]);
            };
            if (keyArray[i] == 'power') {
                powerSelect.set('value', valueArray[i]);
            };
            if (keyArray[i] == 'use_period') {
                useSelect.set('value', valueArray[i]);
            };
            if (keyArray[i] == 'crash_period') {
                crashSelect.set('value', valueArray[i]);
            };
            if (keyArray[i].match(/type\[\d?\]/)) {
                if (valueArray[i] == 'osago') osagoChecked = true;
                if (valueArray[i] == 'kasko') kaskoChecked = true;
            };
            if (keyArray[i].match(/client_type\[\d?\]/)) {
                if (valueArray[i] == 'fiz') iAmFizChecked = true;
                if (valueArray[i] == 'ur') iAmUrChecked = true;
            };
            if (keyArray[i] == 'unlimited_drivers') {
				var input_hidden = $$('input[type=hidden][name=unlimited_drivers]')[0];
				var input_checkbox = $$('input[type=checkbox][name=unlimited_drivers]')[0];
                if (valueArray[i] == '1') {
					input_hidden.set('value', '1');
					input_checkbox.set('value', '1');
					input_checkbox.setProperty('checked', 'checked');
					unlimChecked = true;
				} else {
					input_hidden.set('value', '0');
					input_checkbox.set('value', '0');
					input_checkbox.removeProperty('checked');
					unlimChecked = false;
				}
            };
            if (keyArray[i].indexOf('age') != -1) {
                ages.push(valueArray[i]);
            };
            if (keyArray[i].indexOf('experience') != -1) {
                experiences.push(valueArray[i]);
            };
            if (keyArray[i] == 'car_model') {
                modelsRequest.options.selectedModel = valueArray[i];
            };
            if (keyArray[i] == 'car_modification') {
                modelsRequest.options.selectedModification = valueArray[i];
            };
            if (keyArray[i] == 'warranty_car') {
                onWarranty.checked = true;
                refType.set('value', 'stoa_dealer');
            }
        };
        
        iNeedKasko.checked = kaskoChecked;
        iNeedOsago.checked = osagoChecked;
		//iAmFiz.checked = iAmFizChecked;
        //iUrFiz.checked = iAmUrChecked;
        //unlimCheckbox.checked = unlimChecked;
        checkState();
        
        if (iNeedKasko.checked) {
            (function() {
                priceTipShow();
            }).delay(1000);
        };
        
        if (driversTable.isVisible()) {
            for (var i = 0; i < ages.length; i++) {
                if (i == 0) {
                    var tr = driversTable.getElement('tr');
                    var af = tr.retrieve('ageField');
                    var ef = tr.retrieve('experienceField');
                    af.set('value', ages[0]);
                    ef.set('value', experiences[0]);
                    af.retrieve('caser').doCase();
                    ef.retrieve('caser').doCase();
                } else {
                    addTrWithData(ages[i], experiences[i]);
                };
            };
        };
        if (unlimDriversTable.isVisible()) {
            var tr = unlimDriversTable.getElement('tr');
            var af = tr.retrieve('ageField');
            var ef = tr.retrieve('experienceField');
            
            if (ages.length) {
                af.set('value', ages[0]);
                ef.set('value', experiences[0]);
                af.retrieve('caser').doCase();
                ef.retrieve('caser').doCase();
            };
        };
        if (carManufacturer.getValue().trim().length) {
            // говорим запросу моделей/модификаций/цен о том, что он был вызван из кук
            modelsRequest.options['restore'] = true;
            modelsRequest.send('brand=' + encodeURIComponent(carManufacturer.getValue().trim()) + '&year=' + encodeURIComponent(yearSelect.get('value').trim()) + '&type=model');
        };
    })();

    // восстановление из гета
    (function() {
        var brand = $get('brand');
        var model = $get('model');
        
        if (brand && brand.length) {
            var y = (new Date).getFullYear() - 1;
            yearSelect.set('value', y);
            carManufacturer.setValue(brand);
            if (model && model.length) {
                modelsRequest.options.selectedModel = model;
            };
            modelsRequest.send('brand=' + encodeURIComponent(brand) + '&year=' + encodeURIComponent(y) + '&type=model');
        };
    })();

    // перезвоните мне
    (function() {
        var callbackPopup = $$('.call-back-form')[0];
        var callbackForm = callbackPopup.getFirst();
        var callbackInput = callbackForm.getElement('input');
        var link = $$('.call-back a')[0];
        var titleSpan = callbackForm.getElement('span');
        var formContent = callbackForm.getElement('.form-content');
        
        if (window.Meio && Meio.Mask) {
            callbackInput.meiomask('Fixed', 'Phone-us', {autoSetSize: true});
        };
        
        var r = new Request.JSON({
            url: callbackForm.get('action'),
            onRequest: function() {
                running = true;
            },
            onSuccess: function(json) {
                titleSpan.setStyle('color', '#16701E').set('text', 'Мы обязательно свяжемся с Вами в ближайшее время');
                
                var coords = titleSpan.getCoordinates(titleSpan.getParent('.call-back-form'));
                var top = coords.top;
                var left = coords.left;
                
                new Fx.Morph(titleSpan, {
                    duration: 300,
                    transition: Fx.Transitions.Quint.easeOut,
                    onStart: function() {
                        formContent.hide();
                        titleSpan.setStyle('position', 'absolute');
                    }
                }).start({
                    top: [top, 11],
                    fontSize: [titleSpan.getStyle('fontSize').toInt(), 15],
                    left: [left, 32],
                    lineHeight: [titleSpan.getStyle('lineHeight').toInt(), 23]
                });
                
                running = false;
            }
        });
        var running = false;
        
        link.addEvent('click', function(e) {
            new Event(e).stop();
            callbackPopup.show(true);
            (function() {
                callbackInput.focus();
            }).delay(150);
        });
        
        callbackForm.addEvent('submit', function(e) {
            new Event(e).stop();
            
            if (running) return;
            
            var error = false;
            var phone = callbackInput.get('value').trim();
            
            if (!phone.length || !phone.match(/[\d\-]+/)) {
                error = true;
                callbackInput.twitch();
            };
            
            if (!error) {
                _gaq.push(['_trackEvent', 'mainpage', 'perezvonite_mne']);
                r.send(callbackForm.toQueryString());
            };
        });
    })();
	
	(function() {
		$$('input[type=checkbox][name=unlimited_drivers]')[0].addEvent('change', function() {
			this.set('value', +this.checked);
			$$('input[type=hidden][name=unlimited_drivers]')[0].set('value', +this.checked);
		});
	})();
	
	// заплатка на размер селекта в IE
	if (Browser.ie7 || Browser.ie8) {
		$$([modelsSelect, modificationsSelect]).addEvent('focus', function() {
			var Width = this.scrollWidth + 10;
			if (Width < 145) { Width = 145; }
		
			this.set('disabled', false);
			this.setStyle('width', Width);
		});
        $$([modelsSelect, modificationsSelect]).addEvent('blur', function() {
			this.set('disabled', false);
			this.setStyle('width', 145);
		});
		$$([regionSelect]).addEvent('focus', function() {
			var Width = this.scrollWidth + 20;
			if (Width < 180) { Width = 180; }
		
			this.set('disabled', false);
			this.setStyle('width', Width);
		});
        $$([regionSelect, regionSelect]).addEvent('blur', function() {
			this.set('disabled', false);
			this.setStyle('width', 180);
		});
	};
	
	// сео текст на главной странице
	(function() {
	    var b1 = $('but1');
	    var b2 = $('but2');
	    var b3 = $('but3');
	    
	    var bl1 = $('block1');
	    var bl2 = $('block2');
	    var bl3 = $('block3');
	    
	    bl1.setStyles({
	        'height': 0,
	        'borderWidth': 0
	    }).setStyle('display', 'block');
	    bl2.setStyles({
	        'height': 0,
	        'borderWidth': 0
	    }).setStyle('display', 'block');
	    bl3.setStyles({
	        'height': 0,
	        'borderWidth': 0
	    }).setStyle('display', 'block');
	    
	    var b1height = bl1.getFirst().getDimensions().y + 15;
	    var b2height = bl2.getFirst().getDimensions().y;
	    var b3height = bl3.getFirst().getDimensions().y;
	    
	    var m1 = bl1.get('morph'); m1.options.transition = Fx.Transitions.Cubic.easeInOut;
	    var m2 = bl2.get('morph'); m2.options.transition = Fx.Transitions.Cubic.easeInOut;
	    var m3 = bl3.get('morph'); m3.options.transition = Fx.Transitions.Cubic.easeInOut;
	    
	    b1.addEvent('click', function(e) {
	        new Event(e).stop();
	        
	        if (!m1.isRunning() && !m2.isRunning() && !m3.isRunning()) {
	            if (bl1.getDimensions().y === 0) {
	                b1.addClass('selected');
	                m1.start({
	                    'height': b1height,
	                    'borderWidth': 1
	                });
	                
	                b2.removeClass('selected');
	                m2.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	                b3.removeClass('selected');
	                m3.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            } else {
	                b1.removeClass('selected');
	                m1.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            };
	        };
	    });
	    b2.addEvent('click', function(e) {
	        new Event(e).stop();
	        
	        if (!m1.isRunning() && !m2.isRunning() && !m3.isRunning()) {
	            if (bl2.getDimensions().y === 0) {
	                b2.addClass('selected');
	                m2.start({
	                    'height': b2height,
	                    'borderWidth': 1
	                });
	                
	                b1.removeClass('selected');
	                m1.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	                b3.removeClass('selected');
	                m3.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            } else {
	                b2.removeClass('selected');
	                m2.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            };
	        };
	    });
	    b3.addEvent('click', function(e) {
	        new Event(e).stop();
	        
	        if (!m1.isRunning() && !m2.isRunning() && !m3.isRunning()) {
	            if (bl3.getDimensions().y === 0) {
	                b3.addClass('selected');
	                m3.start({
	                    'height': b3height,
	                    'borderWidth': 1
	                });
	                
	                b1.removeClass('selected');
	                m1.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	                b2.removeClass('selected');
	                m2.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            } else {
	                b3.removeClass('selected');
	                m3.start({
	                    'height': 0,
	                    'borderWidth': 0
	                });
	            };
	        };
	    });
	})();
	
});

if (Browser.name == 'ie' && (Browser.version == '7' || Browser.version == '8')) {
    window.addEvent('beforeunload', function() {
        // гыгы
        saveData();
    });
} else {
    window.addEvent('unload', function() {
        // гыгы
        saveData();
    });
}

/*
---

name: Meio.Mask

description: The base component for the Meio.Mask plugin.

authors:
  - Fábio Miranda Costa

requires:
  - Core/Class.Extras
  - Core/Element.Event
  - Core/Element.Style
  - More/Element.Forms

license: MIT-style license

provides: [Meio.Mask]

...
*/

(function(global, $){

	var Meio = global.Meio || {};

	// credits to Jan Kassens
	Object.append(Element.NativeEvents, {
		'paste': 2, 'input': 2
	});
	Element.Events.paste = {
		base : (Browser.Platform.ios || Browser.opera || (Browser.firefox && Browser.version < 3))? 'input': 'paste',
		condition: function(e){
			this.fireEvent('paste', e, 1);
			return false;
		}
	};

	Meio.Mask = new Class({

		Implements: [Options, Events],

		options: {
			autoTab: false

			//onInvalid: function(){},
			//onValid: function(){},

			//REVERSE MASK OPTIONS
			//autoSetSize: false,
			//autoEmpty: false,
			//alignText: true,
			//symbol: '',
			//precision: 2,
			//decimal: ',',
			//thousands: '.',
			//maxLength: 18

			//REPEAT MASK OPTIONS
			//mask: '',
			//maxLength: 0 // 0 for infinite

			//REGEXP MASK OPTIONS
			//regex: null
		},

		initialize: function(options){
			this.setOptions(options);
			this.ignore = false;
			this.bound = {focus: 0, blur: 0, keydown: 0, keypress: 0, paste: 0};
		},

		link: function(element){
			element = $(element);
			if (element.get('tag') != 'input') return;
			if (this.element) this.unlink();
			this.element = element;
			return this.attach();
		},

		unlink: function(){
			return this.detach();
		},

		attach: function(){
			var self = this;
			if (this.maxlength == null) this.maxlength = this.element.get('maxLength');
			this.element.removeAttribute('maxLength');
			for (var evt in this.bound){
				this.bound[evt] = (function(onMask, func){
					return function(e) {
						return onMask.call(self, e, func);
					}
				})(this.onMask, this[evt]);
				this.element.addEvent(evt, this.bound[evt]);
			}
			var elementValue = this.element.get('value');
			if (elementValue != '') this.element.set('value', this.mask(elementValue));
			return this;
		},

		detach: function(){
			var maxlength = this.maxlength;
			if (maxlength != null) this.element.set('maxlength', maxlength);
			for (var evt in this.bound){
				this.element.removeEvent(evt, this.bound[evt]);
				this.bound[evt] = 0;
			}
			this.element = null;
			return this;
		},

		dettach: function(){ this.detach(); }, // deprecated (incorrect syntax, sorry), use detach instead

		onMask: function(e, func){
			if (this.element.get('readonly')) return true;
			var o = {}, event = e.event, keyCode = (e.type == 'paste') ? null : event.keyCode;
			o.range = this.element.getSelectedRange();
			o.isSelection = (o.range.start !== o.range.end);
			// 8 == backspace && 46 == delete && 127 == iphone's delete
			o.isDelKey = (keyCode == 46 && (event.type != 'keypress' || ((Browser.firefox || Browser.opera) && !event.which)));
			o.isBksKey = (keyCode == 8 || (Browser.Platform.ios && e.code == 127));
			o.isRemoveKey = (o.isBksKey || o.isDelKey);
			func && func.call(this, e, o);
			return true;
		},

		keydown: function(e, o){
			this.ignore = (Meio.Mask.ignoreKeys[e.code] && !o.isRemoveKey) || e.control || e.meta || e.alt;
			if (this.ignore || o.isRemoveKey){
				var keyRepresentation = Meio.Mask.ignoreKeys[e.code] || '';
				this.fireEvent('valid', [this.element, e.code, keyRepresentation]);
			}
			return (Meio.Mask.onlyKeyDownRepeat && o.isRemoveKey) ? this.keypress(e, o) : true;
		},

		keypress: function(e, o){
			if (this.options.autoTab && this.shouldFocusNext()){
				var nextField = this.getNextInput();
				if (nextField){
					nextField.focus();
					if (nextField.select) nextField.select();
				}
			}
			return true;
		},

		focus: function(e, o){
			var element = this.element;
			element.store('meiomask:focusvalue', element.get('value'));
		},

		blur: function(e, o){
			var element = this.element;
			if (e && element.retrieve('meiomask:focusvalue') != element.get('value')){
				element.fireEvent('change');
			}
		},

		getCurrentState: function(e, o){
			var _char = String.fromCharCode(e.code),
				elValue = this.element.get('value');
			var start = o.range.start, end = o.range.end;
			if (o.isRemoveKey && !o.isSelection) o.isDelKey ? end++ : start--;
			return {value: elValue.substring(0, start) + (o.isRemoveKey ? '' : _char) + elValue.substring(end),
				_char: _char, start: start, end: end};
		},

		setSize: function(){
			if (!this.element.get('size')) this.element.set('size', this.maskArray.length);
		},

		shouldFocusNext: function(){
			var maxLength = this.options.maxLength;
			return maxLength && this.element.get('value').length >= maxLength;
		},

		getNextInput: function(){
			var fields = Array.from(this.element.form.elements), field;
			for (var i = fields.indexOf(this.element) + 1, l = fields.length; i < l; i++){
				field = fields[i];
				if (this.isFocusableField(field)) return $(field);
			}
			return null;
		},

		isFocusableField: function(field){
			return (field.offsetWidth > 0 || field.offsetHeight > 0) // is it visible?
				&& field.nodeName.toLowerCase() != 'fieldset';
		},

		isFixedChar: function(_char){
			return !Meio.Mask.matchRules.contains(_char);
		},

		mask: function(str){
			return str;
		},

		unmask: function(str){
			return str;
		}

	});

	Meio.Mask.extend({

		matchRules: '',

		rulesRegex: new RegExp(''),

		rules: {},

		setRule: function(ruleKey, properties){
			this.setRules({ruleKey: properties});
		},

		setRules: function(rulesObj){
			Object.append(this.rules, rulesObj);
			var rulesKeys = [];
			for (rule in rulesObj) rulesKeys.push(rule);
			this.matchRules += rulesKeys.join('');
			this.recompileRulesRegex();
		},

		removeRule: function(rule){
			delete this.rules[rule];
			this.matchRules = this.matchRules.replace(rule, '');
			this.recompileRulesRegex();
		},

		removeRules: function(){
			var rulesToRemove = Array.flatten(arguments);
			for (var i=rulesToRemove.length; i--;) this.removeRule(rulesToRemove[i]);
		},

		recompileRulesRegex: function(){
			this.rulesRegex.compile('[' + this.matchRules.escapeRegExp() + ']', 'g');
		},

		createMasks: function(type, masks){
			type = type.capitalize();
			for (mask in masks){
				this[type][mask.camelCase().capitalize()] = new Class({
					Extends: this[type],
					options: masks[mask]
				});
			}
		},

		// credits to Christoph Pojer's (cpojer) http://cpojer.net/
		upTo: function(number){
			number = '' + number;
			return function(value, index, _char){
				if (value.charAt(index-1) == number[0])
					return (_char <= number[1]);
				return true;
			};
		},

		// http://unixpapa.com/js/key.html
		// if only the keydown auto-repeats
		// if you have a better implementation of this detection tell me
		onlyKeyDownRepeat: !!(Browser.ie || Browser.chrome || (Browser.safari && Browser.version >= 4))

	}).extend(function(){
		var ignoreKeys;
		var desktopIgnoreKeys = {
			8		: 'backspace',
			9		: 'tab',
			13		: 'enter',
			16		: 'shift',
			17		: 'control',
			18		: 'alt',
			27		: 'esc',
			33		: 'page up',
			34		: 'page down',
			35		: 'end',
			36		: 'home',
			37		: 'left',
			38		: 'up',
			39		: 'right',
			40		: 'down',
			45		: 'insert',
			46		: 'delete',
			224		: 'command'
		},
		iphoneIgnoreKeys = {
			10		: 'go',
			127		: 'delete'
		};

		if (Browser.Platform.ios){
			ignoreKeys = iphoneIgnoreKeys;
		} else {
			// f1, f2, f3 ... f12
			for (var i=1; i<=12; i++) desktopIgnoreKeys[111 + i] = 'f' + i;
			ignoreKeys = desktopIgnoreKeys;
		}
		return {ignoreKeys: ignoreKeys};
	}())
	.setRules((function(){
		var rules = {
			'z': {regex: /[a-z]/},
			'Z': {regex: /[A-Z]/},
			'a': {regex: /[a-zA-Z]/},
			'*': {regex: /[0-9a-zA-Z]/},
			'@': {regex: /[0-9a-zA-ZçáàãâéèêíìóòõôúùüñÇÁÀÃÂÉÈÊÍÌÓÒÕÔÚÙÜÑ]/}, // 'i' regex modifier doesnt work well with unicode chars
			'h': {regex: /[0-9]/, check: Meio.Mask.upTo(23)},
			'd': {regex: /[0-9]/, check: Meio.Mask.upTo(31)},
			'm': {regex: /[0-9]/, check: Meio.Mask.upTo(12)}
		};
		for (var i=0; i<=9; i++) rules[i] = {regex: new RegExp('[0-' + i + ']')};
		return rules;
	})());

	global.Meio = Meio;

})(this, document.id);




/*
---

name: Meio.Mask.Fixed

description: A mask used for fixed values like date, time, phone, etc.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Fixed]

...
*/

Meio.Mask.Fixed = new Class({

	Extends: Meio.Mask,

	options: {
		autoSetSize: false,
		placeholder: '_',
		removeIfInvalid: false, // removes the value onblur if the input is not valid
		removeInvalidTrailingChars: true
	},

	initialize: function(options){
		this.parent(options);
		this.slice = Array.prototype.slice;
		this.maskArray = this.options.mask.split('');
		this.maskMold = this.options.mask.replace(Meio.Mask.rulesRegex, this.options.placeholder).split('');
		this.maskMoldEmpty = this.slice.call(this.maskMold);
		this.validIndexes = [];
		this.maskArray.each(function(c, i){
			if (!this.isFixedChar(c)) this.validIndexes.push(i);
		}, this);
		this.createUnmaskRegex();
	},

	link: function(element){
		this.parent(element);
		var elementValue = this.element.get('value');
		if (elementValue != ''){
			var maskedValue = this.mask(elementValue);
			for (var i = maskedValue.length; i--;){
				this.maskMold[i] = maskedValue.charAt(i);
			}
		}
		if (this.options.autoSetSize) this.setSize();
		return this;
	},

	focus: function(e, o){
		var elementValue = this.maskMold.join('');
		this.element.set('value', elementValue);
		this.focusTimeout = this.element.setCaretPosition.delay(0, this.element, [this.getLastValidIndex(elementValue)]);
		this.parent(e, o);
	},

	blur: function(e, o){
		this.parent(e, o);
		clearTimeout(this.focusTimeout);
		var elementValue = this.element.get('value');
		if (this.options.removeIfInvalid){
			if (elementValue.contains(this.options.placeholder)){
				this.maskMold = this.slice.call(this.maskMoldEmpty, 0);
				this.element.set('value', '');
			}
			return true;
		}
		if (this.options.removeInvalidTrailingChars) this.element.set('value', this.removeInvalidTrailingChars(elementValue));
		return true;
	},

	keypress: function(e, o){
		if (this.ignore) return true;
		e.preventDefault();

		var c = String.fromCharCode(e.code),
			maskArray = this.maskArray,
			start, i, returnFromTestEntry;

		if(!o.isSelection){
			// no text selected
			var finalRangePosition;
			if (o.isBksKey){
				do {
					start = this.validIndexes.indexOf(--o.range.start);
				} while (start == -1 && o.range.start >= 0);
				finalRangePosition = this.validIndexes[start] || 0;
			} else {
				do {
					start = this.validIndexes.indexOf(o.range.start++);
				} while (start == -1 && o.range.start < maskArray.length);
				finalRangePosition = (start == -1) ? this.maskMold.length : this.validIndexes[start + 1];
			}

			i = this.validIndexes[start];
			if (!(returnFromTestEntry = this.testEvents(i, c, e.code, o.isRemoveKey))) return true;
			if (typeof returnFromTestEntry == 'string') c = returnFromTestEntry;
			this.maskMold[i] = (o.isRemoveKey) ? this.options.placeholder : c;

			var newCarretPosition = (finalRangePosition == null) ? this.maskMold.length : finalRangePosition;
			this.element.set('value', this.maskMold.join(''))
				.setCaretPosition(newCarretPosition);

		} else {

			var rstart = o.range.start,
				rend = o.range.end,
				end;

			// text selected
			do {
				start = this.validIndexes.indexOf(o.range.start++);
			} while(start == -1 && o.range.start < maskArray.length);
			do {
				end = this.validIndexes.indexOf(o.range.end++);
			} while(end == -1 && o.range.end < maskArray.length);

			// if  you select a fixed char it will ignore your input
			if (!(end - start)) return true;

			// removes all the chars into the range
			for (i=rstart; i<rend; i++){
				this.maskMold[i] = this.maskMoldEmpty[i];
			}

			if (!o.isRemoveKey){
				i = this.validIndexes[start];
				if (!(returnFromTestEntry = this.testEvents(i, c, e.code, o.isRemoveKey))) return true;
				if (typeof returnFromTestEntry == 'string') c = returnFromTestEntry;
				this.maskMold[i] = c;
				start++;
			}

			this.element.set('value', this.maskMold.join(''));
			this.element.setCaretPosition(this.validIndexes[start]);
		}
		return this.parent();
	},

	paste: function(e, o){
		var retApply = this.applyMask(this.element.get('value'), o.range.start);
		this.maskMold = retApply.value;
		this.element.set('value', this.maskMold.join(''))
			.setCaretPosition(retApply.rangeStart);
		return true;
	},

	getLastValidIndex: function(elementValue){
		var lastValidIndex = elementValue.length,
			placeholder = this.options.placeholder,
			i = elementValue.length - 1,
			cont;
		while (i >= 0){
			cont = false;
			while (this.isFixedChar(elementValue.charAt(i)) && elementValue.charAt(i) !== placeholder){
				if (i == 0) lastValidIndex = 0;
				cont = true;
				i--;
			}
			while (elementValue.charAt(i) === placeholder){
				lastValidIndex = i;
				cont = true;
				i--;
			}
			if (!cont) break;
		}
		return lastValidIndex;
	},

	removeInvalidTrailingChars: function(elementValue){
		return elementValue.substring(0, this.getLastValidIndex(elementValue));
	},

	testEvents: function(index, _char, code, isRemoveKey){
		var maskArray = this.maskArray,
			rule = Meio.Mask.rules[maskArray[index]],
			returnFromTestEntry;
		if (!isRemoveKey){
			var args = [this.element, code, _char];
			if (!rule || !(returnFromTestEntry = this.testEntry(this.element.get('value'), index, _char))){
				this.fireEvent('invalid', args);
				return false;
			}
			this.fireEvent('valid', args);
		}
		return (returnFromTestEntry != null) ? returnFromTestEntry : true;
	},

	shouldFocusNext: function(){
		return this.unmask(this.element.get('value')).length >= this.validIndexes.length;
	},

	createUnmaskRegex: function(){
		var fixedCharsArray = [].combine(this.options.mask.replace(Meio.Mask.rulesRegex, '').split(''));
		var chars = (fixedCharsArray.join('') + this.options.placeholder).escapeRegExp();
		this.unmaskRegex = chars ? new RegExp('[' + chars + ']', 'g') : null;
	},

	testEntry: function(str, index, _char){
		var maskArray = this.maskArray,
			rule = Meio.Mask.rules[maskArray[index]],
			ret = (rule && rule.regex.test(_char));
		return (rule.check && ret) ? rule.check(str, index, _char) : ret;
	},

	applyMask: function(str, newRangeStart){
		var strArray = str.split(''),
			maskArray = this.maskArray,
			maskMold = this.maskMold,
			rules = Meio.Mask.rules,
			eli = 0,
			returnFromTestEntry;

		while (eli < maskMold.length){
			if (!strArray[eli]){
				strArray[eli] = maskMold[eli];
			} else if (rules[maskArray[eli]]){
				if (!(returnFromTestEntry = this.testEntry(str, eli, strArray[eli]))){
					strArray.splice(eli, 1);
					continue;
				} else {
					if (typeof returnFromTestEntry == 'string') strArray[eli] = returnFromTestEntry;
				}
				newStartRange = eli;
			} else if (maskArray[eli] != strArray[eli]){
				strArray.splice(eli, 0, maskMold[eli]);
			} else {
				strArray[eli] = maskMold[eli];
			}
			eli++;
		}

		return {value: strArray.slice(0, this.maskMoldEmpty.length), rangeStart: newRangeStart + 1};
	},

	mask: function(str){
		str = this.applyMask(str).value.join('');
		if (this.options.removeInvalidTrailingChars) str = this.removeInvalidTrailingChars(str);
		return str;
	},

	unmask: function(str){
		return this.unmaskRegex ? str.replace(this.unmaskRegex, '') : str;
	}

});


Meio.Mask.createMasks('Fixed', {
    'LocalPhone': {mask: '999-9999'},
	'Phone'		: {mask: '(99) 9999-9999'},
	'PhoneUs'	: {mask: '(999) 999-9999'},
	'Cpf'		: {mask: '999.999.999-99'},
	'Cnpj'		: {mask: '99.999.999/9999-99'},
	'Date'		: {mask: '3d/1m/9999'},
	'DateUs'	: {mask: '1m/3d/9999'},
	'Cep'		: {mask: '99999-999'},
	'Time'		: {mask: '2h:59'},
	'Cc'		: {mask: '9999 9999 9999 9999'}
});


/*
---

name: Meio.Mask.Reverse

description: A mask used for currency and decimal numbers.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Reverse]

...
*/

Meio.Mask.Reverse = new Class({

	Extends: Meio.Mask,

	options: {
		autoSetSize: false,
		autoEmpty: false,
		alignText: true,
		symbol: '',
		precision: 2,
		decimal: ',',
		thousands: '.',
		maxLength: 18
	},

	initialize: function(options){
		this.parent(options);
		var thousandsChar = this.options.thousands,
			escapedThousandsChars = thousandsChar.escapeRegExp(),
			escapedDecimalChar = this.options.decimal.escapeRegExp();
		this.maxlength = this.options.maxLength;
		this.reThousands = /(\d+)(\d{3})/;
		this.reRemoveLeadingZeros = /^0+(.*)$/;
		this.reDecimalNumber = /^\d$/;
		this.thousandsReplaceStr = '$1' + thousandsChar + '$2';
		this.reThousandsReplace = new RegExp(escapedThousandsChars, 'g');
		this.reCleanup = new RegExp('[' + escapedThousandsChars + escapedDecimalChar + ']', 'g');
		this.reRemoveNonNumbers = new RegExp('[^\\d' + escapedThousandsChars + escapedDecimalChar + ']', 'g');
	},
	
	link: function(element){
		this.parent(element);
		if (this.options.alignText) this.element.setStyle('text-align', 'right');
		var elementValue = this.element.get('value');
		if (elementValue === '' && !this.options.autoEmpty){
			this.element.set('value', this.forceMask(elementValue, false));
		}
		return this;
	},

	focus: function(e, o){
		var element = this.element,
			elValue = element.get('value');
		if (this.options.autoEmpty){
			if (elValue === '') element.set('value', this.mask(elValue));
		} else {
			element.set('value', this.getValue(elValue, true));
		}
		this.parent(e, o);
	},

	blur: function(e, o){
		this.parent(e, o);
		var element = this.element,
			value = this.getValue(element.get('value'));
		if (this.options.autoEmpty && this.mask(value) == this.mask()) value = '';
		element.set('value', value);
	},

	keypress: function(e, o){
		if (this.ignore) return true;
		e.preventDefault();
		
		var state = this.getCurrentState(e, o), elementValue = state.value;
		
		if (!this.testEvents(elementValue, state._char, e.code, o.isRemoveKey)) return true;
		elementValue = this.forceMask(elementValue, true);
		this.element.set('value', elementValue).setCaretPosition(elementValue.length);
		
		return this.parent();
	},

	testEvents: function(elementValue, _char, code, isRemoveKey){
		var args = [this.element, code, _char];
		if (!isRemoveKey){
			var elementValueLength = this.getValue(elementValue, false).length;
			if (!(this.reDecimalNumber).test(_char) || (this.maxlength && elementValueLength > this.maxlength)){
				this.fireEvent('invalid', args);
				return false;
			}
			this.fireEvent('valid', args);
		}
		return true;
	},

	paste: function(e, o){
		var element = this.element;
		elValue = element.get('value');
		element.set('value', (elValue = this.forceMask(elValue, true))).setCaretPosition(elValue.length);
		return true;
	},

	forceMask: function(str, applySymbol){
		str = this.cleanup(str);
		var precision = this.options.precision;
		var zeros = precision + 1 - str.length;
		if (zeros > 0) str = this.zeroize(str, zeros);
		if (precision){
			var decimalIndex = str.length - precision;
			str = str.substring(0, decimalIndex) + this.options.decimal + str.substring(decimalIndex);
		}
		return this.getValue(this.maskThousands(str), applySymbol);
	},

	cleanup: function(str){
		return this.getValue(str.replace(this.reCleanup, '')).replace(this.reRemoveLeadingZeros, '$1');
	},

	mask: function(str){
		str = this.unmask(str || '0').replace('.', this.options.decimal);
		return this.getValue(this.maskThousands(str), false);
	},

	unmask: function(str){
		return this.toNumber(this.getValue(str));
	},
	
	toNumber: function(str){
		str = str.replace(this.reRemoveNonNumbers, '');
		if (!isFinite(str)){
			if (this.options.thousands) str = str.replace(this.reThousandsReplace, '');
			var decimalChar = this.options.decimal;
			if (decimalChar) str = str.replace(decimalChar, '.');
		}
		return str.toFloat().toFixed(this.options.precision);
	},

	getValue: function(str, applySymbol){
		var symbol = this.options.symbol;
		return (str.substring(0, symbol.length) === symbol) ?
			applySymbol ? str : str.substring(symbol.length) :
			applySymbol ? symbol + str : str;
	},

	maskThousands: function(str){
		if (this.options.thousands){
			while (this.reThousands.test(str)) str = str.replace(this.reThousands, this.thousandsReplaceStr);
		}
		return str;
	},

	zeroize: function(str, zeros){
		while (zeros--) str = '0' + str;
		return str;
	},

	shouldFocusNext: function(){
		return this.getValue(this.element.get('value'), false).length >= this.options.maxLength;
	}
});

Meio.Mask.createMasks('Reverse', {
	'Integer'		: {precision: 0, maxLength: 18},
	'Decimal'		: { },
	'DecimalUs'		: {thousands: ',', decimal: '.'},
	'Reais'			: {symbol: 'R$ ' },
	'Dollar'		: {symbol: 'US$ ', thousands: ',', decimal: '.'}
});


/*
---

name: Meio.Mask.Repeat

description: A mask that is defined by a pattern that will match each of the inputted chars.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Repeat]

...
*/

Meio.Mask.Repeat = new Class({

	Extends : Meio.Mask,

	options: {
		mask: '',
		maxLength: 0 // 0 for infinite
	},

	keypress: function(e, o){
		if (this.ignore) return true;
		e.preventDefault();
			
		var state = this.getCurrentState(e, o);
		var ruleRegex = Meio.Mask.rules[this.options.mask.charAt(0)].regex;
		var args = [this.element, state._char, e.code];
		var maxLength = this.options.maxLength;
		
		if ((maxLength && state.value.length > maxLength) || (!ruleRegex.test(state._char) && !o.isRemoveKey)){
			this.fireEvent('invalid', args);
		} else {
			this.fireEvent('valid', args);
			this.element.set('value', state.value).setCaretPosition(state.start + (o.isRemoveKey ? 0 : 1));
		}
		
		return this.parent();
	},
	
	paste: function(e, o){
		var maskedValue = this.mask(this.element.get('value'));
		this.element.set('value', maskedValue).setCaretPosition(maskedValue.length);
	},
	
	mask: function(str){
		var strArray = str.split(''),
			ruleRegex = Meio.Mask.rules[this.options.mask.charAt(0)].regex;
		for (var i = 0; i < strArray.length; i++){
			if (!ruleRegex.test(strArray[i])){
				strArray.splice(i, 1);
				i--;
			}
		}
		var maxLength = this.options.maxLength;
		return strArray.join('').substring(0, maxLength ? maxLength : strArray.length);
	}
	
});


/*
---

name: Meio.Mask.Regexp

description: A mask that is defined by a regular expression.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Regexp]

...
*/

Meio.Mask.Regexp = new Class({

	Extends : Meio.Mask,

	options: {
		regex: null
	},

	initialize : function(element, options){
		this.parent(element, options);
		this.regex = new RegExp(this.options.regex);
	},

	keypress: function(e, o){
		if (this.ignore) return true;
		e.preventDefault();
		
		var state = this.getCurrentState(e, o);
		var args = [this.element, state._char, e.code];
		
		if (!this.regex.test(state.value)){
			this.fireEvent('invalid', args);
		} else {
			this.element.set('value', state.value).setCaretPosition(state.start + (o.isRemoveKey ? 0 : 1));
			this.fireEvent('valid', args);
		}
		
		return true;
	},
	
	paste: function(e, o){
		var masked = this.applyMask(this.element.get('value'), true);
		this.element.set('value', masked.value).setCaretPosition(masked.index);
	},
	
	applyMask: function(str, fireEvent){
		var oldValue = '', curValue;
		for (var i = 1; i <= str.length; i++){
			curValue = str.substring(0, i);
			if (!this.regex.test(curValue)){
				if (fireEvent) this.fireEvent('invalid', [this.element, str.charAt(i), str.charCodeAt(i)]);
				break;
			}
			oldValue = curValue;
		}
		return {value: oldValue, index: i};
	},
	
	mask: function(str){
		return this.applyMask(str).value;
	}
	
});

Meio.Mask.createMasks('Regexp', {
	'Ip'		: {regex: /^(\d{0,3}\.){0,3}(\d{0,3})?$/},
	'Email'		: {regex: /^[\w.!#$%&'*+=?~^_`{|}\/-]*@?[.\w-]*$/}
});


/*
---

name: Meio.Mask.Extras

description: Extra functionality for Meio.Mask plugin. Like String.meiomask that masks a string and Element.meiomask which is a convinience method for setting the masks.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Extras]

...
*/

(function(){

	var meiomask = 'meiomask';
	
	var upperCamelize = function(str){
		return str.camelCase().capitalize();
	};
	
	var getClassOptions = function(a1, a2, opts){
		var klass;
		if (typeOf(a1) == 'string'){
			if (typeOf(a2) != 'string'){
				opts = a2;
				a1 = a1.split('.');
				a2 = a1[1];
				a1 = a1[0];
			}
			klass = Meio.Mask[upperCamelize(a1)];
			if (a2) klass = klass[upperCamelize(a2)];
		} else {
			klass = a1;
			opts = a2;
		}
		return {klass: klass, options: opts || {}};
	};
	
	var executeFunction = function(functionName, args){
		var co = getClassOptions.apply(null, args); 
		return new co.klass(co.options)[functionName](this);
	};

	String.implement({
		meiomask: function(){
			return executeFunction.call(this, 'mask', arguments);
		},
		meiounmask: function(){
			return executeFunction.call(this, 'unmask', arguments);
		}
	});

	Element.Properties.meiomask = {
		set: function(args){
			args = getClassOptions.apply(null, args), mask = this.retrieve(meiomask);
			if (mask){
				mask.unlink();
				mask = null;
			}
			return this.store(meiomask, new args.klass(args.options).link(this));
		},
		// returns the mask object
		get: function(){
			return this.retrieve(meiomask);
		},
		// removes completely the mask from this input
		erase: function(){
			var mask = this.retrieve(meiomask);
			if (mask) mask.unlink();
			return this;
		}
	};
	
	Element.Properties[meiomask + ':value'] = {
		// sets the value but first it applyes the mask (if theres any)
		set: function(value){
			var mask = this.retrieve(meiomask);
			if (mask) value = mask.mask(value);
			return this.set('value', value);
		},
		
		// gets the unmasked value
		get: function(){
			var mask = this.retrieve(meiomask);
			var value = this.get('value');
			return (mask) ? mask.unmask(value) : value;
		}
	};

	Element.implement({
		meiomask: function(mask, type, options){
			return this.set(meiomask, [mask, type, options]);
		}
	});
	
})();


var FormValidator = function(form) {
    this.form = $(form); var htmlFields = form.getElements('.vf');
    
    // element — Element | Element[]
    // tag — String
    // type — String
    // validators — {type:String,validators:[validators,...]}
    // label — {element:Element,twitch:Boolean,usecolor:Boolean,color:String}
    // message — Element
    this.fields = [];
    this.validFields = [];
    this.wrongFields = [];
    this.formValid = true;
    this.delegate = null;
    
    htmlFields.each(function(f) {
        var field = {}, element = null, tag = f.get('tag'), type = f.get('type'), validators = {}, label = {}, message = null;
        
        if (type == 'checkbox' || type == 'radio') {
            element = this.form.getElements('[name=' + f.get('name') + ']');
        } else {
            element = f;
        };
        element.store('validator', true);
        
        if (type === 'text' || type === 'password' || tag === 'textarea') {
            validators = this.getValidatorsForElement(f);
        };
        
        label = this.getLabelForElement(f);
        
        message = this.form.getElement('[rel=vm-' + f.get('name') + ']');
        
        this.fields.push({
            element: element,
            tag: tag,
            type: type,
            validators: validators,
            label: label,
            message: message
        });
        
    }, this);
    
    form.addEvent('submit', this.validate.bindWithEvent(this));
    
    form.store('validator', this);
};

FormValidator.prototype.validators = {
	'integer' : /^[0-9]+$/,
	'float' : /^[-+]?[0-9]+(\.[0-9]+)?$/,
	'phone' : /^(?:\+\d)*\s*(?:\(\d{3}\)\s*)*\d{3}(?:-{0,1}|\s{0,1})\d{2}(?:-{0,1}|\s{0,1})\d{2}$/,
	'russian_mobile_phone' : /^\+?\d\s*\-*\s*(?:(?:\(?:\d{3}\))|(?:\d{3}))\s*\d{3}(?:(?:\s*)|(?:\s*\-\s*))\d{2}(?:(?:\s*)|(?:\s*\-\s*))\d{2}$/,
	'time' : /^([0-1][0-9]|[2][0-3])(:([0-5][0-9])){1,2}$/,
	'url' : /^(http[s]?:\/\/|ftp:\/\/)?(www\.)?[a-zA-Z0-9-\.]+\.(aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$/i,
	'email' : /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i,
	'alpha' : /^[a-zA-Zа-яА-Я\s]*$/,
	'alnum' : /^[a-zA-Zа-яА-Я0-9Z\s]*$/,
	'date' : /^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/,
	'notempty' : /^.+$/,
	'empty' : /^$/
};
// "{and,[notempty,min-6]}"
FormValidator.prototype.getValidatorsForElement = function(f) {
    var cl = f.get('class');
    var validatorString = cl.match(/vfc\-([^\s]+)/)[1];
    
    if (validatorString.match(/^\{/)) {
        validatorString = validatorString.replace('and', '"type":"and"');
        validatorString = validatorString.replace('or', '"type":"or"');
        validatorString = validatorString.replace(/\[/g, '"validators":[');
        validatorString = validatorString.replace(/(\[|\,)([^\[\]\{\}\,\:]+)/g, '$1"$2"');
        validatorString = validatorString.replace(/""/g, '"');
        return JSON.decode(validatorString);
    } else {
        if (this.validators[validatorString]) {
            return {type:'and', validators:[validatorString]};
        };
    };
};

FormValidator.prototype.getLabelForElement = function(f) {
    var name = f.get('name'); name = name.replace(/\[/g, '\\[').replace(/\]/g, '\\]');
    var label = this.form.getElement('[rel=vl-' + name + ']');
    if (!label) {
        label = this.form.getElement('[rel*=vl-' + name + ']');
        if (label) {
            var tmpRel = label.get('rel').trim().substr(3, 1000);
            if (tmpRel !== name) {
                return {element: null};
            };
        } else {
            return {element: null};
        };
    };
    
    if (!label) return {element: null};
    
    var cl = label.get('class');
    var twitch = (cl.match(/vle-twitch/)) ? true : false;
    var usecolor = cl.match(/vle-#([a-fA-F0-9]{6})/);
    var color = (usecolor) ? '#' + usecolor[1] : ''; usecolor = (usecolor) ? true : false;
    
    return {
        element: label,
        twitch: twitch,
        usecolor: usecolor,
        color: color
    };
};

FormValidator.prototype.setFieldWrong = function(f) {
    this.formValid = false;
    
	f.element.addClass('wrong');
	
	if (f.message) {
		f.message.show();
	};
	
	if (f.label.element) {
	    if (f.label.usecolor) {
	        f.label.element.setStyle('color', f.label.color);
	    };
	    if (f.label.twitch) {
	        f.label.element.twitch();
	    };
	};
	
	this.wrongFields.push(f);
};

FormValidator.prototype.setFieldClear = function(f) {
    f.element.removeClass('wrong');
	
	if (f.message) {
		f.message.hide();
	};
	
	if (f.label.element && f.label.usecolor) {
	    f.label.element.setStyle('color', '');
	};
	
	this.validFields.push(f);
};

FormValidator.prototype.checkRecursively = function(validators, value) {
	var braching = validators.type;
	switch (braching) {
		case 'or' :
			if (validators.validators.some(function(validator) {
					    return this.validateTextField.run([validator, value], this);
				    }, this)) {
				return true;
			} else {
				return false;
			};
            break;
		case 'and' :
			if (validators.validators.every(function(validator) {
						return this.validateTextField.run([validator, value], this);
					}, this)) {
			    return true;
			} else {
					return false;
			};
			break;
		};
};

FormValidator.prototype.validateTextField = function(validator, value) {
	if ($type.string(validator)) {
		if (this.validators[validator]) {
			return this.validators[validator].test(value);
		};
		
		// больше или меньше определенного числового значения (><=15.5)
		var equality;
		if (equality = validator.match(/^(>|<)(=?)([-+]?[0-9]+(\.[0-9]+)?)$/)) {
			if (equality[1] === '>' && !equality[2].length && value.trim().toFloat() <= equality[3]) {
				return false;
			};
			if (equality[1] === '>' && equality[2] === '=' && value.trim().toFloat() < equality[3]) {
				return false;
			};
			if (equality[1] === '<' && !equality[2].length && value.trim().toFloat() >= equality[3]) {
				return false;
			};
			if (equality[1] === '<' && equality[2] === '=' && value.trim().toFloat() > equality[3]) {
				return false;
			};
			return true;
		};
		
		// сравнение значение поля со значением другого поля (к примеру,
        // пароль и подтверждение пароля (compare[айдишник поля в этой же форме])
        var compared_field;
        if (compared_field = validator.match(/^compare\|([^\|]+)\|$/)) {
            var cf = this.form.getElement('#' + compared_field[1]);
            if (cf && cf.get('value').trim() == value) {
                return true;
            };
        	return false;
        };
		
		// длина значения не меньше минимального (min-5)
		var min_length;
		if (min_length = validator.match(/^min\-(\d+)$/)) {
			if (value.length < min_length[1].toInt()) {
				return false;
			};
			return true;
		};
		
		// длина значения не больше миксимального (max-7)
		var max_length;
		if (max_length = validator.match(/^max\-(\d+)$/)) {
			if (value.length > max_length[1].toInt()) {
				return false;
			};
			return true;
		};
	};
	
	if ($type.object(validator)) {
		return this.checkRecursively(validator, value);
	};
};

FormValidator.prototype.setDelegate = function(d) {
    this.delegate = d;
};

FormValidator.prototype.validate = function(e) {
    var event = new Event(e);
    
    this.formValid = true;
    this.validFields = [];
    this.wrongFields = [];
    
    $each(this.fields, function(field) {
    	
    	if (field.type === 'text' || field.type === 'password' || field.tag === 'textarea') {
    		var value = field.element.get('value').trim();
    		if (!this.checkRecursively(field.validators, value)) {
    		    this.setFieldWrong(field);
    		} else {
            	this.setFieldClear(field);
            };
    	};
    	
    	if (field.type === 'checkbox' || field.type === 'radio') {
    		if (!field.element.getChecked().length) {
    			this.setFieldWrong(field);
    		} else {
            	this.setFieldClear(field);
            };
    	};
    	
    	if (field.type.indexOf('select') != -1) {
    		var selectedOptions = field.element.getSelected();
    		if (selectedOptions.some(function(opt) {
    			return !opt.get('value').trim().length;
    		})) {
    			this.setFieldWrong(field);
    		} else {
            	this.setFieldClear(field);
            };
    	};
        	
    }, this);
    
    if (this.delegate) {
        try {
            disableSubmits(false);
        } catch(e) {
            $each($$('input[type=submit], button[type=submit], input[type=image]'), function(s){
                s.disabled = false;
            });
        }
        this.delegate.call(this, event);
    } else {
        if (!this.formValid) {
    	    event.stop();
    	};
    };
};

window.addEvent('domready', function() {
    $each($$('.vform'), function(form){
        if (!form.retrieve('validator')) {
            var f = new FormValidator(form);
            form.store('validator', f);
        };
    });
});

var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}


