if(!("console"in window)||!("firebug"in console))
{
 var names=["log","debug","info","warn","error","assert","dir","dirxml",
"group","groupEnd","time","timeEnd","count","trace","profile","profileEnd"];

 window.console={};
 for(var i=0;i<names.length;++i)
 window.console[names[i]]=function(){}
}


var Prototype={
 Version:'1.6.0.2',

 Browser:{
 IE:!!(window.attachEvent&&!window.opera),
 Opera:!!window.opera,
 WebKit:navigator.userAgent.indexOf('AppleWebKit/')>-1,
 Gecko:navigator.userAgent.indexOf('Gecko')>-1&&navigator.userAgent.indexOf('KHTML')==-1,
 MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
},

 BrowserFeatures:{
 XPath:!!document.evaluate,
 ElementExtensions:!!window.HTMLElement,
 SpecificElementExtensions:
 document.createElement('div').__proto__&&
 document.createElement('div').__proto__!==
 document.createElement('form').__proto__
},

 ScriptFragment:'<script[^>]*>([\\S\\s]*?)<\/script>',
 JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,

 emptyFunction:function(){},
 K:function(x){return x}
};

if(Prototype.Browser.MobileSafari)
 Prototype.BrowserFeatures.SpecificElementExtensions=false;



var Class={
 create:function(){
 var parent=null,properties=$A(arguments);
 if(Object.isFunction(properties[0]))
 parent=properties.shift();

 function klass(){
 this.initialize.apply(this,arguments);
}

 Object.extend(klass,Class.Methods);
 klass.superclass=parent;
 klass.subclasses=[];

 if(parent){
 var subclass=function(){};
 subclass.prototype=parent.prototype;
 klass.prototype=new subclass;
 parent.subclasses.push(klass);
}

 for(var i=0;i<properties.length;i++)
 klass.addMethods(properties[i]);

 if(!klass.prototype.initialize)
 klass.prototype.initialize=Prototype.emptyFunction;

 klass.prototype.constructor=klass;

 return klass;
}
};

Class.Methods={
 addMethods:function(source){
 var ancestor=this.superclass&&this.superclass.prototype;
 var properties=Object.keys(source);

 if(!Object.keys({toString:true}).length)
 properties.push("toString","valueOf");

 for(var i=0,length=properties.length;i<length;i++){
 var property=properties[i],value=source[property];
 if(ancestor&&Object.isFunction(value)&&
 value.argumentNames().first()=="$super"){
 var method=value,value=Object.extend((function(m){
 return function(){return ancestor[m].apply(this,arguments)};
})(property).wrap(method),{
 valueOf:function(){return method},
 toString:function(){return method.toString()}
});
}
 this.prototype[property]=value;
}

 return this;
}
};

var Abstract={};

Object.extend=function(destination,source){
 for(var property in source)
 destination[property]=source[property];
 return destination;
};

Object.extend(Object,{
 inspect:function(object){
 try{
 if(Object.isUndefined(object))return'undefined';
 if(object===null)return'null';
 return object.inspect?object.inspect():String(object);
}catch(e){
 if(e instanceof RangeError)return'...';
 throw e;
}
},

 toJSON:function(object){
 var type=typeof object;
 switch(type){
 case'undefined':
 case'function':
 case'unknown':return;
 case'boolean':return object.toString();
}

 if(object===null)return'null';
 if(object.toJSON)return object.toJSON();
 if(Object.isElement(object))return;

 var results=[];
 for(var property in object){
 var value=Object.toJSON(object[property]);
 if(!Object.isUndefined(value))
 results.push(property.toJSON()+': '+value);
}

 return'{'+results.join(', ')+'}';
},

 toQueryString:function(object){
 return $H(object).toQueryString();
},

 toHTML:function(object){
 return object&&object.toHTML?object.toHTML():String.interpret(object);
},

 keys:function(object){
 var keys=[];
 for(var property in object)
 keys.push(property);
 return keys;
},

 values:function(object){
 var values=[];
 for(var property in object)
 values.push(object[property]);
 return values;
},

 clone:function(object){
 return Object.extend({},object);
},

 isElement:function(object){
 return object&&object.nodeType==1;
},

 isArray:function(object){
 return!!(object&&object.join&&object.splice);
},

 isHash:function(object){
 return object instanceof Hash;
},

 isFunction:function(object){
 return typeof object=="function";
},

 isString:function(object){
 return typeof object=="string";
},

 isNumber:function(object){
 return typeof object=="number";
},

 isUndefined:function(object){
 return typeof object=="undefined";
}
});

Object.extend(Function.prototype,{
 argumentNames:function(){
 var names=this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
 return names.length==1&&!names[0]?[]:names;
},

 bind:function(){
 var __method=this,object=arguments[0];
 if(arguments.length<2){
 return!object?this:function(){
 return __method.apply(object,arguments);
}
}
 var args=$A(arguments);
 args.shift();
 return function(){
 return __method.apply(object,args.concat($A(arguments)));
}
},

 bindAsEventListener:function(){
 var __method=this,args=$A(arguments),object=args.shift();
 return function(event){
 return __method.apply(object,[event||window.event].concat(args));
}
},

 curry:function(){
 if(!arguments.length)return this;
 var __method=this,args=$A(arguments);
 return function(){
 return __method.apply(this,args.concat($A(arguments)));
}
},

 delay:function(){
 var __method=this,args=$A(arguments),timeout=args.shift()*1000;
 return window.setTimeout(function(){
 return __method.apply(__method,args);
},timeout);
},

 wrap:function(wrapper){
 var __method=this;
 return function(){
 return wrapper.apply(this,[__method.bind(this)].concat($A(arguments)));
}
},

 methodize:function(){
 if(this._methodized)return this._methodized;
 var __method=this;
 return this._methodized=function(){
 return __method.apply(null,[this].concat($A(arguments)));
};
}
});

Function.prototype.defer=Function.prototype.delay.curry(0.01);

Date.prototype.toJSON=function(){
 return'"'+this.getUTCFullYear()+'-'+
(this.getUTCMonth()+1).toPaddedString(2)+'-'+
 this.getUTCDate().toPaddedString(2)+'T'+
 this.getUTCHours().toPaddedString(2)+':'+
 this.getUTCMinutes().toPaddedString(2)+':'+
 this.getUTCSeconds().toPaddedString(2)+'Z"';
};

var Try={
 these:function(){
 var returnValue;

 for(var i=0,length=arguments.length;i<length;i++){
 var lambda=arguments[i];
 try{
 returnValue=lambda();
 break;
}catch(e){}
}

 return returnValue;
}
};

RegExp.prototype.match=RegExp.prototype.test;

RegExp.escape=function(str){
 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,'\\$1');
};



var PeriodicalExecuter=Class.create({
 initialize:function(callback,frequency){
 this.callback=callback;
 this.frequency=frequency;
 this.currentlyExecuting=false;

 this.registerCallback();
},

 registerCallback:function(){
 this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000);
},

 execute:function(){
 this.callback(this);
},

 stop:function(){
 if(!this.timer)return;
 clearInterval(this.timer);
 this.timer=null;
},

 onTimerEvent:function(){
 if(!this.currentlyExecuting){
 try{
 this.currentlyExecuting=true;
 this.execute();
}finally{
 this.currentlyExecuting=false;
}
}
}
});
Object.extend(String,{
 interpret:function(value){
 return value==null?'':String(value);
},
 specialChar:{
'\b':'\\b',
'\t':'\\t',
'\n':'\\n',
'\f':'\\f',
'\r':'\\r',
'\\':'\\\\'
}
});

Object.extend(String.prototype,{
 gsub:function(pattern,replacement){
 var result='',source=this,match;
 replacement=arguments.callee.prepareReplacement(replacement);

 while(source.length>0){
 if(match=source.match(pattern)){
 result+=source.slice(0,match.index);
 result+=String.interpret(replacement(match));
 source=source.slice(match.index+match[0].length);
}else{
 result+=source,source='';
}
}
 return result;
},

 sub:function(pattern,replacement,count){
 replacement=this.gsub.prepareReplacement(replacement);
 count=Object.isUndefined(count)?1:count;

 return this.gsub(pattern,function(match){
 if(--count<0)return match[0];
 return replacement(match);
});
},

 scan:function(pattern,iterator){
 this.gsub(pattern,iterator);
 return String(this);
},

 truncate:function(length,truncation){
 length=length||30;
 truncation=Object.isUndefined(truncation)?'...':truncation;
 return this.length>length?
 this.slice(0,length-truncation.length)+truncation:String(this);
},

 strip:function(){
 return this.replace(/^\s+/,'').replace(/\s+$/,'');
},

 stripTags:function(){
 return this.replace(/<\/?[^>]+>/gi,'');
},

 stripScripts:function(){
 return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'');
},

 extractScripts:function(){
 var matchAll=new RegExp(Prototype.ScriptFragment,'img');
 var matchOne=new RegExp(Prototype.ScriptFragment,'im');
 return(this.match(matchAll)||[]).map(function(scriptTag){
 return(scriptTag.match(matchOne)||['',''])[1];
});
},

 evalScripts:function(){
 return this.extractScripts().map(function(script){return eval(script)});
},

 escapeHTML:function(){
 var self=arguments.callee;
 self.text.data=this;
 return self.div.innerHTML;
},

 unescapeHTML:function(){
 var div=new Element('div');
 div.innerHTML=this.stripTags();
 return div.childNodes[0]?(div.childNodes.length>1?
 $A(div.childNodes).inject('',function(memo,node){return memo+node.nodeValue}):
 div.childNodes[0].nodeValue):'';
},

 toQueryParams:function(separator){
 var match=this.strip().match(/([^?#]*)(#.*)?$/);
 if(!match)return{};

 return match[1].split(separator||'&').inject({},function(hash,pair){
 if((pair=pair.split('='))[0]){
 var key=decodeURIComponent(pair.shift());
 var value=pair.length>1?pair.join('='):pair[0];
 if(value!=undefined)value=decodeURIComponent(value);

 if(key in hash){
 if(!Object.isArray(hash[key]))hash[key]=[hash[key]];
 hash[key].push(value);
}
 else hash[key]=value;
}
 return hash;
});
},

 toArray:function(){
 return this.split('');
},

 succ:function(){
 return this.slice(0,this.length-1)+
 String.fromCharCode(this.charCodeAt(this.length-1)+1);
},

 times:function(count){
 return count<1?'':new Array(count+1).join(this);
},

 camelize:function(){
 var parts=this.split('-'),len=parts.length;
 if(len==1)return parts[0];

 var camelized=this.charAt(0)=='-'
?parts[0].charAt(0).toUpperCase()+parts[0].substring(1)
:parts[0];

 for(var i=1;i<len;i++)
 camelized+=parts[i].charAt(0).toUpperCase()+parts[i].substring(1);

 return camelized;
},

 capitalize:function(){
 return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase();
},

 underscore:function(){
 return this.gsub(/::/,'/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
},

 dasherize:function(){
 return this.gsub(/_/,'-');
},

 inspect:function(useDoubleQuotes){
 var escapedString=this.gsub(/[\x00-\x1f\\]/,function(match){
 var character=String.specialChar[match[0]];
 return character?character:'\\u00'+match[0].charCodeAt().toPaddedString(2,16);
});
 if(useDoubleQuotes)return'"'+escapedString.replace(/"/g,'\\"')+'"';
 return"'"+escapedString.replace(/'/g,'\\\'')+"'";
},

 toJSON:function(){
 return this.inspect(true);
},

 unfilterJSON:function(filter){
 return this.sub(filter||Prototype.JSONFilter,'#{1}');
},

 isJSON:function(){
 var str=this;
 if(str.blank())return false;
 str=this.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"/g,'');
 return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
},

 evalJSON:function(sanitize){
 var json=this.unfilterJSON();
 try{
 if(!sanitize||json.isJSON())return eval('('+json+')');
}catch(e){}
 throw new SyntaxError('Badly formed JSON string: '+this.inspect());
},

 include:function(pattern){
 return this.indexOf(pattern)>-1;
},

 startsWith:function(pattern){
 return this.indexOf(pattern)===0;
},

 endsWith:function(pattern){
 var d=this.length-pattern.length;
 return d>=0&&this.lastIndexOf(pattern)===d;
},

 empty:function(){
 return this=='';
},

 blank:function(){
 return/^\s*$/.test(this);
},

 interpolate:function(object,pattern){
 return new Template(this,pattern).evaluate(object);
}
});

if(Prototype.Browser.WebKit||Prototype.Browser.IE)Object.extend(String.prototype,{
 escapeHTML:function(){
 return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
},
 unescapeHTML:function(){
 return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
}
});

String.prototype.gsub.prepareReplacement=function(replacement){
 if(Object.isFunction(replacement))return replacement;
 var template=new Template(replacement);
 return function(match){return template.evaluate(match)};
};

String.prototype.parseQuery=String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML,{
 div:document.createElement('div'),
 text:document.createTextNode('')
});

with(String.prototype.escapeHTML)div.appendChild(text);

var Template=Class.create({
 initialize:function(template,pattern){
 this.template=template.toString();
 this.pattern=pattern||Template.Pattern;
},

 evaluate:function(object){
 if(Object.isFunction(object.toTemplateReplacements))
 object=object.toTemplateReplacements();

 return this.template.gsub(this.pattern,function(match){
 if(object==null)return'';

 var before=match[1]||'';
 if(before=='\\')return match[2];

 var ctx=object,expr=match[3];
 var pattern=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
 match=pattern.exec(expr);
 if(match==null)return before;

 while(match!=null){
 var comp=match[1].startsWith('[')?match[2].gsub('\\\\]',']'):match[1];
 ctx=ctx[comp];
 if(null==ctx||''==match[3])break;
 expr=expr.substring('['==match[3]?match[1].length:match[0].length);
 match=pattern.exec(expr);
}

 return before+String.interpret(ctx);
});
}
});
Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;

var $break={};

var Enumerable={
 each:function(iterator,context){
 var index=0;
 iterator=iterator.bind(context);
 try{
 this._each(function(value){
 iterator(value,index++);
});
}catch(e){
 if(e!=$break)throw e;
}
 return this;
},

 eachSlice:function(number,iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var index=-number,slices=[],array=this.toArray();
 while((index+=number)<array.length)
 slices.push(array.slice(index,index+number));
 return slices.collect(iterator,context);
},

 all:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result=true;
 this.each(function(value,index){
 result=result&&!!iterator(value,index);
 if(!result)throw $break;
});
 return result;
},

 any:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result=false;
 this.each(function(value,index){
 if(result=!!iterator(value,index))
 throw $break;
});
 return result;
},

 collect:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var results=[];
 this.each(function(value,index){
 results.push(iterator(value,index));
});
 return results;
},

 detect:function(iterator,context){
 iterator=iterator.bind(context);
 var result;
 this.each(function(value,index){
 if(iterator(value,index)){
 result=value;
 throw $break;
}
});
 return result;
},

 findAll:function(iterator,context){
 iterator=iterator.bind(context);
 var results=[];
 this.each(function(value,index){
 if(iterator(value,index))
 results.push(value);
});
 return results;
},

 grep:function(filter,iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var results=[];

 if(Object.isString(filter))
 filter=new RegExp(filter);

 this.each(function(value,index){
 if(filter.match(value))
 results.push(iterator(value,index));
});
 return results;
},

 include:function(object){
 if(Object.isFunction(this.indexOf))
 if(this.indexOf(object)!=-1)return true;

 var found=false;
 this.each(function(value){
 if(value==object){
 found=true;
 throw $break;
}
});
 return found;
},

 inGroupsOf:function(number,fillWith){
 fillWith=Object.isUndefined(fillWith)?null:fillWith;
 return this.eachSlice(number,function(slice){
 while(slice.length<number)slice.push(fillWith);
 return slice;
});
},

 inject:function(memo,iterator,context){
 iterator=iterator.bind(context);
 this.each(function(value,index){
 memo=iterator(memo,value,index);
});
 return memo;
},

 invoke:function(method){
 var args=$A(arguments).slice(1);
 return this.map(function(value){
 return value[method].apply(value,args);
});
},

 max:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result;
 this.each(function(value,index){
 value=iterator(value,index);
 if(result==null||value>=result)
 result=value;
});
 return result;
},

 min:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result;
 this.each(function(value,index){
 value=iterator(value,index);
 if(result==null||value<result)
 result=value;
});
 return result;
},

 partition:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var trues=[],falses=[];
 this.each(function(value,index){
(iterator(value,index)?
 trues:falses).push(value);
});
 return[trues,falses];
},

 pluck:function(property){
 var results=[];
 this.each(function(value){
 results.push(value[property]);
});
 return results;
},

 reject:function(iterator,context){
 iterator=iterator.bind(context);
 var results=[];
 this.each(function(value,index){
 if(!iterator(value,index))
 results.push(value);
});
 return results;
},

 sortBy:function(iterator,context){
 iterator=iterator.bind(context);
 return this.map(function(value,index){
 return{value:value,criteria:iterator(value,index)};
}).sort(function(left,right){
 var a=left.criteria,b=right.criteria;
 return a<b?-1:a>b?1:0;
}).pluck('value');
},

 toArray:function(){
 return this.map();
},

 zip:function(){
 var iterator=Prototype.K,args=$A(arguments);
 if(Object.isFunction(args.last()))
 iterator=args.pop();

 var collections=[this].concat(args).map($A);
 return this.map(function(value,index){
 return iterator(collections.pluck(index));
});
},

 size:function(){
 return this.toArray().length;
},

 inspect:function(){
 return'#<Enumerable:'+this.toArray().inspect()+'>';
}
};

Object.extend(Enumerable,{
 map:Enumerable.collect,
 find:Enumerable.detect,
 select:Enumerable.findAll,
 filter:Enumerable.findAll,
 member:Enumerable.include,
 entries:Enumerable.toArray,
 every:Enumerable.all,
 some:Enumerable.any
});
function $A(iterable){
 if(!iterable)return[];
 if(iterable.toArray)return iterable.toArray();
 var length=iterable.length||0,results=new Array(length);
 while(length--)results[length]=iterable[length];
 return results;
}

if(Prototype.Browser.WebKit){
 $A=function(iterable){
 if(!iterable)return[];
 if(!(Object.isFunction(iterable)&&iterable=='[object NodeList]')&&
 iterable.toArray)return iterable.toArray();
 var length=iterable.length||0,results=new Array(length);
 while(length--)results[length]=iterable[length];
 return results;
};
}

Array.from=$A;

Object.extend(Array.prototype,Enumerable);

if(!Array.prototype._reverse)Array.prototype._reverse=Array.prototype.reverse;

Object.extend(Array.prototype,{
 _each:function(iterator){
 for(var i=0,length=this.length;i<length;i++)
 iterator(this[i]);
},

 clear:function(){
 this.length=0;
 return this;
},

 first:function(){
 return this[0];
},

 last:function(){
 return this[this.length-1];
},

 compact:function(){
 return this.select(function(value){
 return value!=null;
});
},

 flatten:function(){
 return this.inject([],function(array,value){
 return array.concat(Object.isArray(value)?
 value.flatten():[value]);
});
},

 without:function(){
 var values=$A(arguments);
 return this.select(function(value){
 return!values.include(value);
});
},

 reverse:function(inline){
 return(inline!==false?this:this.toArray())._reverse();
},

 reduce:function(){
 return this.length>1?this:this[0];
},

 uniq:function(sorted){
 return this.inject([],function(array,value,index){
 if(0==index||(sorted?array.last()!=value:!array.include(value)))
 array.push(value);
 return array;
});
},

 intersect:function(array){
 return this.uniq().findAll(function(item){
 return array.detect(function(value){return item===value});
});
},

 clone:function(){
 return[].concat(this);
},

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

 inspect:function(){
 return'['+this.map(Object.inspect).join(', ')+']';
},

 toJSON:function(){
 var results=[];
 this.each(function(object){
 var value=Object.toJSON(object);
 if(!Object.isUndefined(value))results.push(value);
});
 return'['+results.join(', ')+']';
}
});


if(Object.isFunction(Array.prototype.forEach))
 Array.prototype._each=Array.prototype.forEach;

if(!Array.prototype.indexOf)Array.prototype.indexOf=function(item,i){
 i||(i=0);
 var length=this.length;
 if(i<0)i=length+i;
 for(;i<length;i++)
 if(this[i]===item)return i;
 return-1;
};

if(!Array.prototype.lastIndexOf)Array.prototype.lastIndexOf=function(item,i){
 i=isNaN(i)?this.length:(i<0?this.length+i:i)+1;
 var n=this.slice(0,i).reverse().indexOf(item);
 return(n<0)?n:i-n-1;
};

Array.prototype.toArray=Array.prototype.clone;

function $w(string){
 if(!Object.isString(string))return[];
 string=string.strip();
 return string?string.split(/\s+/):[];
}

if(Prototype.Browser.Opera){
 Array.prototype.concat=function(){
 var array=[];
 for(var i=0,length=this.length;i<length;i++)array.push(this[i]);
 for(var i=0,length=arguments.length;i<length;i++){
 if(Object.isArray(arguments[i])){
 for(var j=0,arrayLength=arguments[i].length;j<arrayLength;j++)
 array.push(arguments[i][j]);
}else{
 array.push(arguments[i]);
}
}
 return array;
};
}
Object.extend(Number.prototype,{
 toColorPart:function(){
 return this.toPaddedString(2,16);
},

 succ:function(){
 return this+1;
},

 times:function(iterator){
 $R(0,this,true).each(iterator);
 return this;
},

 toPaddedString:function(length,radix){
 var string=this.toString(radix||10);
 return'0'.times(length-string.length)+string;
},

 toJSON:function(){
 return isFinite(this)?this.toString():'null';
}
});

$w('abs round ceil floor').each(function(method){
 Number.prototype[method]=Math[method].methodize();
});
function $H(object){
 return new Hash(object);
};

var Hash=Class.create(Enumerable,(function(){

 function toQueryPair(key,value){
 if(Object.isUndefined(value))return key;
 return key+'='+encodeURIComponent(String.interpret(value));
}

 return{
 initialize:function(object){
 this._object=Object.isHash(object)?object.toObject():Object.clone(object);
},

 _each:function(iterator){
 for(var key in this._object){
 var value=this._object[key],pair=[key,value];
 pair.key=key;
 pair.value=value;
 iterator(pair);
}
},

 set:function(key,value){
 return this._object[key]=value;
},

 get:function(key){
 return this._object[key];
},

 unset:function(key){
 var value=this._object[key];
 delete this._object[key];
 return value;
},

 toObject:function(){
 return Object.clone(this._object);
},

 keys:function(){
 return this.pluck('key');
},

 values:function(){
 return this.pluck('value');
},

 index:function(value){
 var match=this.detect(function(pair){
 return pair.value===value;
});
 return match&&match.key;
},

 merge:function(object){
 return this.clone().update(object);
},

 update:function(object){
 return new Hash(object).inject(this,function(result,pair){
 result.set(pair.key,pair.value);
 return result;
});
},

 toQueryString:function(){
 return this.map(function(pair){
 var key=encodeURIComponent(pair.key),values=pair.value;

 if(values&&typeof values=='object'){
 if(Object.isArray(values))
 return values.map(toQueryPair.curry(key)).join('&');
}
 return toQueryPair(key,values);
}).join('&');
},

 inspect:function(){
 return'#<Hash:{'+this.map(function(pair){
 return pair.map(Object.inspect).join(': ');
}).join(', ')+'}>';
},

 toJSON:function(){
 return Object.toJSON(this.toObject());
},

 clone:function(){
 return new Hash(this);
}
}
})());

Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;
Hash.from=$H;
var ObjectRange=Class.create(Enumerable,{
 initialize:function(start,end,exclusive){
 this.start=start;
 this.end=end;
 this.exclusive=exclusive;
},

 _each:function(iterator){
 var value=this.start;
 while(this.include(value)){
 iterator(value);
 value=value.succ();
}
},

 include:function(value){
 if(value<this.start)
 return false;
 if(this.exclusive)
 return value<this.end;
 return value<=this.end;
}
});

var $R=function(start,end,exclusive){
 return new ObjectRange(start,end,exclusive);
};

var Ajax={
 getTransport:function(){
 return Try.these(
 function(){return new XMLHttpRequest()},
 function(){return new ActiveXObject('Msxml2.XMLHTTP')},
 function(){return new ActiveXObject('Microsoft.XMLHTTP')}
)||false;
},

 activeRequestCount:0
};

Ajax.Responders={
 responders:[],

 _each:function(iterator){
 this.responders._each(iterator);
},

 register:function(responder){
 if(!this.include(responder))
 this.responders.push(responder);
},

 unregister:function(responder){
 this.responders=this.responders.without(responder);
},

 dispatch:function(callback,request,transport,json){
 this.each(function(responder){
 if(Object.isFunction(responder[callback])){
 try{
 responder[callback].apply(responder,[request,transport,json]);
}catch(e){}
}
});
}
};

Object.extend(Ajax.Responders,Enumerable);

Ajax.Responders.register({
 onCreate:function(){Ajax.activeRequestCount++},
 onComplete:function(){Ajax.activeRequestCount--}
});

Ajax.Base=Class.create({
 initialize:function(options){
 this.options={
 method:'post',
 asynchronous:true,
 contentType:'application/x-www-form-urlencoded',
 encoding:'UTF-8',
 parameters:'',
 evalJSON:true,
 evalJS:true
};
 Object.extend(this.options,options||{});

 this.options.method=this.options.method.toLowerCase();

 if(Object.isString(this.options.parameters))
 this.options.parameters=this.options.parameters.toQueryParams();
 else if(Object.isHash(this.options.parameters))
 this.options.parameters=this.options.parameters.toObject();
}
});

Ajax.Request=Class.create(Ajax.Base,{
 _complete:false,

 initialize:function($super,url,options){
 $super(options);
 this.transport=Ajax.getTransport();
 this.request(url);
},

 request:function(url){
 this.url=url;
 this.method=this.options.method;
 var params=Object.clone(this.options.parameters);

 if(!['get','post'].include(this.method)){

 params['_method']=this.method;
 this.method='post';
}

 this.parameters=params;

 if(params=Object.toQueryString(params)){

 if(this.method=='get')
 this.url+=(this.url.include('?')?'&':'?')+params;
 else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
 params+='&_=';
}

 try{
 var response=new Ajax.Response(this);
 if(this.options.onCreate)this.options.onCreate(response);
 Ajax.Responders.dispatch('onCreate',this,response);

 this.transport.open(this.method.toUpperCase(),this.url,
 this.options.asynchronous);

 if(this.options.asynchronous)this.respondToReadyState.bind(this).defer(1);

 this.transport.onreadystatechange=this.onStateChange.bind(this);
 this.setRequestHeaders();

 this.body=this.method=='post'?(this.options.postBody||params):null;
 this.transport.send(this.body);


 if(!this.options.asynchronous&&this.transport.overrideMimeType)
 this.onStateChange();

}
 catch(e){
 this.dispatchException(e);
}
},

 onStateChange:function(){
 var readyState=this.transport.readyState;
 if(readyState>1&&!((readyState==4)&&this._complete))
 this.respondToReadyState(this.transport.readyState);
},

 setRequestHeaders:function(){
 var headers={
'X-Requested-With':'XMLHttpRequest',
'X-Prototype-Version':Prototype.Version,
'Accept':'text/javascript, text/html, application/xml, text/xml, */*'
};

 if(this.method=='post'){
 headers['Content-type']=this.options.contentType+
(this.options.encoding?'; charset='+this.options.encoding:'');


 if(this.transport.overrideMimeType&&
(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005)
 headers['Connection']='close';
}


 if(typeof this.options.requestHeaders=='object'){
 var extras=this.options.requestHeaders;

 if(Object.isFunction(extras.push))
 for(var i=0,length=extras.length;i<length;i+=2)
 headers[extras[i]]=extras[i+1];
 else
 $H(extras).each(function(pair){headers[pair.key]=pair.value});
}

 for(var name in headers)
 this.transport.setRequestHeader(name,headers[name]);
},

 success:function(){
 var status=this.getStatus();
 return!status||(status>=200&&status<300);
},

 getStatus:function(){
 try{



 return this.transport.status==1223?204:this.transport.status||0;
}catch(e){return 0}
},

 respondToReadyState:function(readyState){
 var state=Ajax.Request.Events[readyState],response=new Ajax.Response(this);

 if(state=='Complete'){
 var startAt=new Date();
 try{
 this._complete=true;
(this.options['on'+response.status]
||this.options['on'+(this.success()?'Success':'Failure')]
||Prototype.emptyFunction)(response,response.headerJSON);
}catch(e){
 this.dispatchException(e);
}finally{

 var processTime=(new Date()-startAt)/1000;
 if(processTime>.5){
 var durl=this.url.replace(/.*\/([^/?]*).*/,'$1');
 console.warn('Warning! '+durl+' took '+processTime+' seconds to process - this may be affecting useability.');
}
}

 var contentType=response.getHeader('Content-type');
 if(this.options.evalJS=='force'
||(this.options.evalJS&&this.isSameOrigin()&&contentType
&&contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
 this.evalResponse();
}

 try{
(this.options['on'+state]||Prototype.emptyFunction)(response,response.headerJSON);
 Ajax.Responders.dispatch('on'+state,this,response,response.headerJSON);
}catch(e){
 this.dispatchException(e);
}

 if(state=='Complete'){

 this.transport.onreadystatechange=Prototype.emptyFunction;
}
},

 isSameOrigin:function(){
 var m=this.url.match(/^\s*https?:\/\/[^\/]*/);
 return!m||(m[0]=='#{protocol}//#{domain}#{port}'.interpolate({
 protocol:location.protocol,
 domain:document.domain,
 port:location.port?':'+location.port:''
}));
},

 getHeader:function(name){
 try{
 return this.transport.getResponseHeader(name)||null;
}catch(e){return null}
},

 evalResponse:function(){
 try{
 return eval((this.transport.responseText||'').unfilterJSON());
}catch(e){
 this.dispatchException(e);
}
},

 dispatchException:function(exception){
(this.options.onException||Prototype.emptyFunction)(this,exception);
 Ajax.Responders.dispatch('onException',this,exception);
}
});

Ajax.Request.Events=
['Uninitialized','Loading','Loaded','Interactive','Complete'];

Ajax.Response=Class.create({
 initialize:function(request){
 this.request=request;
 var transport=this.transport=request.transport,
 readyState=this.readyState=transport.readyState;

 if((readyState>2&&!Prototype.Browser.IE)||readyState==4){
 this.status=this.getStatus();
 this.statusText=this.getStatusText();
 this.responseText=String.interpret(transport.responseText);
 this.headerJSON=this._getHeaderJSON();
}

 if(readyState==4){
 var xml=transport.responseXML;
 this.responseXML=Object.isUndefined(xml)?null:xml;
 this.responseJSON=this._getResponseJSON();
}
},

 status:0,
 statusText:'',

 getStatus:Ajax.Request.prototype.getStatus,

 getStatusText:function(){
 try{
 return this.transport.statusText||'';
}catch(e){return''}
},

 getHeader:Ajax.Request.prototype.getHeader,

 getAllHeaders:function(){
 try{
 return this.getAllResponseHeaders();
}catch(e){return null}
},

 getResponseHeader:function(name){
 return this.transport.getResponseHeader(name);
},

 getAllResponseHeaders:function(){
 return this.transport.getAllResponseHeaders();
},

 _getHeaderJSON:function(){
 var json=this.getHeader('X-JSON');
 if(!json)return null;
 json=decodeURIComponent(escape(json));
 try{
 return json.evalJSON(this.request.options.sanitizeJSON||
!this.request.isSameOrigin());
}catch(e){
 this.request.dispatchException(e);
}
},

 _getResponseJSON:function(){
 var options=this.request.options;
 if(!options.evalJSON||(options.evalJSON!='force'&&
!(this.getHeader('Content-type')||'').include('application/json'))||
 this.responseText.blank())
 return null;
 try{
 return this.responseText.evalJSON(options.sanitizeJSON||
!this.request.isSameOrigin());
}catch(e){
 this.request.dispatchException(e);
}
}
});

Ajax.Updater=Class.create(Ajax.Request,{
 initialize:function($super,container,url,options){
 this.container={
 success:(container.success||container),
 failure:(container.failure||(container.success?null:container))
};

 options=Object.clone(options);
 var onComplete=options.onComplete;
 options.onComplete=(function(response,json){
 this.updateContent(response.responseText);
 if(Object.isFunction(onComplete))onComplete(response,json);
}).bind(this);

 $super(url,options);
},

 updateContent:function(responseText){
 var receiver=this.container[this.success()?'success':'failure'],
 options=this.options;

 if(!options.evalScripts)responseText=responseText.stripScripts();

 if(receiver=$(receiver)){
 if(options.insertion){
 if(Object.isString(options.insertion)){
 var insertion={};insertion[options.insertion]=responseText;
 receiver.insert(insertion);
}
 else options.insertion(receiver,responseText);
}
 else receiver.update(responseText);
}
}
});

Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{
 initialize:function($super,container,url,options){
 $super(options);
 this.onComplete=this.options.onComplete;

 this.frequency=(this.options.frequency||2);
 this.decay=(this.options.decay||1);

 this.updater={};
 this.container=container;
 this.url=url;

 this.start();
},

 start:function(){
 this.options.onComplete=this.updateComplete.bind(this);
 this.onTimerEvent();
},

 stop:function(){
 this.updater.options.onComplete=undefined;
 clearTimeout(this.timer);
(this.onComplete||Prototype.emptyFunction).apply(this,arguments);
},

 updateComplete:function(response){
 if(this.options.decay){
 this.decay=(response.responseText==this.lastText?
 this.decay*this.options.decay:1);

 this.lastText=response.responseText;
}
 this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency);
},

 onTimerEvent:function(){
 this.updater=new Ajax.Updater(this.container,this.url,this.options);
}
});
function $(element){
 if(arguments.length>1){
 for(var i=0,elements=[],length=arguments.length;i<length;i++)
 elements.push($(arguments[i]));
 return elements;
}
 if(Object.isString(element))
 element=document.getElementById(element);
 return Element.extend(element);
}

if(Prototype.BrowserFeatures.XPath){
 document._getElementsByXPath=function(expression,parentElement){
 var results=[];
 var query=document.evaluate(expression,$(parentElement)||document,
 null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
 for(var i=0,length=query.snapshotLength;i<length;i++)
 results.push(Element.extend(query.snapshotItem(i)));
 return results;
};
}



if(!window.Node)var Node={};

if(!Node.ELEMENT_NODE){

 Object.extend(Node,{
 ELEMENT_NODE:1,
 ATTRIBUTE_NODE:2,
 TEXT_NODE:3,
 CDATA_SECTION_NODE:4,
 ENTITY_REFERENCE_NODE:5,
 ENTITY_NODE:6,
 PROCESSING_INSTRUCTION_NODE:7,
 COMMENT_NODE:8,
 DOCUMENT_NODE:9,
 DOCUMENT_TYPE_NODE:10,
 DOCUMENT_FRAGMENT_NODE:11,
 NOTATION_NODE:12
});
}

(function(){
 var element=this.Element;
 this.Element=function(tagName,attributes){
 attributes=attributes||{};
 tagName=tagName.toLowerCase();
 var cache=Element.cache;
 if(Prototype.Browser.IE&&attributes.name){
 tagName='<'+tagName+' name="'+attributes.name+'">';
 delete attributes.name;
 return Element.writeAttribute(document.createElement(tagName),attributes);
}
 if(!cache[tagName])cache[tagName]=Element.extend(document.createElement(tagName));
 return Element.writeAttribute(cache[tagName].cloneNode(false),attributes);
};
 Object.extend(this.Element,element||{});
}).call(window);

Element.cache={};

Element.Methods={
 visible:function(element){
 return $(element).style.display!='none';
},

 toggle:function(element){
 element=$(element);
 Element[Element.visible(element)?'hide':'show'](element);
 return element;
},

 hide:function(element){
 $(element).style.display='none';
 return element;
},

 show:function(element){
 $(element).style.display='';
 return element;
},

 remove:function(element){
 element=$(element);
 element.parentNode.removeChild(element);
 return element;
},

 update:function(element,content){
 element=$(element);
 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content))return element.update().insert(content);
 content=Object.toHTML(content);
 element.innerHTML=content.stripScripts();
 content.evalScripts.bind(content).defer();
 return element;
},

 replace:function(element,content){
 element=$(element);
 if(content&&content.toElement)content=content.toElement();
 else if(!Object.isElement(content)){
 content=Object.toHTML(content);
 var range=element.ownerDocument.createRange();
 range.selectNode(element);
 content.evalScripts.bind(content).defer();
 content=range.createContextualFragment(content.stripScripts());
}
 element.parentNode.replaceChild(content,element);
 return element;
},

 insert:function(element,insertions){
 element=$(element);

 if(Object.isString(insertions)||Object.isNumber(insertions)||
 Object.isElement(insertions)||(insertions&&(insertions.toElement||insertions.toHTML)))
 insertions={bottom:insertions};

 var content,insert,tagName,childNodes;

 for(var position in insertions){
 content=insertions[position];
 position=position.toLowerCase();
 insert=Element._insertionTranslations[position];

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content)){
 insert(element,content);
 continue;
}

 content=Object.toHTML(content);

 tagName=((position=='before'||position=='after')
?element.parentNode:element).tagName.toUpperCase();

 childNodes=Element._getContentFromAnonymousElement(tagName,content.stripScripts());

 if(position=='top'||position=='after')childNodes.reverse();
 childNodes.each(insert.curry(element));

 content.evalScripts.bind(content).defer();
}

 return element;
},

 wrap:function(element,wrapper,attributes){
 element=$(element);
 if(Object.isElement(wrapper))
 $(wrapper).writeAttribute(attributes||{});
 else if(Object.isString(wrapper))wrapper=new Element(wrapper,attributes);
 else wrapper=new Element('div',wrapper);
 if(element.parentNode)
 element.parentNode.replaceChild(wrapper,element);
 wrapper.appendChild(element);
 return wrapper;
},

 inspect:function(element){
 element=$(element);
 var result='<'+element.tagName.toLowerCase();
 $H({'id':'id','className':'class'}).each(function(pair){
 var property=pair.first(),attribute=pair.last();
 var value=(element[property]||'').toString();
 if(value)result+=' '+attribute+'='+value.inspect(true);
});
 return result+'>';
},

 recursivelyCollect:function(element,property){
 element=$(element);
 var elements=[];
 while(element=element[property])
 if(element.nodeType==1)
 elements.push(Element.extend(element));
 return elements;
},

 ancestors:function(element){
 return $(element).recursivelyCollect('parentNode');
},

 descendants:function(element){
 return $(element).select("*");
},

 firstDescendant:function(element){
 element=$(element).firstChild;
 while(element&&element.nodeType!=1)element=element.nextSibling;
 return $(element);
},

 immediateDescendants:function(element){
 if(!(element=$(element).firstChild))return[];
 while(element&&element.nodeType!=1)element=element.nextSibling;
 if(element)return[element].concat($(element).nextSiblings());
 return[];
},

 previousSiblings:function(element){
 return $(element).recursivelyCollect('previousSibling');
},

 nextSiblings:function(element){
 return $(element).recursivelyCollect('nextSibling');
},

 siblings:function(element){
 element=$(element);
 return element.previousSiblings().reverse().concat(element.nextSiblings());
},

 match:function(element,selector){
 if(Object.isString(selector))
 selector=new Selector(selector);
 return selector.match($(element));
},

 up:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(element.parentNode);
 var ancestors=element.ancestors();
 return Object.isNumber(expression)?ancestors[expression]:
 Selector.findElement(ancestors,expression,index);
},

 down:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return element.firstDescendant();
 return Object.isNumber(expression)?element.descendants()[expression]:
 element.select(expression)[index||0];
},

 previous:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(Selector.handlers.previousElementSibling(element));
 var previousSiblings=element.previousSiblings();
 return Object.isNumber(expression)?previousSiblings[expression]:
 Selector.findElement(previousSiblings,expression,index);
},

 next:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(Selector.handlers.nextElementSibling(element));
 var nextSiblings=element.nextSiblings();
 return Object.isNumber(expression)?nextSiblings[expression]:
 Selector.findElement(nextSiblings,expression,index);
},

 select:function(){
 var args=$A(arguments),element=$(args.shift());
 return Selector.findChildElements(element,args);
},

 adjacent:function(){
 var args=$A(arguments),element=$(args.shift());
 return Selector.findChildElements(element.parentNode,args).without(element);
},

 identify:function(element){
 element=$(element);
 var id=element.readAttribute('id'),self=arguments.callee;
 if(id)return id;
 do{id='anonymous_element_'+self.counter++}while($(id));
 element.writeAttribute('id',id);
 return id;
},

 readAttribute:function(element,name){
 element=$(element);
 if(Prototype.Browser.IE){
 var t=Element._attributeTranslations.read;
 if(t.values[name])return t.values[name](element,name);
 if(t.names[name])name=t.names[name];
 if(name.include(':')){
 return(!element.attributes||!element.attributes[name])?null:
 element.attributes[name].value;
}
}
 return element.getAttribute(name);
},

 writeAttribute:function(element,name,value){
 element=$(element);
 var attributes={},t=Element._attributeTranslations.write;

 if(typeof name=='object')attributes=name;
 else attributes[name]=Object.isUndefined(value)?true:value;

 for(var attr in attributes){
 name=t.names[attr]||attr;
 value=attributes[attr];
 if(t.values[attr])name=t.values[attr](element,value);
 if(value===false||value===null)
 element.removeAttribute(name);
 else if(value===true)
 element.setAttribute(name,name);
 else element.setAttribute(name,value);
}
 return element;
},

 getHeight:function(element){
 return $(element).getDimensions().height;
},

 getWidth:function(element){
 return $(element).getDimensions().width;
},

 classNames:function(element){
 return new Element.ClassNames(element);
},

 hasClassName:function(element,className){
 if(!(element=$(element)))return;
 var elementClassName=element.className;
 return(elementClassName.length>0&&(elementClassName==className||
 new RegExp("(^|\\s)"+className+"(\\s|$)").test(elementClassName)));
},

 addClassName:function(element,className){
 if(!(element=$(element)))return;
 if(!element.hasClassName(className))
 element.className+=(element.className?' ':'')+className;
 return element;
},

 removeClassName:function(element,className){
 if(!(element=$(element)))return;
 element.className=element.className.replace(
 new RegExp("(^|\\s+)"+className+"(\\s+|$)"),' ').strip();
 return element;
},

 toggleClassName:function(element,className){
 if(!(element=$(element)))return;
 return element[element.hasClassName(className)?
'removeClassName':'addClassName'](className);
},


 cleanWhitespace:function(element){
 element=$(element);
 var node=element.firstChild;
 while(node){
 var nextNode=node.nextSibling;
 if(node.nodeType==3&&!/\S/.test(node.nodeValue))
 element.removeChild(node);
 node=nextNode;
}
 return element;
},

 empty:function(element){
 return $(element).innerHTML.blank();
},

 descendantOf:function(element,ancestor){
 element=$(element),ancestor=$(ancestor);
 var originalAncestor=ancestor;

 if(element.compareDocumentPosition)
 return(element.compareDocumentPosition(ancestor)&8)===8;

 if(element.sourceIndex&&!Prototype.Browser.Opera){
 var e=element.sourceIndex,a=ancestor.sourceIndex,
 nextAncestor=ancestor.nextSibling;
 if(!nextAncestor){
 do{ancestor=ancestor.parentNode;}
 while(!(nextAncestor=ancestor.nextSibling)&&ancestor.parentNode);
}
 if(nextAncestor&&nextAncestor.sourceIndex)
 return(e>a&&e<nextAncestor.sourceIndex);
}

 while(element=element.parentNode)
 if(element==originalAncestor)return true;
 return false;
},

 scrollTo:function(element){
 element=$(element);
 var pos=element.cumulativeOffset();
 window.scrollTo(pos[0],pos[1]);
 return element;
},

 getStyle:function(element,style){
 element=$(element);
 style=style=='float'?'cssFloat':style.camelize();
 var value=element.style[style];
 if(!value){
 var css=document.defaultView.getComputedStyle(element,null);
 value=css?css[style]:null;
}
 if(style=='opacity')return value?parseFloat(value):1.0;
 return value=='auto'?null:value;
},

 getOpacity:function(element){
 return $(element).getStyle('opacity');
},

 setStyle:function(element,styles){
 element=$(element);
 var elementStyle=element.style,match;
 if(Object.isString(styles)){
 element.style.cssText+=';'+styles;
 return styles.include('opacity')?
 element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element;
}
 for(var property in styles)
 if(property=='opacity')element.setOpacity(styles[property]);
 else
 elementStyle[(property=='float'||property=='cssFloat')?
(Object.isUndefined(elementStyle.styleFloat)?'cssFloat':'styleFloat'):
 property]=styles[property];

 return element;
},

 setOpacity:function(element,value){
 element=$(element);
 element.style.opacity=(value==1||value==='')?'':
(value<0.00001)?0:value;
 return element;
},

 getDimensions:function(element){
 element=$(element);
 var display=$(element).getStyle('display');
 if(display!='none'&&display!=null)
 return{width:element.offsetWidth,height:element.offsetHeight};



 var els=element.style;
 var originalVisibility=els.visibility;
 var originalPosition=els.position;
 var originalDisplay=els.display;
 els.visibility='hidden';
 els.position='absolute';
 els.display='block';
 var originalWidth=element.clientWidth;
 var originalHeight=element.clientHeight;
 els.display=originalDisplay;
 els.position=originalPosition;
 els.visibility=originalVisibility;
 return{width:originalWidth,height:originalHeight};
},

 makePositioned:function(element){
 element=$(element);
 var pos=Element.getStyle(element,'position');
 if(pos=='static'||!pos){
 element._madePositioned=true;
 element.style.position='relative';


 if(window.opera){
 element.style.top=0;
 element.style.left=0;
}
}
 return element;
},

 undoPositioned:function(element){
 element=$(element);
 if(element._madePositioned){
 element._madePositioned=undefined;
 element.style.position=
 element.style.top=
 element.style.left=
 element.style.bottom=
 element.style.right='';
}
 return element;
},

 makeClipping:function(element){
 element=$(element);
 if(element._overflow)return element;
 element._overflow=Element.getStyle(element,'overflow')||'auto';
 if(element._overflow!=='hidden')
 element.style.overflow='hidden';
 return element;
},

 undoClipping:function(element){
 element=$(element);
 if(!element._overflow)return element;
 element.style.overflow=element._overflow=='auto'?'':element._overflow;
 element._overflow=null;
 return element;
},

 cumulativeOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 element=element.offsetParent;
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 positionedOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 element=element.offsetParent;
 if(element){
 if(element.tagName=='BODY')break;
 var p=Element.getStyle(element,'position');
 if(p!=='static')break;
}
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 absolutize:function(element){
 element=$(element);
 if(element.getStyle('position')=='absolute')return;


 var offsets=element.positionedOffset();
 var top=offsets[1];
 var left=offsets[0];
 var width=element.clientWidth;
 var height=element.clientHeight;

 element._originalLeft=left-parseFloat(element.style.left||0);
 element._originalTop=top-parseFloat(element.style.top||0);
 element._originalWidth=element.style.width;
 element._originalHeight=element.style.height;

 element.style.position='absolute';
 element.style.top=top+'px';
 element.style.left=left+'px';
 element.style.width=width+'px';
 element.style.height=height+'px';
 return element;
},

 relativize:function(element){
 element=$(element);
 if(element.getStyle('position')=='relative')return;


 element.style.position='relative';
 var top=parseFloat(element.style.top||0)-(element._originalTop||0);
 var left=parseFloat(element.style.left||0)-(element._originalLeft||0);

 element.style.top=top+'px';
 element.style.left=left+'px';
 element.style.height=element._originalHeight;
 element.style.width=element._originalWidth;
 return element;
},

 cumulativeScrollOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.scrollTop||0;
 valueL+=element.scrollLeft||0;
 element=element.parentNode;
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 getOffsetParent:function(element){
 if(element.offsetParent)return $(element.offsetParent);
 if(element==document.body)return $(element);

 while((element=element.parentNode)&&element!=document.body)
 if(Element.getStyle(element,'position')!='static')
 return $(element);

 return $(document.body);
},

 viewportOffset:function(forElement){
 var valueT=0,valueL=0;

 var element=forElement;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;


 if(element.offsetParent==document.body&&
 Element.getStyle(element,'position')=='absolute')break;

}while(element=element.offsetParent);

 element=forElement;
 do{
 if(!Prototype.Browser.Opera||element.tagName=='BODY'){
 valueT-=element.scrollTop||0;
 valueL-=element.scrollLeft||0;
}
}while(element=element.parentNode);

 return Element._returnOffset(valueL,valueT);
},

 clonePosition:function(element,source){
 var options=Object.extend({
 setLeft:true,
 setTop:true,
 setWidth:true,
 setHeight:true,
 offsetTop:0,
 offsetLeft:0
},arguments[2]||{});


 source=$(source);
 var p=source.viewportOffset();


 element=$(element);
 var delta=[0,0];
 var parent=null;


 if(Element.getStyle(element,'position')=='absolute'){
 parent=element.getOffsetParent();
 delta=parent.viewportOffset();
}


 if(parent==document.body){
 delta[0]-=document.body.offsetLeft;
 delta[1]-=document.body.offsetTop;
}


 if(options.setLeft)element.style.left=(p[0]-delta[0]+options.offsetLeft)+'px';
 if(options.setTop)element.style.top=(p[1]-delta[1]+options.offsetTop)+'px';
 if(options.setWidth)element.style.width=source.offsetWidth+'px';
 if(options.setHeight)element.style.height=source.offsetHeight+'px';
 return element;
}
};

Element.Methods.identify.counter=1;

Object.extend(Element.Methods,{
 getElementsBySelector:Element.Methods.select,
 childElements:Element.Methods.immediateDescendants
});

Element._attributeTranslations={
 write:{
 names:{
 className:'class',
 htmlFor:'for'
},
 values:{}
}
};

if(Prototype.Browser.Opera){
 Element.Methods.getStyle=Element.Methods.getStyle.wrap(
 function(proceed,element,style){
 switch(style){
 case'left':case'top':case'right':case'bottom':
 if(proceed(element,'position')==='static')return null;
 case'height':case'width':

 if(!Element.visible(element))return null;



 var dim=parseInt(proceed(element,style),10);

 if(dim!==element['offset'+style.capitalize()])
 return dim+'px';

 var properties;
 if(style==='height'){
 properties=['border-top-width','padding-top',
'padding-bottom','border-bottom-width'];
}
 else{
 properties=['border-left-width','padding-left',
'padding-right','border-right-width'];
}
 return properties.inject(dim,function(memo,property){
 var val=proceed(element,property);
 return val===null?memo:memo-parseInt(val,10);
})+'px';
 default:return proceed(element,style);
}
}
);

 Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(
 function(proceed,element,attribute){
 if(attribute==='title')return element.title;
 return proceed(element,attribute);
}
);
}

else if(Prototype.Browser.IE){


 Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(
 function(proceed,element){
 element=$(element);
 var position=element.getStyle('position');
 if(position!=='static')return proceed(element);
 element.setStyle({position:'relative'});
 var value=proceed(element);
 element.setStyle({position:position});
 return value;
}
);

 $w('positionedOffset viewportOffset').each(function(method){
 Element.Methods[method]=Element.Methods[method].wrap(
 function(proceed,element){
 element=$(element);
 var position=element.getStyle('position');
 if(position!=='static')return proceed(element);


 var offsetParent=element.getOffsetParent();
 if(offsetParent&&offsetParent.getStyle('position')==='fixed')
 offsetParent.setStyle({zoom:1});
 element.setStyle({position:'relative'});
 var value=proceed(element);
 element.setStyle({position:position});
 return value;
}
);
});

 Element.Methods.getStyle=function(element,style){
 element=$(element);
 style=(style=='float'||style=='cssFloat')?'styleFloat':style.camelize();
 var value=element.style[style];
 if(!value&&element.currentStyle)value=element.currentStyle[style];

 if(style=='opacity'){
 if(value=(element.getStyle('filter')||'').match(/alpha\(opacity=(.*)\)/))
 if(value[1])return parseFloat(value[1])/100;
 return 1.0;
}

 if(value=='auto'){
 if((style=='width'||style=='height')&&(element.getStyle('display')!='none'))
 return element['offset'+style.capitalize()]+'px';
 return null;
}
 return value;
};

 Element.Methods.setOpacity=function(element,value){
 function stripAlpha(filter){
 return filter.replace(/alpha\([^\)]*\)/gi,'');
}
 element=$(element);
 var currentStyle=element.currentStyle;
 if((currentStyle&&!currentStyle.hasLayout)||
(!currentStyle&&element.style.zoom=='normal'))
 element.style.zoom=1;

 var filter=element.getStyle('filter'),style=element.style;
 if(value==1||value===''){
(filter=stripAlpha(filter))?
 style.filter=filter:style.removeAttribute('filter');
 return element;
}else if(value<0.00001)value=0;
 style.filter=stripAlpha(filter)+
'alpha(opacity='+(value*100)+')';
 return element;
};

 Element._attributeTranslations={
 read:{
 names:{
'class':'className',
'for':'htmlFor'
},
 values:{
 _getAttr:function(element,attribute){
 return element.getAttribute(attribute,2);
},
 _getAttrNode:function(element,attribute){
 var node=element.getAttributeNode(attribute);
 return node?node.value:"";
},
 _getEv:function(element,attribute){
 attribute=element.getAttribute(attribute);
 return attribute?attribute.toString().slice(23,-2):null;
},
 _flag:function(element,attribute){
 return $(element).hasAttribute(attribute)?attribute:null;
},
 style:function(element){
 return element.style.cssText.toLowerCase();
},
 title:function(element){
 return element.title;
}
}
}
};

 Element._attributeTranslations.write={
 names:Object.extend({
 cellpadding:'cellPadding',
 cellspacing:'cellSpacing'
},Element._attributeTranslations.read.names),
 values:{
 checked:function(element,value){
 element.checked=!!value;
},

 style:function(element,value){
 element.style.cssText=value?value:'';
}
}
};

 Element._attributeTranslations.has={};

 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex '+
'encType maxLength readOnly longDesc').each(function(attr){
 Element._attributeTranslations.write.names[attr.toLowerCase()]=attr;
 Element._attributeTranslations.has[attr.toLowerCase()]=attr;
});

(function(v){
 Object.extend(v,{
 href:v._getAttr,
 src:v._getAttr,
 type:v._getAttr,
 action:v._getAttrNode,
 disabled:v._flag,
 checked:v._flag,
 readonly:v._flag,
 multiple:v._flag,
 onload:v._getEv,
 onunload:v._getEv,
 onclick:v._getEv,
 ondblclick:v._getEv,
 onmousedown:v._getEv,
 onmouseup:v._getEv,
 onmouseover:v._getEv,
 onmousemove:v._getEv,
 onmouseout:v._getEv,
 onfocus:v._getEv,
 onblur:v._getEv,
 onkeypress:v._getEv,
 onkeydown:v._getEv,
 onkeyup:v._getEv,
 onsubmit:v._getEv,
 onreset:v._getEv,
 onselect:v._getEv,
 onchange:v._getEv
});
})(Element._attributeTranslations.read.values);
}

else if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){
 Element.Methods.setOpacity=function(element,value){
 element=$(element);
 element.style.opacity=(value==1)?0.999999:
(value==='')?'':(value<0.00001)?0:value;
 return element;
};
}

else if(Prototype.Browser.WebKit){
 Element.Methods.setOpacity=function(element,value){
 element=$(element);
 element.style.opacity=(value==1||value==='')?'':
(value<0.00001)?0:value;

 if(value==1)
 if(element.tagName=='IMG'&&element.width){
 element.width++;element.width--;
}else try{
 var n=document.createTextNode(' ');
 element.appendChild(n);
 element.removeChild(n);
}catch(e){}

 return element;
};




 Element.Methods.cumulativeOffset=function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 if(element.offsetParent==document.body)
 if(Element.getStyle(element,'position')=='absolute')break;

 element=element.offsetParent;
}while(element);

 return Element._returnOffset(valueL,valueT);
};
}

if(Prototype.Browser.IE||Prototype.Browser.Opera){

 Element.Methods.update=function(element,content){
 element=$(element);

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content))return element.update().insert(content);

 content=Object.toHTML(content);
 var tagName=element.tagName.toUpperCase();

 if(tagName in Element._insertionTranslations.tags){
 $A(element.childNodes).each(function(node){element.removeChild(node)});
 Element._getContentFromAnonymousElement(tagName,content.stripScripts())
.each(function(node){element.appendChild(node)});
}
 else element.innerHTML=content.stripScripts();

 content.evalScripts.bind(content).defer();
 return element;
};
}

if('outerHTML'in document.createElement('div')){
 Element.Methods.replace=function(element,content){
 element=$(element);

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content)){
 element.parentNode.replaceChild(content,element);
 return element;
}

 content=Object.toHTML(content);
 var parent=element.parentNode,tagName=parent.tagName.toUpperCase();

 if(Element._insertionTranslations.tags[tagName]){
 var nextSibling=element.next();
 var fragments=Element._getContentFromAnonymousElement(tagName,content.stripScripts());
 parent.removeChild(element);
 if(nextSibling)
 fragments.each(function(node){parent.insertBefore(node,nextSibling)});
 else
 fragments.each(function(node){parent.appendChild(node)});
}
 else element.outerHTML=content.stripScripts();

 content.evalScripts.bind(content).defer();
 return element;
};
}

Element._returnOffset=function(l,t){
 var result=[l,t];
 result.left=l;
 result.top=t;
 return result;
};

Element._getContentFromAnonymousElement=function(tagName,html){
 var div=new Element('div'),t=Element._insertionTranslations.tags[tagName];
 if(t){
 div.innerHTML=t[0]+html+t[1];
 t[2].times(function(){div=div.firstChild});
}else div.innerHTML=html;
 return $A(div.childNodes);
};

Element._insertionTranslations={
 before:function(element,node){
 element.parentNode.insertBefore(node,element);
},
 top:function(element,node){
 element.insertBefore(node,element.firstChild);
},
 bottom:function(element,node){
 element.appendChild(node);
},
 after:function(element,node){
 element.parentNode.insertBefore(node,element.nextSibling);
},
 tags:{
 TABLE:['<table>','</table>',1],
 TBODY:['<table><tbody>','</tbody></table>',2],
 TR:['<table><tbody><tr>','</tr></tbody></table>',3],
 TD:['<table><tbody><tr><td>','</td></tr></tbody></table>',4],
 SELECT:['<select>','</select>',1]
}
};

(function(){
 Object.extend(this.tags,{
 THEAD:this.tags.TBODY,
 TFOOT:this.tags.TBODY,
 TH:this.tags.TD
});
}).call(Element._insertionTranslations);

Element.Methods.Simulated={
 hasAttribute:function(element,attribute){
 attribute=Element._attributeTranslations.has[attribute]||attribute;
 var node=$(element).getAttributeNode(attribute);
 return node&&node.specified;
}
};

Element.Methods.ByTag={};

Object.extend(Element,Element.Methods);

if(!Prototype.BrowserFeatures.ElementExtensions&&
 document.createElement('div').__proto__){
 window.HTMLElement={};
 window.HTMLElement.prototype=document.createElement('div').__proto__;
 Prototype.BrowserFeatures.ElementExtensions=true;
}

Element.extend=(function(){
 if(Prototype.BrowserFeatures.SpecificElementExtensions)
 return Prototype.K;

 var Methods={},ByTag=Element.Methods.ByTag;

 var extend=Object.extend(function(element){
 if(!element||element._extendedByPrototype||
 element.nodeType!=1||element==window)return element;

 var methods=Object.clone(Methods),
 tagName=element.tagName,property,value;


 if(ByTag[tagName])Object.extend(methods,ByTag[tagName]);

 for(property in methods){
 value=methods[property];
 if(Object.isFunction(value)&&!(property in element))
 element[property]=value.methodize();
}

 element._extendedByPrototype=Prototype.emptyFunction;
 return element;

},{
 refresh:function(){

 if(!Prototype.BrowserFeatures.ElementExtensions){
 Object.extend(Methods,Element.Methods);
 Object.extend(Methods,Element.Methods.Simulated);
}
}
});

 extend.refresh();
 return extend;
})();

Element.hasAttribute=function(element,attribute){
 if(element.hasAttribute)return element.hasAttribute(attribute);
 return Element.Methods.Simulated.hasAttribute(element,attribute);
};

Element.addMethods=function(methods){
 var F=Prototype.BrowserFeatures,T=Element.Methods.ByTag;

 if(!methods){
 Object.extend(Form,Form.Methods);
 Object.extend(Form.Element,Form.Element.Methods);
 Object.extend(Element.Methods.ByTag,{
"FORM":Object.clone(Form.Methods),
"INPUT":Object.clone(Form.Element.Methods),
"SELECT":Object.clone(Form.Element.Methods),
"TEXTAREA":Object.clone(Form.Element.Methods)
});
}

 if(arguments.length==2){
 var tagName=methods;
 methods=arguments[1];
}

 if(!tagName)Object.extend(Element.Methods,methods||{});
 else{
 if(Object.isArray(tagName))tagName.each(extend);
 else extend(tagName);
}

 function extend(tagName){
 tagName=tagName.toUpperCase();
 if(!Element.Methods.ByTag[tagName])
 Element.Methods.ByTag[tagName]={};
 Object.extend(Element.Methods.ByTag[tagName],methods);
}

 function copy(methods,destination,onlyIfAbsent){
 onlyIfAbsent=onlyIfAbsent||false;
 for(var property in methods){
 var value=methods[property];
 if(!Object.isFunction(value))continue;
 if(!onlyIfAbsent||!(property in destination))
 destination[property]=value.methodize();
}
}

 function findDOMClass(tagName){
 var klass;
 var trans={
"OPTGROUP":"OptGroup","TEXTAREA":"TextArea","P":"Paragraph",
"FIELDSET":"FieldSet","UL":"UList","OL":"OList","DL":"DList",
"DIR":"Directory","H1":"Heading","H2":"Heading","H3":"Heading",
"H4":"Heading","H5":"Heading","H6":"Heading","Q":"Quote",
"INS":"Mod","DEL":"Mod","A":"Anchor","IMG":"Image","CAPTION":
"TableCaption","COL":"TableCol","COLGROUP":"TableCol","THEAD":
"TableSection","TFOOT":"TableSection","TBODY":"TableSection","TR":
"TableRow","TH":"TableCell","TD":"TableCell","FRAMESET":
"FrameSet","IFRAME":"IFrame"
};
 if(trans[tagName])klass='HTML'+trans[tagName]+'Element';
 if(window[klass])return window[klass];
 klass='HTML'+tagName+'Element';
 if(window[klass])return window[klass];
 klass='HTML'+tagName.capitalize()+'Element';
 if(window[klass])return window[klass];

 window[klass]={};
 window[klass].prototype=document.createElement(tagName).__proto__;
 return window[klass];
}

 if(F.ElementExtensions){
 copy(Element.Methods,HTMLElement.prototype);
 copy(Element.Methods.Simulated,HTMLElement.prototype,true);
}

 if(F.SpecificElementExtensions){
 for(var tag in Element.Methods.ByTag){
 var klass=findDOMClass(tag);
 if(Object.isUndefined(klass))continue;
 copy(T[tag],klass.prototype);
}
}

 Object.extend(Element,Element.Methods);
 delete Element.ByTag;

 if(Element.extend.refresh)Element.extend.refresh();
 Element.cache={};
};

document.viewport={
 getDimensions:function(){
 var dimensions={};
 var B=Prototype.Browser;
 $w('width height').each(function(d){
 var D=d.capitalize();
 dimensions[d]=(B.WebKit&&!document.evaluate)?self['inner'+D]:
(B.Opera)?document.body['client'+D]:document.documentElement['client'+D];
});
 return dimensions;
},

 getWidth:function(){
 return this.getDimensions().width;
},

 getHeight:function(){
 return this.getDimensions().height;
},

 getScrollOffsets:function(){
 return Element._returnOffset(
 window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,
 window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop);
}
};


var Selector=Class.create({
 initialize:function(expression){
 this.expression=expression.strip();
 this.compileMatcher();
},

 shouldUseXPath:function(){
 if(!Prototype.BrowserFeatures.XPath)return false;

 var e=this.expression;


 if(Prototype.Browser.WebKit&&
(e.include("-of-type")||e.include(":empty")))
 return false;



 if((/(\[[\w-]*?:|:checked)/).test(this.expression))
 return false;

 return true;
},

 compileMatcher:function(){
 if(this.shouldUseXPath())
 return this.compileXPathMatcher();

 var e=this.expression,ps=Selector.patterns,h=Selector.handlers,
 c=Selector.criteria,le,p,m;

 if(Selector._cache[e]){
 this.matcher=Selector._cache[e];
 return;
}

 this.matcher=["this.matcher = function(root) {",
"var r = root, h = Selector.handlers, c = false, n;"];

 while(e&&le!=e&&(/\S/).test(e)){
 le=e;
 for(var i in ps){
 p=ps[i];
 if(m=e.match(p)){
 this.matcher.push(Object.isFunction(c[i])?c[i](m):
 new Template(c[i]).evaluate(m));
 e=e.replace(m[0],'');
 break;
}
}
}

 this.matcher.push("return h.unique(n);\n}");
 eval(this.matcher.join('\n'));
 Selector._cache[this.expression]=this.matcher;
},

 compileXPathMatcher:function(){
 var e=this.expression,ps=Selector.patterns,
 x=Selector.xpath,le,m;

 if(Selector._cache[e]){
 this.xpath=Selector._cache[e];return;
}

 this.matcher=['.//*'];
 while(e&&le!=e&&(/\S/).test(e)){
 le=e;
 for(var i in ps){
 if(m=e.match(ps[i])){
 this.matcher.push(Object.isFunction(x[i])?x[i](m):
 new Template(x[i]).evaluate(m));
 e=e.replace(m[0],'');
 break;
}
}
}

 this.xpath=this.matcher.join('');
 Selector._cache[this.expression]=this.xpath;
},

 findElements:function(root){
 root=root||document;
 if(this.xpath)return document._getElementsByXPath(this.xpath,root);
 return this.matcher(root);
},

 match:function(element){
 this.tokens=[];

 var e=this.expression,ps=Selector.patterns,as=Selector.assertions;
 var le,p,m;

 while(e&&le!==e&&(/\S/).test(e)){
 le=e;
 for(var i in ps){
 p=ps[i];
 if(m=e.match(p)){


 if(as[i]){
 this.tokens.push([i,Object.clone(m)]);
 e=e.replace(m[0],'');
}else{


 return this.findElements(document).include(element);
}
}
}
}

 var match=true,name,matches;
 for(var i=0,token;token=this.tokens[i];i++){
 name=token[0],matches=token[1];
 if(!Selector.assertions[name](element,matches)){
 match=false;break;
}
}

 return match;
},

 toString:function(){
 return this.expression;
},

 inspect:function(){
 return"#<Selector:"+this.expression.inspect()+">";
}
});

Object.extend(Selector,{
 _cache:{},

 xpath:{
 descendant:"//*",
 child:"/*",
 adjacent:"/following-sibling::*[1]",
 laterSibling:'/following-sibling::*',
 tagName:function(m){
 if(m[1]=='*')return'';
 return"[local-name()='"+m[1].toLowerCase()+
"' or local-name()='"+m[1].toUpperCase()+"']";
},
 className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",
 id:"[@id='#{1}']",
 attrPresence:function(m){
 m[1]=m[1].toLowerCase();
 return new Template("[@#{1}]").evaluate(m);
},
 attr:function(m){
 m[1]=m[1].toLowerCase();
 m[3]=m[5]||m[6];
 return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
},
 pseudo:function(m){
 var h=Selector.xpath.pseudos[m[1]];
 if(!h)return'';
 if(Object.isFunction(h))return h(m);
 return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
},
 operators:{
'=':"[@#{1}='#{3}']",
'!=':"[@#{1}!='#{3}']",
'^=':"[starts-with(@#{1}, '#{3}')]",
'$=':"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
'*=':"[contains(@#{1}, '#{3}')]",
'~=':"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
'|=':"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
},
 pseudos:{
'first-child':'[not(preceding-sibling::*)]',
'last-child':'[not(following-sibling::*)]',
'only-child':'[not(preceding-sibling::* or following-sibling::*)]',
'empty':"[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
'checked':"[@checked]",
'disabled':"[@disabled]",
'enabled':"[not(@disabled)]",
'not':function(m){
 var e=m[6],p=Selector.patterns,
 x=Selector.xpath,le,v;

 var exclusion=[];
 while(e&&le!=e&&(/\S/).test(e)){
 le=e;
 for(var i in p){
 if(m=e.match(p[i])){
 v=Object.isFunction(x[i])?x[i](m):new Template(x[i]).evaluate(m);
 exclusion.push("("+v.substring(1,v.length-1)+")");
 e=e.replace(m[0],'');
 break;
}
}
}
 return"[not("+exclusion.join(" and ")+")]";
},
'nth-child':function(m){
 return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",m);
},
'nth-last-child':function(m){
 return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",m);
},
'nth-of-type':function(m){
 return Selector.xpath.pseudos.nth("position() ",m);
},
'nth-last-of-type':function(m){
 return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",m);
},
'first-of-type':function(m){
 m[6]="1";return Selector.xpath.pseudos['nth-of-type'](m);
},
'last-of-type':function(m){
 m[6]="1";return Selector.xpath.pseudos['nth-last-of-type'](m);
},
'only-of-type':function(m){
 var p=Selector.xpath.pseudos;return p['first-of-type'](m)+p['last-of-type'](m);
},
 nth:function(fragment,m){
 var mm,formula=m[6],predicate;
 if(formula=='even')formula='2n+0';
 if(formula=='odd')formula='2n+1';
 if(mm=formula.match(/^(\d+)$/))
 return'['+fragment+"= "+mm[1]+']';
 if(mm=formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){
 if(mm[1]=="-")mm[1]=-1;
 var a=mm[1]?Number(mm[1]):1;
 var b=mm[2]?Number(mm[2]):0;
 predicate="[((#{fragment} - #{b}) mod #{a} = 0) and "+
"((#{fragment} - #{b}) div #{a} >= 0)]";
 return new Template(predicate).evaluate({
 fragment:fragment,a:a,b:b});
}
}
}
},

 criteria:{
 tagName:'n = h.tagName(n, r, "#{1}", c);      c = false;',
 className:'n = h.className(n, r, "#{1}", c);    c = false;',
 id:'n = h.id(n, r, "#{1}", c);           c = false;',
 attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',
 attr:function(m){
 m[3]=(m[5]||m[6]);
 return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
},
 pseudo:function(m){
 if(m[6])m[6]=m[6].replace(/"/g,'\\"');
 return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
},
 descendant:'c = "descendant";',
 child:'c = "child";',
 adjacent:'c = "adjacent";',
 laterSibling:'c = "laterSibling";'
},

 patterns:{


 laterSibling:/^\s*~\s*/,
 child:/^\s*>\s*/,
 adjacent:/^\s*\+\s*/,
 descendant:/^\s/,


 tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,
 id:/^#([\w\-\*]+)(\b|$)/,
 className:/^\.([\w\-\*]+)(\b|$)/,
 pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
 attrPresence:/^\[([\w]+)\]/,
 attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
},


 assertions:{
 tagName:function(element,matches){
 return matches[1].toUpperCase()==element.tagName.toUpperCase();
},

 className:function(element,matches){
 return Element.hasClassName(element,matches[1]);
},

 id:function(element,matches){
 return element.id===matches[1];
},

 attrPresence:function(element,matches){
 return Element.hasAttribute(element,matches[1]);
},

 attr:function(element,matches){
 var nodeValue=Element.readAttribute(element,matches[1]);
 return nodeValue&&Selector.operators[matches[2]](nodeValue,matches[5]||matches[6]);
}
},

 handlers:{


 concat:function(a,b){
 for(var i=0,node;node=b[i];i++)
 a.push(node);
 return a;
},


 mark:function(nodes){
 var _true=Prototype.emptyFunction;
 for(var i=0,node;node=nodes[i];i++)
 node._countedByPrototype=_true;
 return nodes;
},

 unmark:function(nodes){
 for(var i=0,node;node=nodes[i];i++)
 node._countedByPrototype=undefined;
 return nodes;
},




 index:function(parentNode,reverse,ofType){
 parentNode._countedByPrototype=Prototype.emptyFunction;
 if(reverse){
 for(var nodes=parentNode.childNodes,i=nodes.length-1,j=1;i>=0;i--){
 var node=nodes[i];
 if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;
}
}else{
 for(var i=0,j=1,nodes=parentNode.childNodes;node=nodes[i];i++)
 if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;
}
},


 unique:function(nodes){
 if(nodes.length==0)return nodes;
 var results=[],n;
 for(var i=0,l=nodes.length;i<l;i++)
 if(!(n=nodes[i])._countedByPrototype){
 n._countedByPrototype=Prototype.emptyFunction;
 results.push(Element.extend(n));
}
 return Selector.handlers.unmark(results);
},


 descendant:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 h.concat(results,node.getElementsByTagName('*'));
 return results;
},

 child:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++){
 for(var j=0,child;child=node.childNodes[j];j++)
 if(child.nodeType==1&&child.tagName!='!')results.push(child);
}
 return results;
},

 adjacent:function(nodes){
 for(var i=0,results=[],node;node=nodes[i];i++){
 var next=this.nextElementSibling(node);
 if(next)results.push(next);
}
 return results;
},

 laterSibling:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 h.concat(results,Element.nextSiblings(node));
 return results;
},

 nextElementSibling:function(node){
 while(node=node.nextSibling)
 if(node.nodeType==1)return node;
 return null;
},

 previousElementSibling:function(node){
 while(node=node.previousSibling)
 if(node.nodeType==1)return node;
 return null;
},


 tagName:function(nodes,root,tagName,combinator){
 var uTagName=tagName.toUpperCase();
 var results=[],h=Selector.handlers;
 if(nodes){
 if(combinator){

 if(combinator=="descendant"){
 for(var i=0,node;node=nodes[i];i++)
 h.concat(results,node.getElementsByTagName(tagName));
 return results;
}else nodes=this[combinator](nodes);
 if(tagName=="*")return nodes;
}
 for(var i=0,node;node=nodes[i];i++)
 if(node.tagName.toUpperCase()===uTagName)results.push(node);
 return results;
}else return root.getElementsByTagName(tagName);
},

 id:function(nodes,root,id,combinator){
 var targetNode=$(id),h=Selector.handlers;
 if(!targetNode)return[];
 if(!nodes&&root==document)return[targetNode];
 if(nodes){
 if(combinator){
 if(combinator=='child'){
 for(var i=0,node;node=nodes[i];i++)
 if(targetNode.parentNode==node)return[targetNode];
}else if(combinator=='descendant'){
 for(var i=0,node;node=nodes[i];i++)
 if(Element.descendantOf(targetNode,node))return[targetNode];
}else if(combinator=='adjacent'){
 for(var i=0,node;node=nodes[i];i++)
 if(Selector.handlers.previousElementSibling(targetNode)==node)
 return[targetNode];
}else nodes=h[combinator](nodes);
}
 for(var i=0,node;node=nodes[i];i++)
 if(node==targetNode)return[targetNode];
 return[];
}
 return(targetNode&&Element.descendantOf(targetNode,root))?[targetNode]:[];
},

 className:function(nodes,root,className,combinator){
 if(nodes&&combinator)nodes=this[combinator](nodes);
 return Selector.handlers.byClassName(nodes,root,className);
},

 byClassName:function(nodes,root,className){
 if(!nodes)nodes=Selector.handlers.descendant([root]);
 var needle=' '+className+' ';
 for(var i=0,results=[],node,nodeClassName;node=nodes[i];i++){
 nodeClassName=node.className;
 if(nodeClassName.length==0)continue;
 if(nodeClassName==className||(' '+nodeClassName+' ').include(needle))
 results.push(node);
}
 return results;
},

 attrPresence:function(nodes,root,attr,combinator){
 if(!nodes)nodes=root.getElementsByTagName("*");
 if(nodes&&combinator)nodes=this[combinator](nodes);
 var results=[];
 for(var i=0,node;node=nodes[i];i++)
 if(Element.hasAttribute(node,attr))results.push(node);
 return results;
},

 attr:function(nodes,root,attr,value,operator,combinator){
 if(!nodes)nodes=root.getElementsByTagName("*");
 if(nodes&&combinator)nodes=this[combinator](nodes);
 var handler=Selector.operators[operator],results=[];
 for(var i=0,node;node=nodes[i];i++){
 var nodeValue=Element.readAttribute(node,attr);
 if(nodeValue===null)continue;
 if(handler(nodeValue,value))results.push(node);
}
 return results;
},

 pseudo:function(nodes,name,value,root,combinator){
 if(nodes&&combinator)nodes=this[combinator](nodes);
 if(!nodes)nodes=root.getElementsByTagName("*");
 return Selector.pseudos[name](nodes,value,root);
}
},

 pseudos:{
'first-child':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){
 if(Selector.handlers.previousElementSibling(node))continue;
 results.push(node);
}
 return results;
},
'last-child':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){
 if(Selector.handlers.nextElementSibling(node))continue;
 results.push(node);
}
 return results;
},
'only-child':function(nodes,value,root){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!h.previousElementSibling(node)&&!h.nextElementSibling(node))
 results.push(node);
 return results;
},
'nth-child':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root);
},
'nth-last-child':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,true);
},
'nth-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,false,true);
},
'nth-last-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,true,true);
},
'first-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,"1",root,false,true);
},
'last-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,"1",root,true,true);
},
'only-of-type':function(nodes,formula,root){
 var p=Selector.pseudos;
 return p['last-of-type'](p['first-of-type'](nodes,formula,root),formula,root);
},


 getIndices:function(a,b,total){
 if(a==0)return b>0?[b]:[];
 return $R(1,total).inject([],function(memo,i){
 if(0==(i-b)%a&&(i-b)/a>=0)memo.push(i);
 return memo;
});
},


 nth:function(nodes,formula,root,reverse,ofType){
 if(nodes.length==0)return[];
 if(formula=='even')formula='2n+0';
 if(formula=='odd')formula='2n+1';
 var h=Selector.handlers,results=[],indexed=[],m;
 h.mark(nodes);
 for(var i=0,node;node=nodes[i];i++){
 if(!node.parentNode._countedByPrototype){
 h.index(node.parentNode,reverse,ofType);
 indexed.push(node.parentNode);
}
}
 if(formula.match(/^\d+$/)){
 formula=Number(formula);
 for(var i=0,node;node=nodes[i];i++)
 if(node.nodeIndex==formula)results.push(node);
}else if(m=formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){
 if(m[1]=="-")m[1]=-1;
 var a=m[1]?Number(m[1]):1;
 var b=m[2]?Number(m[2]):0;
 var indices=Selector.pseudos.getIndices(a,b,nodes.length);
 for(var i=0,node,l=indices.length;node=nodes[i];i++){
 for(var j=0;j<l;j++)
 if(node.nodeIndex==indices[j])results.push(node);
}
}
 h.unmark(nodes);
 h.unmark(indexed);
 return results;
},

'empty':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){

 if(node.tagName=='!'||(node.firstChild&&!node.innerHTML.match(/^\s*$/)))continue;
 results.push(node);
}
 return results;
},

'not':function(nodes,selector,root){
 var h=Selector.handlers,selectorType,m;
 var exclusions=new Selector(selector).findElements(root);
 h.mark(exclusions);
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!node._countedByPrototype)results.push(node);
 h.unmark(exclusions);
 return results;
},

'enabled':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!node.disabled)results.push(node);
 return results;
},

'disabled':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(node.disabled)results.push(node);
 return results;
},

'checked':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(node.checked)results.push(node);
 return results;
}
},

 operators:{
'=':function(nv,v){return nv==v;},
'!=':function(nv,v){return nv!=v;},
'^=':function(nv,v){return nv.startsWith(v);},
'$=':function(nv,v){return nv.endsWith(v);},
'*=':function(nv,v){return nv.include(v);},
'~=':function(nv,v){return(' '+nv+' ').include(' '+v+' ');},
'|=':function(nv,v){return('-'+nv.toUpperCase()+'-').include('-'+v.toUpperCase()+'-');}
},

 split:function(expression){
 var expressions=[];
 expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){
 expressions.push(m[1].strip());
});
 return expressions;
},

 matchElements:function(elements,expression){
 var matches=$$(expression),h=Selector.handlers;
 h.mark(matches);
 for(var i=0,results=[],element;element=elements[i];i++)
 if(element._countedByPrototype)results.push(element);
 h.unmark(matches);
 return results;
},

 findElement:function(elements,expression,index){
 if(Object.isNumber(expression)){
 index=expression;expression=false;
}
 return Selector.matchElements(elements,expression||'*')[index||0];
},

 findChildElements:function(element,expressions){
 expressions=Selector.split(expressions.join(','));
 var results=[],h=Selector.handlers;
 for(var i=0,l=expressions.length,selector;i<l;i++){
 selector=new Selector(expressions[i].strip());
 h.concat(results,selector.findElements(element));
}
 return(l>1)?h.unique(results):results;
}
});

if(Prototype.Browser.IE){
 Object.extend(Selector.handlers,{


 concat:function(a,b){
 for(var i=0,node;node=b[i];i++)
 if(node.tagName!=="!")a.push(node);
 return a;
},


 unmark:function(nodes){
 for(var i=0,node;node=nodes[i];i++)
 node.removeAttribute('_countedByPrototype');
 return nodes;
}
});
}

function $$(){
 return Selector.findChildElements(document,$A(arguments));
}
var Form={
 reset:function(form){
 $(form).reset();
 return form;
},

 serializeElements:function(elements,options){
 if(typeof options!='object')options={hash:!!options};
 else if(Object.isUndefined(options.hash))options.hash=true;
 var key,value,submitted=false,submit=options.submit;

 var data=elements.inject({},function(result,element){
 if(!element.disabled&&element.name){
 key=element.name;value=$(element).getValue();
 if(value!=null&&(element.type!='submit'||(!submitted&&
 submit!==false&&(!submit||key==submit)&&(submitted=true)))){
 if(key in result){

 if(!Object.isArray(result[key]))result[key]=[result[key]];
 result[key].push(value);
}
 else result[key]=value;
}
}
 return result;
});

 return options.hash?data:Object.toQueryString(data);
}
};

Form.Methods={
 serialize:function(form,options){
 return Form.serializeElements(Form.getElements(form),options);
},

 getElements:function(form){
 return $A($(form).getElementsByTagName('*')).inject([],
 function(elements,child){
 if(Form.Element.Serializers[child.tagName.toLowerCase()])
 elements.push(Element.extend(child));
 return elements;
}
);
},

 getInputs:function(form,typeName,name){
 form=$(form);
 var inputs=form.getElementsByTagName('input');

 if(!typeName&&!name)return $A(inputs).map(Element.extend);

 for(var i=0,matchingInputs=[],length=inputs.length;i<length;i++){
 var input=inputs[i];
 if((typeName&&input.type!=typeName)||(name&&input.name!=name))
 continue;
 matchingInputs.push(Element.extend(input));
}

 return matchingInputs;
},

 disable:function(form){
 form=$(form);
 Form.getElements(form).invoke('disable');
 return form;
},

 enable:function(form){
 form=$(form);
 Form.getElements(form).invoke('enable');
 return form;
},

 findFirstElement:function(form){
 var elements=$(form).getElements().findAll(function(element){
 return'hidden'!=element.type&&!element.disabled;
});
 var firstByIndex=elements.findAll(function(element){
 return element.hasAttribute('tabIndex')&&element.tabIndex>=0;
}).sortBy(function(element){return element.tabIndex}).first();

 return firstByIndex?firstByIndex:elements.find(function(element){
 return['input','select','textarea'].include(element.tagName.toLowerCase());
});
},

 focusFirstElement:function(form){
 form=$(form);
 form.findFirstElement().activate();
 return form;
},

 request:function(form,options){
 form=$(form),options=Object.clone(options||{});

 var params=options.parameters,action=form.readAttribute('action')||'';
 if(action.blank())action=window.location.href;
 options.parameters=form.serialize(true);

 if(params){
 if(Object.isString(params))params=params.toQueryParams();
 Object.extend(options.parameters,params);
}

 if(form.hasAttribute('method')&&!options.method)
 options.method=form.method;

 return new Ajax.Request(action,options);
}
};



Form.Element={
 focus:function(element){
 $(element).focus();
 return element;
},

 select:function(element){
 $(element).select();
 return element;
}
};

Form.Element.Methods={
 serialize:function(element){
 element=$(element);
 if(!element.disabled&&element.name){
 var value=element.getValue();
 if(value!=undefined){
 var pair={};
 pair[element.name]=value;
 return Object.toQueryString(pair);
}
}
 return'';
},

 getValue:function(element){
 element=$(element);
 var method=element.tagName.toLowerCase();
 return Form.Element.Serializers[method](element);
},

 setValue:function(element,value){
 element=$(element);
 var method=element.tagName.toLowerCase();
 Form.Element.Serializers[method](element,value);
 return element;
},

 clear:function(element){
 $(element).value='';
 return element;
},

 present:function(element){
 return $(element).value!='';
},

 activate:function(element){
 element=$(element);
 try{
 element.focus();
 if(element.select&&(element.tagName.toLowerCase()!='input'||
!['button','reset','submit'].include(element.type)))
 element.select();
}catch(e){}
 return element;
},

 disable:function(element){
 element=$(element);
 element.blur();
 element.disabled=true;
 return element;
},

 enable:function(element){
 element=$(element);
 element.disabled=false;
 return element;
}
};



var Field=Form.Element;
var $F=Form.Element.Methods.getValue;



Form.Element.Serializers={
 input:function(element,value){
 switch(element.type.toLowerCase()){
 case'checkbox':
 case'radio':
 return Form.Element.Serializers.inputSelector(element,value);
 default:
 return Form.Element.Serializers.textarea(element,value);
}
},

 inputSelector:function(element,value){
 if(Object.isUndefined(value))return element.checked?element.value:null;
 else element.checked=!!value;
},

 textarea:function(element,value){
 if(Object.isUndefined(value))return element.value;
 else element.value=value;
},

 select:function(element,index){
 if(Object.isUndefined(index))
 return this[element.type=='select-one'?
'selectOne':'selectMany'](element);
 else{
 var opt,value,single=!Object.isArray(index);
 for(var i=0,length=element.length;i<length;i++){
 opt=element.options[i];
 value=this.optionValue(opt);
 if(single){
 if(value==index){
 opt.selected=true;
 return;
}
}
 else opt.selected=index.include(value);
}
}
},

 selectOne:function(element){
 var index=element.selectedIndex;
 return index>=0?this.optionValue(element.options[index]):null;
},

 selectMany:function(element){
 var values,length=element.length;
 if(!length)return null;

 for(var i=0,values=[];i<length;i++){
 var opt=element.options[i];
 if(opt.selected)values.push(this.optionValue(opt));
}
 return values;
},

 optionValue:function(opt){

 return Element.extend(opt).hasAttribute('value')?opt.value:opt.text;
}
};



Abstract.TimedObserver=Class.create(PeriodicalExecuter,{
 initialize:function($super,element,frequency,callback){
 $super(callback,frequency);
 this.element=$(element);
 this.lastValue=this.getValue();
},

 execute:function(){
 var value=this.getValue();
 if(Object.isString(this.lastValue)&&Object.isString(value)?
 this.lastValue!=value:String(this.lastValue)!=String(value)){
 this.callback(this.element,value);
 this.lastValue=value;
}
}
});

Form.Element.Observer=Class.create(Abstract.TimedObserver,{
 getValue:function(){
 return Form.Element.getValue(this.element);
}
});

Form.Observer=Class.create(Abstract.TimedObserver,{
 getValue:function(){
 return Form.serialize(this.element);
}
});



Abstract.EventObserver=Class.create({
 initialize:function(element,callback){
 this.element=$(element);
 this.callback=callback;

 this.lastValue=this.getValue();
 if(this.element.tagName.toLowerCase()=='form')
 this.registerFormCallbacks();
 else
 this.registerCallback(this.element);
},

 onElementEvent:function(){
 var value=this.getValue();
 if(this.lastValue!=value){
 this.callback(this.element,value);
 this.lastValue=value;
}
},

 registerFormCallbacks:function(){
 Form.getElements(this.element).each(this.registerCallback,this);
},

 registerCallback:function(element){
 if(element.type){
 switch(element.type.toLowerCase()){
 case'checkbox':
 case'radio':
 Event.observe(element,'click',this.onElementEvent.bind(this));
 break;
 default:
 Event.observe(element,'change',this.onElementEvent.bind(this));
 break;
}
}
}
});

Form.Element.EventObserver=Class.create(Abstract.EventObserver,{
 getValue:function(){
 return Form.Element.getValue(this.element);
}
});

Form.EventObserver=Class.create(Abstract.EventObserver,{
 getValue:function(){
 return Form.serialize(this.element);
}
});
if(!window.Event)var Event={};

Object.extend(Event,{
 KEY_BACKSPACE:8,
 KEY_TAB:9,
 KEY_RETURN:13,
 KEY_ESC:27,
 KEY_LEFT:37,
 KEY_UP:38,
 KEY_RIGHT:39,
 KEY_DOWN:40,
 KEY_DELETE:46,
 KEY_HOME:36,
 KEY_END:35,
 KEY_PAGEUP:33,
 KEY_PAGEDOWN:34,
 KEY_INSERT:45,

 cache:{},

 relatedTarget:function(event){
 var element;
 switch(event.type){
 case'mouseover':element=event.fromElement;break;
 case'mouseout':element=event.toElement;break;
 default:return null;
}
 return Element.extend(element);
}
});

Event.Methods=(function(){
 var isButton;

 if(Prototype.Browser.IE){
 var buttonMap={0:1,1:4,2:2};
 isButton=function(event,code){
 return event.button==buttonMap[code];
};

}else if(Prototype.Browser.WebKit){
 isButton=function(event,code){
 switch(code){
 case 0:return event.which==1&&!event.metaKey;
 case 1:return event.which==1&&event.metaKey;
 default:return false;
}
};

}else{
 isButton=function(event,code){
 return event.which?(event.which===code+1):(event.button===code);
};
}

 return{
 isLeftClick:function(event){return isButton(event,0)},
 isMiddleClick:function(event){return isButton(event,1)},
 isRightClick:function(event){return isButton(event,2)},

 element:function(event){
 var node=Event.extend(event).target;
 return Element.extend(node.nodeType==Node.TEXT_NODE?node.parentNode:node);
},

 findElement:function(event,expression){
 var element=Event.element(event);
 if(!expression)return element;
 var elements=[element].concat(element.ancestors());
 return Selector.findElement(elements,expression,0);
},

 pointer:function(event){
 return{
 x:event.pageX||(event.clientX+
(document.documentElement.scrollLeft||document.body.scrollLeft)),
 y:event.pageY||(event.clientY+
(document.documentElement.scrollTop||document.body.scrollTop))
};
},

 pointerX:function(event){return Event.pointer(event).x},
 pointerY:function(event){return Event.pointer(event).y},

 stop:function(event){
 Event.extend(event);
 event.preventDefault();
 event.stopPropagation();
 event.stopped=true;
}
};
})();

Event.extend=(function(){
 var methods=Object.keys(Event.Methods).inject({},function(m,name){
 m[name]=Event.Methods[name].methodize();
 return m;
});

 if(Prototype.Browser.IE){
 Object.extend(methods,{
 stopPropagation:function(){this.cancelBubble=true},
 preventDefault:function(){this.returnValue=false},
 inspect:function(){return"[object Event]"}
});

 return function(event){
 if(!event)return false;
 if(event._extendedByPrototype)return event;

 event._extendedByPrototype=Prototype.emptyFunction;
 var pointer=Event.pointer(event);
 Object.extend(event,{
 target:event.srcElement,
 relatedTarget:Event.relatedTarget(event),
 pageX:pointer.x,
 pageY:pointer.y
});
 return Object.extend(event,methods);
};

}else{
 Event.prototype=Event.prototype||document.createEvent("HTMLEvents").__proto__;
 Object.extend(Event.prototype,methods);
 return Prototype.K;
}
})();

Object.extend(Event,(function(){
 var cache=Event.cache;

 function getEventID(element){
 if(element._prototypeEventID)return element._prototypeEventID[0];
 arguments.callee.id=arguments.callee.id||1;
 return element._prototypeEventID=[++arguments.callee.id];
}

 function getDOMEventName(eventName){
 if(eventName&&eventName.include(':'))return"dataavailable";
 if(!Prototype.Browser.IE)eventName={mouseenter:"mouseover",mouseleave:"mouseout"}[eventName]||eventName;
 return eventName;
}

 function getCacheForID(id){
 return cache[id]=cache[id]||{};
}

 function getWrappersForEventName(id,eventName){
 var c=getCacheForID(id);
 return c[eventName]=c[eventName]||[];
}

 function createWrapper(element,eventName,handler){
 var id=getEventID(element);
 var c=getWrappersForEventName(id,eventName);
 if(c.pluck("handler").include(handler))return false;

 var wrapper=function(event){
 if(!Event||!Event.extend||
(event.eventName&&event.eventName!=eventName))
 return false;

 Event.extend(event);
 handler.call(element,event);
};

 if(!(Prototype.Browser.IE)&&['mouseenter','mouseleave'].include(eventName)){
 wrapper=wrapper.wrap(function(proceed,event){
 var rel=event.relatedTarget,cur=event.currentTarget;
 if(rel&&rel.nodeType==Node.TEXT_NODE)rel=rel.parentNode;
 if(rel&&rel!=cur&&!rel.descendantOf(cur))
 return proceed(event);
});
}

 wrapper.handler=handler;
 c.push(wrapper);
 return wrapper;
}

 function findWrapper(id,eventName,handler){
 var c=getWrappersForEventName(id,eventName);
 return c.find(function(wrapper){return wrapper.handler==handler});
}

 function destroyWrapper(id,eventName,handler){
 var c=getCacheForID(id);
 if(!c[eventName])return false;
 c[eventName]=c[eventName].without(findWrapper(id,eventName,handler));
}

 function destroyCache(){
 for(var id in cache)
 for(var eventName in cache[id])
 cache[id][eventName]=null;
}

 if(window.attachEvent){
 window.attachEvent("onunload",destroyCache);
}

 return{
 observe:function(element,eventName,handler){
 element=$(element);
 var name=getDOMEventName(eventName);

 var wrapper=createWrapper(element,eventName,handler);
 if(!wrapper)return element;

 if(element.addEventListener){
 element.addEventListener(name,wrapper,false);
}else{
 element.attachEvent("on"+name,wrapper);
}

 return element;
},

 stopObserving:function(element,eventName,handler){
 element=$(element);
 var id=getEventID(element),name=getDOMEventName(eventName);

 if(!handler&&eventName){
 getWrappersForEventName(id,eventName).each(function(wrapper){
 element.stopObserving(eventName,wrapper.handler);
});
 return element;

}else if(!eventName){
 Object.keys(getCacheForID(id)).each(function(eventName){
 element.stopObserving(eventName);
});
 return element;
}

 var wrapper=findWrapper(id,eventName,handler);
 if(!wrapper)return element;

 if(element.removeEventListener){
 element.removeEventListener(name,wrapper,false);
}else{
 element.detachEvent("on"+name,wrapper);
}

 destroyWrapper(id,eventName,handler);

 return element;
},

 fire:function(element,eventName,memo){
 element=$(element);
 if(element==document&&document.createEvent&&!element.dispatchEvent)
 element=document.documentElement;

 var event;
 if(document.createEvent){
 event=document.createEvent("HTMLEvents");
 event.initEvent("dataavailable",true,true);
}else{
 event=document.createEventObject();
 event.eventType="ondataavailable";
}

 event.eventName=eventName;
 event.memo=memo||{};

 if(document.createEvent){
 element.dispatchEvent(event);
}else{
 element.fireEvent(event.eventType,event);
}

 return Event.extend(event);
}
};
})());

Object.extend(Event,Event.Methods);

Element.addMethods({
 fire:Event.fire,
 observe:Event.observe,
 stopObserving:Event.stopObserving
});

Object.extend(document,{
 fire:Element.Methods.fire.methodize(),
 observe:Element.Methods.observe.methodize(),
 stopObserving:Element.Methods.stopObserving.methodize(),
 loaded:false
});

(function(){


 var timer;

 function fireContentLoadedEvent(){
 if(document.loaded)return;
 if(timer)window.clearInterval(timer);
 document.fire("dom:loaded");
 document.loaded=true;
}

 if(document.addEventListener){
 if(Prototype.Browser.WebKit){
 timer=window.setInterval(function(){
 if(/loaded|complete/.test(document.readyState))
 fireContentLoadedEvent();
},0);

 Event.observe(window,"load",fireContentLoadedEvent);

}else{
 document.addEventListener("DOMContentLoaded",
 fireContentLoadedEvent,false);
}

}else{
 document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
 $("__onDOMContentLoaded").onreadystatechange=function(){
 if(this.readyState=="complete"){
 this.onreadystatechange=null;
 fireContentLoadedEvent();
}
};
}
})();


Hash.toQueryString=Object.toQueryString;

var Toggle={display:Element.toggle};

Element.Methods.childOf=Element.Methods.descendantOf;

var Insertion={
 Before:function(element,content){
 return Element.insert(element,{before:content});
},

 Top:function(element,content){
 return Element.insert(element,{top:content});
},

 Bottom:function(element,content){
 return Element.insert(element,{bottom:content});
},

 After:function(element,content){
 return Element.insert(element,{after:content});
}
};

var $continue=new Error('"throw $continue" is deprecated, use "return" instead');



var Position={



 includeScrollOffsets:false,



 prepare:function(){
 this.deltaX=window.pageXOffset
||document.documentElement.scrollLeft
||document.body.scrollLeft
||0;
 this.deltaY=window.pageYOffset
||document.documentElement.scrollTop
||document.body.scrollTop
||0;
},


 within:function(element,x,y){
 if(this.includeScrollOffsets)
 return this.withinIncludingScrolloffsets(element,x,y);
 this.xcomp=x;
 this.ycomp=y;
 this.offset=Element.cumulativeOffset(element);

 return(y>=this.offset[1]&&
 y<this.offset[1]+element.offsetHeight&&
 x>=this.offset[0]&&
 x<this.offset[0]+element.offsetWidth);
},

 withinIncludingScrolloffsets:function(element,x,y){
 var offsetcache=Element.cumulativeScrollOffset(element);

 this.xcomp=x+offsetcache[0]-this.deltaX;
 this.ycomp=y+offsetcache[1]-this.deltaY;
 this.offset=Element.cumulativeOffset(element);

 return(this.ycomp>=this.offset[1]&&
 this.ycomp<this.offset[1]+element.offsetHeight&&
 this.xcomp>=this.offset[0]&&
 this.xcomp<this.offset[0]+element.offsetWidth);
},


 overlap:function(mode,element){
 if(!mode)return 0;
 if(mode=='vertical')
 return((this.offset[1]+element.offsetHeight)-this.ycomp)/
 element.offsetHeight;
 if(mode=='horizontal')
 return((this.offset[0]+element.offsetWidth)-this.xcomp)/
 element.offsetWidth;
},



 cumulativeOffset:Element.Methods.cumulativeOffset,

 positionedOffset:Element.Methods.positionedOffset,

 absolutize:function(element){
 Position.prepare();
 return Element.absolutize(element);
},

 relativize:function(element){
 Position.prepare();
 return Element.relativize(element);
},

 realOffset:Element.Methods.cumulativeScrollOffset,

 offsetParent:Element.Methods.getOffsetParent,

 page:Element.Methods.viewportOffset,

 clone:function(source,target,options){
 options=options||{};
 return Element.clonePosition(target,source,options);
}
};



if(!document.getElementsByClassName)document.getElementsByClassName=function(instanceMethods){
 function iter(name){
 return name.blank()?null:"[contains(concat(' ', @class, ' '), ' "+name+" ')]";
}

 instanceMethods.getElementsByClassName=Prototype.BrowserFeatures.XPath?
 function(element,className){
 className=className.toString().strip();
 var cond=/\s/.test(className)?$w(className).map(iter).join(''):iter(className);
 return cond?document._getElementsByXPath('.//*'+cond,element):[];
}:function(element,className){
 className=className.toString().strip();
 var elements=[],classNames=(/\s/.test(className)?$w(className):null);
 if(!classNames&&!className)return elements;

 var nodes=$(element).getElementsByTagName('*');
 className=' '+className+' ';

 for(var i=0,child,cn;child=nodes[i];i++){
 if(child.className&&(cn=' '+child.className+' ')&&(cn.include(className)||
(classNames&&classNames.all(function(name){
 return!name.toString().blank()&&cn.include(' '+name+' ');
}))))
 elements.push(Element.extend(child));
}
 return elements;
};

 return function(className,parentElement){
 return $(parentElement||document.body).getElementsByClassName(className);
};
}(Element.Methods);



Element.ClassNames=Class.create();
Element.ClassNames.prototype={
 initialize:function(element){
 this.element=$(element);
},

 _each:function(iterator){
 this.element.className.split(/\s+/).select(function(name){
 return name.length>0;
})._each(iterator);
},

 set:function(className){
 this.element.className=className;
},

 add:function(classNameToAdd){
 if(this.include(classNameToAdd))return;
 this.set($A(this).concat(classNameToAdd).join(' '));
},

 remove:function(classNameToRemove){
 if(!this.include(classNameToRemove))return;
 this.set($A(this).without(classNameToRemove).join(' '));
},

 toString:function(){
 return $A(this).join(' ');
}
};

Object.extend(Element.ClassNames.prototype,Enumerable);



Element.addMethods();

(function(){



 Function.prototype.bind=function(object){
 var __method=this;
 if(arguments.length<2&&arguments[0]===undefined)return this;
 if(arguments.length==1){
 return function(){
 return __method.apply(object,arguments);
};
}
 var args=$A(arguments);
 args.shift();
 return function(){
 return __method.apply(object,args.concat($A(arguments)));
};
};


 window.zen={

 api:function(path,obj,verbatim){
 var wrappers=zen.api._wrappers=zen.api._wrappers||{};
 obj=obj||{};

 if(!wrappers[path]){
 var wrapper=obj;
 if(typeof(obj)!='function'||obj.subclasses){


 wrapper=function(){
 var parts=path.split('.');
 var api=parts.pop();
 var loc=zen.resolve(parts);
 if(!loc)return console.error('zen.api: Can\'t create "'+path+'"');
 loc[api]=obj;
};
}
 wrappers[path]=wrapper;
}else{
 return console.error('zen.api(): '+window.name+':  "'+path+'" already defined');
}
},


 require:function(){
 var stack=zen.api._stack=zen.api._stack||[];
 $A(arguments).each(function(api){
 stack.push(api);
 try{

 var f=zen.api._wrappers&&zen.api._wrappers[api];
 if(!f)throw new Error('"'+api+'" is not a defined API');
 zen.api._wrappers[api]=Prototype.emptyFunction;
 f();
}catch(e){
 zen.logException(e,'zen.require() exception. stack = '+stack.join(' > '));
}
 zen.api._wrappers[api]=Prototype.emptyFunction;
 stack.pop();
});
},


 resolve:function(path,parent){
 parent=parent||window;
 if(path.split)path=path.split('.');
 for(var i=0;i<path.length;i++){
 if(!parent)throw new Error('zen.resolve(): "'+path[i-1]+'" in '+
 path.join('.')+' is not defined');
 parent=parent[path[i]];
}
 return parent;
},


 proxy:function(remotePath,localPath){
 localPath=localPath||remotePath;
 var obj;
 try{
 obj=eval(localPath);
}catch(e){}
 if(!obj){
 obj=this.locate(remotePath);
 if(obj){
 if(obj._noproxy){
 console.error('zen.proxy: '+remotePath+' should not be proxied.');
}
 eval(localPath+' = obj;');
}else{
 console.error('zen.proxy: Unable to zen.locate "'+remotePath+'"');
}
}
},


 locate:function(path,w){
 w=w||parent;
 try{
 while(w){
 var obj;
 try{
 obj=w.eval(path);
}catch(e){}
 if(obj)return obj;
 w=(w.parent!==w)?w.parent:w.opener;
}
}catch(e){


}
 return null;
},


 deprecate:function(a,b){
 var c=arguments.callee;
 if(c[b])return;
 c[b]=true;

 if(a.indexOf('!')==0){
 console.error('Deprecation: '+a.substr(1)+(b?' --> '+b:''));
}else{
 console.warn('Deprecation: '+a+(b?' --> '+b:''));
}
},


 logException:function(e,msg){
 msg=msg?msg+' ('+e+')':e;
 console.group();
 console.error('['+zen.getWindowName()+'] '+msg);
 console.dir(e);
 console.groupEnd();
 return e;
},


 getWindowName:function(){
 return window.name||(window==top?'top':'no name');
},


 bind:function(){
 var a=$A(arguments),o=a.shift(),k;
 while(k=a.shift()){
 var asEvent=k.indexOf('#')==0;
 k=asEvent?k.substr(1):k;
 if(!o[k])throw new Error('bind: "'+k+'" is not defined');
 o[k]=asEvent?o[k].bindAsEventListener(o):o[k].bind(o);
}
},


 escapeHTML:function(o){
 o=(o===undefined||o===null)?'':
(typeof(o)!='string'?o+'':o);
 return o.escapeHTML();
},


 preload:function(){
 $A(arguments).flatten().each(function(url){new Image().src=url;});
},


 isAccessible:function(w){
 try{
 return((typeof(w.name)=='string')&&!w.closed);
}catch(e){
 console.log('window inaccessible');
}
 return false;
},


 setTitle:function(str){
 top.document.title=str;
},


 openDownload:function(url){
 if(!$('download_frame')){
 document.body.insert('<iframe name="download_frame" id="download_frame" style="display:none"></iframe>');
}
 $('download_frame').src=url;
},




 _subwins:[],

 _subwinNotify:function(){
[top,parent,opener].each(function(w){
 if(w&&w!==window&&zen.isAccessible(w)&&w.zen){
 w.zen._subwinLoad(window);
}
});
},

 _subwinLoad:function(w){

 this._subwins=this._subwins.findAll(function(o){
 return o.w==w?o.f(true)&&false:(new Date()-o.t)>6e4;
});
},


 observeSubwindowLoad:function(w,f){
 this._subwins.push({
 w:w.contentWindow||w,
 f:f,
 t:new Date()
});
}
};


 Event.observe(window,'load',function(){setTimeout(zen._subwinNotify,0);});


 zen.cookie={

 get:function(name){
 var nameEQ=name+"=";
 var ca=document.cookie.split(';');
 for(var i=0;i<ca.length;i++){
 var c=ca[i];
 while(c.charAt(0)==' ')c=c.substring(1,c.length);
 if(c.indexOf(nameEQ)==0)return c.substring(nameEQ.length,c.length);
}
 return null;
},

 set:function(name,value,keep,path){
 var expires=keep?new Date():null;
 if(expires)keep=='destroy'?expires.setYear(expires.getFullYear()-1):
 expires.setYear(expires.getFullYear()+5);

 var httpPath=path?path:'/';
 document.cookie=name+"="+value+"; path="+httpPath+
(!expires?'':"; expires="+expires.toGMTString());
},

 destroy:function(name,path){
 var value=this.get(name);
 this.set(name,value,'destroy',path);
 console.log('destroyed cookie '+name);
}
};


 Object.extend(window,{

 $unique:function(pattern){
 var c=arguments.callee;
 c._i=(c._i||0)+1;
 return pattern?pattern.replace(/#/g,c._i):c._i;
},


 $to_a:function(obj){
 return Object.isArray(obj)?obj:[obj];
},


 $px:function(o){
 return parseInt(o,10)+'px';
},


 $cid:function(elementId){
 var match=elementId.match(/(c\d*)$/);
 return match?match[0]:false;
},


 $uuid:function(len){
 var uuid=[],me=arguments.callee,c=me.chars;
 if(!c)c=me.chars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');

 if(len){

 for(var i=0;i<len;i++)uuid[i]=c[0|Math.random()*62];
}else{
 var ri=0,r;

 uuid[8]=uuid[13]=uuid[18]=uuid[23]='-';
 uuid[14]='4';

 for(var i=0;i<36;i++){
 if(uuid[i])continue;
 r=0|Math.random()*16;

 uuid[i]=c[(i==19)?(r&0x3)|0x8:r&0xf];
}
}

 return uuid.join('');
},


 $url:function(string){
 var routing_domain=zen.locate('ROUTING_DOMAIN');
 var release_path="http://assets-m-qa1.zenbe.com";
 var default_path_prefix=zen.locate('DEFAULT_PATH_PREFIX');
 if(string.include(routing_domain))return string;

 if(string.match(/^\/?(domain|shareflow|lists|push)\b/)){
 return'/'+routing_domain+string;
}

 if(string.match(/^\/(images|javascripts|html|stylesheets)\b/)){
 return release_path?release_path+string:string;
}

 return(default_path_prefix||'')+string;
},

 $lru:function(string){
 var lruRe=new RegExp(zen.locate('ROUTING_DOMAIN')+'|'+zen.locate('RELEASE_PATH')+'|'+zen.locate('DEFAULT_PATH_PREFIX'));
 return string.gsub(lruRe,'');
}

});








 var makeWrapper=function(s){
 var f=console[s];
 console[s]=function(){
 var a=arguments;
 a[0]=typeof(a[0])=='string'?'['+zen.getWindowName()+'] '+a[0]:a[0];
 f.apply(console,arguments);
};
 console[s+'Trace']=function(){
 console.group();
 var a=arguments;
 a[0]=typeof(a[0])=='string'?'['+zen.getWindowName()+'] '+a[0]:a[0];
 f.apply(console,arguments);
 console.trace();
 console.groupEnd();
};
};
['debug','error','info','log','warn'].each(function(o){
 makeWrapper(o);
});


 if(!Prototype.Browser.IE){
 if(document.activeElement===undefined){
 document.addEventListener('focus',
 function(e){document.activeElement=e.target;},true);
 document.addEventListener('blur',
 function(e){document.activeElement=null;},true);
};
};




 Event.observe(document,'click',function(e){
 var el=Event.element(e=e||event);
 while(el){
 if(el.nodeName=='A'){



 var href=(el.href+'').replace(/#$/,'');
 var loc=(window.location.href+'').replace(/#$/,'');
 if(href===''||href==loc)Event.stop(e);
}
 el=el.parentNode;
}
});



 window.SafeString=function(s,isEscaped){
 s=s||'';

 this._safe=isEscaped?s:s.escapeHTML();

 this._unsafe=!isEscaped?s:s.unescapeHTML();

 this.length=this._safe.length;
};

 Object.extend(SafeString,{

 safe:function(x){
 return(x&&x.safe&&x.safe())||x;
},


 unsafe:function(x){
 return(x&&x.unsafe&&x.unsafe())||x;
},


 _addMethods:function(names){
 names.each(function(name){
 var m=String.prototype[name];
 SafeString.prototype[name]=function(){
 return m.apply(this._safe,arguments);
};
});
}
});

 SafeString.prototype={

 isSafe:true,


 unsafe:function(){return this._unsafe;},


 safe:function(){return this;},

 toString:function(){return this._safe;},
 valueOf:function(){return this._safe;}
};


 SafeString._addMethods(['charAt','charCodeAt','concat','indexOf',
'lastIndexOf','localeCompare','match','replace','search','slice',
'split','substr','substring','toLowerCase','toUpperCase']);




 SafeString._addMethods(['blank','camelize','capitalize','dasherize',
'empty','endsWith','escapeHTML','gsub','include','inspect',
'interpolate','scan','startsWith','strip','sub','succ','times',
'toArray','toJSON','truncate','underscore','unescapeHTML']);


 Object.extend(String.prototype,{

 safe:function(){return new SafeString(this);},


 unsafe:function(){return this;}
});








 Ajax.Responders.register({

 onCreate:function(request,xmlHttp){
 var indicator=request.options.indicator;
 if(!indicator)return;
 if(typeof(indicator)=='function')return indicator(true);

 try{
 indicator=$(indicator);
 console.assert(indicator&&indicator.nodeName,'indicator must be either a function or an element.');
 if(indicator){
 var t=request.options.indicatorText;
 if(t)indicator.update(t);



(indicator.up('.wait_indicator_container')||indicator).show();
}
}catch(e){
 zen.logException(e);
}
},


 onComplete:function(request,xmlHttp){
 var indicator=request.options.indicator;
 if(!indicator)return;
 if(typeof(indicator)=='function')return indicator(false);

 try{
 indicator=$(indicator);
 if(!indicator||!indicator.nodeName){
 console.error('indicator for '+request.url+' must be either a function or an element.');
}
(indicator.up('.wait_indicator_container')||indicator).hide();
}catch(e){
 zen.logException(e);
}
},


 onException:function(request,e){
 zen.logException(e,'Exception during '+request.method+' to '
+request.url+'?'
+unescape(Object.toQueryString(request.options.parameters)));
}
});



 if(!window.fluid){
 window.fluid={
 dockBadge:0,
 addDockMenuItem:Prototype.emptyFunction,
 removeDockMenuItem:Prototype.emptyFunction,
 showGrowlNotification:Prototype.emptyFunction,
 beep:Prototype.emptyFunction,
 playSoundNamed:Prototype.emptyFunction
};
}
})();

zen.api('Rect',function(){

 window.Rect=Class.create({

 x:0,

 y:0,

 w:0,

 h:0,

 r:0,

 b:0,


 initialize:function(x,y,w,h){
 var z=arguments.length>1;
 if(z){
 this.w=Math.max(0,z?w:(x.w||x.width));
 this.h=Math.max(0,z?h:(x.h||x.height));
 this.y=z?y:(x.y||x.top);
 this.x=z?x:(x.x||x.left);
 this._rbCache();
}
},


 _whCache:function(wh){
 this.w=this.r-this.x;this.h=this.b-this.y;return this;
},


 _rbCache:function(wh){
 this.r=this.x+this.w;this.b=this.y+this.h;return this;
},


 clone:function(){
 return new Rect(this);
},


 contains:function(x,y){
 return x>=this.x&&x<this.r&&y>=this.y&&y<this.b;
},


 moveTo:function(x,y){
 this.x=x;this.y=y;return this._rbCache();
},


 translate:function(dx,dy){
 this.x+=dx;this.y+=dy;return this._rbCache();
},


 sizeTo:function(w,h){
 this.w=w;this.h=h;return this._rbCache();
},


 constrainTo:function(rect){
 this.x=Math.max(rect.x,Math.min(this.x,rect.r-this.w));
 this.y=Math.max(rect.y,Math.min(this.y,rect.b-this.h));
 return this._rbCache();
},


 inset:function(dx,dy){
 dy=arguments.length>1?dy:dx;
 this.x+=dx;this.y+=dy;
 this.w-=Math.min(this.w,2*dx);this.h-=Math.min(this.h,2*dy);
 return this._rbCache();
},


 union:function(rect){
 this.x=Math.min(this.x,rect.x);this.r=Math.max(this.r,rect.r);
 this.y=Math.min(this.y,rect.y);this.b=Math.max(this.b,rect.b);
 return this._whCache();
},


 intersect:function(rect){
 this.x=Math.max(this.x,rect.x);this.r=Math.min(this.r,rect.r);
 this.y=Math.max(this.y,rect.y);this.b=Math.min(this.b,rect.b);
 return this._whCache();
}
});
});


zen.api('Dom',function(){
 zen.require('Rect');

 window.Dom={
 _wheelListeners:[],


 getViewport:function(scope,nested){
 var d=scope?(scope.document||scope):document;
 var del=d.documentElement;
 var b=Prototype.Browser.WebKit?new Rect(
 d.body.scrollLeft,d.body.scrollTop,
 del.clientWidth,del.clientHeight
):new Rect(
 del.scrollLeft,del.scrollTop,
 del.clientWidth,del.clientHeight
);

 if(nested){
 var x=0,y=0;
 var w=window;
 while(w.parent!=w){
 w=w.parent;
 var del=w.document.documentElement;
 x+=del.offsetLeft;
 y+=del.offsetTop;

 b.translate(del.offsetLeft,del.offsetTop).intersection(Dom.getViewport(w));
}

 b.translate(-x,-y);
}
 return b;
},


 getPage:function(target){
 var w=target||window;
 var d=w.document;

 return{
 width:d.width||Math.max(d.body.offsetWidth,d.body.scrollHeight),
 height:d.height||Math.max(d.body.offsetHeight,d.body.scrollHeight)
};
},


 observeMouseWheel:function(element,listener){
 if(Dom._wheelListeners.length<=0){

 if(window.addEventListener)window.addEventListener('DOMMouseScroll',
 Dom._handleMouseWheel,false);
 window.onmousewheel=document.onmousewheel=Dom._handleMouseWheel;
}

 Dom._wheelListeners.push({element:element,listener:listener});
},


 _handleMouseWheel:function(e){
 e=e||window.event;


 var delta=e.wheelDelta?(e.wheelDelta/120*(window.opera?-1:1)):
(e.detail?-e.detail/3:0)


 var target=$(Event.element(e));
 if(delta){
 Dom._wheelListeners.each(function(o){

 if(target&&
(target==o.element||Element.descendantOf(target,o.element))){
 o.listener(delta);
 Event.stop(e);
};
});
}
}
}
});

zen.api('xElement',function(){
 zen.require('xNative','Rect','Dom');

 Object.extend(Element,{

 Factory:Class.create({

 initialize:function(template,initializer){
 this._template=template=$(template);
 this._parent=template.parentNode;
 this._initializer=initializer;

 template.remove();
 template.style.display='none';
 this._next=0;
 this._elements=[];
},


 destroy:function(){
 this._elements.invoke('remove');
 this._parent=null;
 return this;
},


 reset:function(){
 this.setVisible(false);
 this._next=0;
 return this;
},


 setVisible:function(flag){
 for(var i=this._next-1;i>=0;i--)
 this._elements[i].style.display=flag?'':'none';
 return this;
},


 next:function(){
 var el=this._elements[this._next];
 if(!el){
 this._elements[this._next]=el=this._template.cloneNode(true);
 el.id=null;
 this._parent.appendChild(el);
 this._initializer(el);
}
 this._next++;
 return el;
}
}),


 textUp:function(el,upArg){
 el=$(el.nodeType==3?el.parentNode:el);
 return upArg?el.up(upArg):el;
}
});

 Element.addMethods({

 partOf:function(el,ancestor){
 return el==ancestor||Element.descendantOf(el,ancestor);
},


 setHoverClass:function(el,hoverClass){
 el.observe("mouseover",function(e){
 el.addClassName(hoverClass);
});
 el.observe("mouseout",function(e){
 el.removeClassName(hoverClass);
});
},


 setClassMode:function(el,state,group){
 group=group||'mode';
 var re=new RegExp("\\w+_"+group+"(\\s|$)",'g');
 var mode=(state==null)?"":state+"_"+group;
 var name=el.className.replace(re,'')+' '+mode;
 name=name.replace(/\s\s/g,' ');
 el.className=name;
 return mode;
},



 firstClass:function(el,cn){
 if(Prototype.BrowserFeatures.XPath){



 return $(el.getElementsByClassName(cn)[0]);
}


 var els=el.getElementsByTagName('*');
 var re=new RegExp('(^|\\s)'+cn+'($|\\s)');
 for(var i=0;i<els.length;i++){
 var ecn=els[i].className||'';

 if(ecn.indexOf(cn)>=0&&re.test(ecn))return $(els[i]);
}

 return null;
},


 byClass:function(el,cn){
 var els=el?el.getElementsByClassName(cn):
 document.getElementsByClassName(cn);



 var nels=[],nel;
 for(var i=0;i<els.length;i++)
 if(nel=els[i])nels.push(nel);

 return nels;
},


 firstTag:function(el,tagName){
 return $(el.getElementsByTagName(tagName)[0]);
},


 firstUp:function(el,iterator){
 while(el&&!iterator(el)){el=el.parentNode;}
 return $(el);
},


 clear:function(el,iterator){
 if(!iterator){
 el.update('');
}else{
 el.childElements().each(function(el){
 if(iterator(el)){
 el.remove();
}
});
}
 return el;
},


 wink:function(el,pulses){
 if(!el._winking){
 new Effect.Pulsate(el,{
 duration:0.9,
 pulses:pulses||3,
 beforeStart:function(){el._winking=true;},
 afterFinish:function(){el._winking=false;}
});
}
},


 isOrphan:function(el){
 for(var t=el;t.parentNode;t=t.parentNode){}
 return t.nodeName!='#document';
},


 getScrollRatio:function(el){
 var sh=el.scrollHeight,oh=el.offsetHeight;
 return sh>oh?el.scrollTop/(sh-oh):0;
},


 getScrollBottom:function(el){
 var sh=el.scrollHeight,oh=el.offsetHeight;
 return sh>oh?sh-el.scrollTop-oh:0;
},


 setClassName:function(el,name,condition){
 el=$(el);
 return condition?el.addClassName(name):el.removeClassName(name);
},


 replaceClassName:function(el,newClass,oldClass){
 el=$(el);
 el.removeClassName(oldClass);
 el.addClassName(newClass);
},


 setVisible:function(el,condition){
 $(el).style.display=condition?'':'none';
 return el;
},


 moveIndex:function(el,x,y){
 el.insertAtIndex(el.removeChild(el.childNodes[x]),y);
},


 removeIndex:function(el,x){
 el.removeChild(el.childNodes[x]);
},


 insertAtIndex:function(el,insertEl,i){


 var descendants=el.immediateDescendants();

 if(i<descendants.length&&i>=0){
 if(typeof(insertEl)=='string'){
 descendants[i].insert({before:insertEl});
}else{
 el.insertBefore(insertEl,descendants[i]);
}
}else{
 if(typeof(insertEl)=='string'){
 el.insert({bottom:insertEl});
}else{
 el.appendChild(insertEl);
};
}
},



 getBounds:function(el){
 var o=el.cumulativeOffset();
 var s=el.cumulativeScrollOffset();
 var wh=el.getDimensions();

 s.top-=document.documentElement.scrollTop||document.body.scrollTop||0;
 s.left+=document.documentElement.scrollLeft||document.body.scrollLeft||0;
 return new Rect(o.left-s.left,o.top-s.top,wh.width,wh.height);
},


 commonParent:function(el,ek){
 var p0=[],p1=[],par=null;


 while(el){p0.push(el);el=el.parentNode;}
 while(ek){p1.push(ek);ek=ek.parentNode;}


 var i0=p0.length-1,i1=p1.length-1;
 while(i0>=0&&i1>=0&&p0[i0]===p1[i1]){
 par=p0[i0];
 i0--;i1--;
}

 return $(par);
},


 previousElement:function(el,onlyVisible){
 var previous=$(el.previousSibling);
 while(previous&&(previous.nodeType!=1||(!onlyVisible||!previous.visible()))){
 previous=$(previous.previousSibling);
}

 return previous;
},


 nextElement:function(el,onlyVisible){
 var next=$(el.nextSibling);
 while(next&&(next.nodeType!=1||(!onlyVisible||!next.visible()))){
 next=$(next.nextSibling);
}

 return next;
},


 depth:function(el){
 for(var i=0;(el=el.parentNode);i++);
 return i;
},


 alignCoords:function(el,anchor,pos,xFudge,yFudge){
 el=$(el);
 anchor=$(anchor);
 pos=pos||'';


 var b=anchor.getBounds();


 var elb=el.getDimensions();


 var x,y;
 if(pos.indexOf('-left')>=0){
 x=b.x;
}else if(pos.indexOf('left')>=0){
 x=b.x-elb.width;
}else if(pos.indexOf('-right')>=0){
 x=b.r-elb.width;
}else if(pos.indexOf('right')>=0){
 x=b.r;
}else{
 x=b.x+(b.w-elb.width)/2;
}

 if(pos.indexOf('-top')>=0){
 y=b.y;
}else if(pos.indexOf('top')>=0){
 y=b.y-elb.height;
}else if(pos.indexOf('-bottom')>=0){
 y=b.b-elb.height;
}else if(pos.indexOf('bottom')>=0){
 y=b.b;
}else{
 y=b.y+(b.h-elb.height)/2;
}


 var constraint=true;
 if(pos.indexOf('no-constraint')>=0)constraint=false;


 x+=xFudge||0;
 y+=yFudge||0;


 var nb=new Rect(x,y,elb.width,elb.height);
 if(constraint)nb=nb.constrainTo(Dom.getViewport());


 if(el.offsetParent){
 var ob=$(el.offsetParent).getBounds();
 nb.translate(-ob.x,-ob.y);
}


 return nb;
},


 alignTo:function(el,anchor,pos,xFudge,yFudge,container){


 if(!el.visible()){
 var rehide=true;
 el.setStyle({position:'absolute',top:'-10000px',left:'-10000px',display:'block'});
}

 var o=Element.Methods.alignCoords(el,anchor,pos,xFudge,yFudge);
 el.setStyle({
 position:'absolute',
 left:$px(o.x),
 top:$px(o.y)
});

 if(rehide)el.hide();
 return el;
},


 center:function(el,win){
 win=window||win;
 var scrollOffset=win.document.viewport.getScrollOffsets();
 el.setStyle({
 top:$px((win.document.viewport.getHeight()+scrollOffset.top)/2-el.getHeight()/2),
 left:$px((win.document.viewport.getWidth()+scrollOffset.left)/2-el.getWidth()/2)
});
 return el;
},


 autohide:function(el,options){
 options=Object.extend({
 leaveOpen:false,
 hideCallback:false
},options||{});

 el._autoignore=true;
 setTimeout(function(){el._autoignore=false;el.removeAttribute('_autoignore');},0);

 if(!el._autohider){
 el._autohider=function(e){
 if(el._autoignore||(options.leaveOpen&&Element.partOf(e.element(),el)))
 return;
 var proceed=(options.hideCallback)?options.hideCallback(el):true;
 if(!proceed)return;
 this.hide();
 Event.stopObserving(document,'click',this._autohider,true);
 Event.stopObserving(document,'keypress',this._autohider,true);
 this._autohider=null;
}.bind(el);

 Event.observe(document,'click',el._autohider,true);
 Event.observe(document,'keypress',el._autohider,true);
}
},


 hasAnyClassName:function(el,classNames){
 return el.classNames().find(function(cName){
 return(classNames.indexOf(cName)!=-1);
});
},





 idToInt:function(el){
 return el.id.match(/[0-9]+/);
},



 singleListener:function(el,attribute,callback){



 el['on'+attribute]=function(e){
 callback(Event.extend(e||event));
};
},


 fireNativeEvent:function(el,eventName){
 if(document.createEventObject){
 var evt=document.createEventObject();
 return el.fireEvent('on'+eventName,evt);
}else{
 var evt=document.createEvent("HTMLEvents");
 evt.initEvent(eventName,true,true);
 return!el.dispatchEvent(evt);
}
}
});







 Element.addMethods({

 enableLazyChange:function(el){
 if(!el._lazyChanger){
 var f=el._lazyChanger=function(e){
 this.refocus();
}.bind(el);

 el.observe('keypress',function(e){
 this._lazyChanger.setLazy(1000);
}.bind(el));
 el.observe('blur',f.clearLazy.bind(f));
}
},


 enableChangeOnEnter:function(el){
 if(Prototype.Browser.IE&&!el._enterHandler){
 el._enterHandler=function(e){
 e=e||event;
 if(e.keyCode==Event.KEY_RETURN){
 Event.element(e).refocus();
}
};

 el.observe('keypress',el._enterHandler);
}
},


 refocus:function(el){
 el.blur();
 el.focus();
 return el;
},


 getLeading:function(el){
 return el.value.substr(0,el.getRange().start);
},


 hasFocus:function(el){
 return document.activeElement==el;
},


 getRange:function(el){
 try{
 return{start:el.selectionStart,end:el.selectionEnd};
}catch(ex){}
 return{start:el.value.length,end:el.value.length};
},



 recurseChildren:function(el,func,callback,nodeTypes,tagNamesToExclude){

 var nodeTypes=nodeTypes||[Node.TEXT_NODE,Node.ELEMENT_NODE];
 var nodeStack=[el];
 var node=null;
 var func=func||function(){};
 var callback=callback||function(){};
 var nodesProcessed=0;
 var startTime=new Date().getTime();


 var pushChildren=function(node,stack){
 if(!node||!node.childNodes)return;
 $A(node.childNodes).each(function(n){
 if(nodeTypes.include(n.nodeType)&&(!n.tagName||!tagNamesToExclude.include(n.tagName))){
 stack.unshift(n);
};
});
};

 var recursiveWrapper=function(node,func,pushChildren){
 nodesProcessed++;
 pushChildren(node,nodeStack);
 func(node);
 if(nodeStack.length==0){
 callback(node,nodesProcessed);
 var executionTime=(new Date().getTime()-startTime)/1000;
 console.log('processed: '+nodesProcessed+' nodes in '+executionTime+' seconds');
}else{
 recursiveWrapper.bind(this,nodeStack.pop(),func,pushChildren).defer();
};
};

 recursiveWrapper.bind(this,nodeStack.pop(),func,pushChildren).defer();
},



 setRange:function(el,start,end){
 if(el.selectionStart!==undefined){
 return el.setSelectionRange((start.start||start||0),(start.end||end||0));
}
 else if(el.createTextRange){
 var range=el.createTextRange();
 range.collapse(true);
 range.moveEnd('character',end);
 range.moveStart('character',start);
 range.select();
}
},



 caret:function(input){
 var result={start:0,end:0};
 if(input.setSelectionRange)
{
 result.start=input.selectionStart;
 result.end=input.selectionEnd;
}
 else if(document.selection&&document.selection.createRange)
{
 var range=document.selection.createRange();
 var r2=range.duplicate();
 result.start=0-r2.moveStart('character',-100000);
 result.end=result.start+range.text.length;
}
 return result.start;
}
});
});


zen.api('xNative',function(){

 Object.extend(Object,{

 each:function(o,f){
 var pairs=[];
 for(var k in o)pairs.push({key:k,value:o[k]});
 for(var i=0;i<pairs.length;i++)f(pairs[i]);
},


 eachKey:function(o,f){
 if(o)Object.keys(o).each(f);
},


 eachValue:function(o,f){
 if(o)Object.values(o).each(f);
},


 isEmpty:function(o){
 for(var k in o)return false;
 return true;
},


 extendOptions:function(dst,src){
 dst=dst||{};
 for(var key in src){
 if(/^on[A-Z]/.test(key)&&dst[key]){

 dst[key]=dst[key].before(src[key]);
}else if(key=='parameters'){

 if(dst[key]||src[key]){
 dst[key]=Object.extend(dst[key]||{},src[key]||{});
}
}else{

 dst[key]=src[key];
}
}
 return dst;
},


 isEqualContents:function(a,b){
 var k0=Object.keys(a),k1=Object.keys(b);
 if(k0.length!=k1.length)return false;
 for(var k in a)if(!Object.isEqual(a[k],b[k]))return false;
 return true;
},


 isEqual:function(a,b){

 if(a===b)return true;


 var at=typeof(a),bt=typeof(b);
 if(at!=bt)return false;


 if(a==b)return true;


 if(!a||!b)return false;


 if(a.isEqual&&a.isEqual(b))return true;


 return at==='object'&&Object.isEqualContents(a,b);
},


 cloneDeep:function(obj,scope){
 console.assert(scope,'cloneDeep: scope must be defined');

 var rv=obj;
 if(obj){
 if(obj.constructor==scope.Object){

 rv={};
 for(var k in obj){
 rv[k]=Object.cloneDeep(obj[k],scope);
}
}else if(Object.isArray(obj)){

 rv=[];
 for(var i=0;i<obj.length;i++){
 rv[i]=Object.cloneDeep(obj[i],scope);
}
}
}

 return rv;
},

 redirect:function(from,fromMethod,to,toMethod){
 from[fromMethod]=function(){
 return to[toMethod||fromMethod].apply(to,arguments);
};
}
});



 Object.extend(Array.prototype,{

 isEqual:function(a){
 if(this.length!=a.length)return false;
 for(var i=this.length-1;i>=0;i--){
 if(!Object.isEqual(this[i],a[i]))return false;
}
 return true;
},


 thin:function(){
 var l=this.length;
 for(var i=0,j=0;i<l;i++)if(this[i])this[j++]=this[i];
 while(l>=j)delete this[l--];
 this.length=j;
 return this;
},


 trim:function(){
 for(var i=this.length;i>=0&&!this[i];i--);
 this.length=i+1;
 return this;
},


 firstEmpty:function(){
 for(var i=0;i<this.length;i++)if(!this[i])break;
 return i;
},


 move:function(x,y){
 var l=this.length;
 if(x>=0&&x<l&&y>=0&&y<l){
 if(x!=y){
 var o=this[x],di=x<y?1:-1;
 for(var i=x;i!=y;)this[i]=this[i=i+di];
 this[y]=o;
}
}else{
 throw new RangeError('Array#move('+x+', '+y+'): index out of bounds');
}
 return this;
},


 insert:function(o,x){
 this[this.length]=o;
 return this.move(this.length-1,x||0);
},


 removeIndex:function(x){
 this.move(x,this.length-1);
 return this.pop();
},


 remove:function(o){
 var l=this.length;
 for(var i=0,j=0;i<l;i++){
 if(this[i]==o)continue;
 this[j]=this[i];
 j++;
}
 while(i>j)delete this[i--];
 this.length=j;
 return this.length==l?null:o;
},


 runMutate:function(dst,callbacks){
 var src=[].concat(this);


 this.subtract(dst).each(function(o,i){
 var i=src.indexOf(o);
 try{
 callbacks.remove(i);
}catch(e){
 zen.logException(e);
}
 src.removeIndex(i);
});


 dst.subtract(src).each(function(o){
 var i=dst.indexOf(o);
 var si=Math.min(src.length,i);
 try{
 callbacks.insert(i,si);
}catch(e){
 zen.logException(e);
}
 src.insert(o,si);
});


 for(var i=0;i<dst.length;i++){
 if(dst[i]!=src[i]){
 var si=src.indexOf(dst[i]);
 try{
 callbacks.move(si,i);
}catch(e){
 zen.logException(e);
}
 src.move(si,i);
 i--;
}
}
},


 subtract:function(arr){
 var a=[];
 for(var i=0;i<this.length;i++){
 if(arr.indexOf(this[i])<0)a.push(this[i]);
}
 return a;
},



 threadedIterator:function(iterator,limit,callback){
 var length=this.length;
 if(length>=limit){
 var rq=this.clone();
 iterator.wrap(function(func){
 var i=rq.pop();
 func(i);
 if(rq.length>0){
 return true;
}else{
 if(callback&&typeof(callback)=='function')callback();
 return false;
};
}).run();
}else{
 for(var i=0;i<length;i++){
 iterator(this[i]);
};
 if(callback&&typeof(callback)=='function')callback();
}

}

});

 Object.extend(Array,{

 createComparator:function(tmpl,r){
 var src='a = '+tmpl.replace(/#\{object\}/g,'a')+
'; b = '+tmpl.replace(/#\{object\}/g,'b')+
'; return a < b ? -1 : (b < a ? 1 : 0);';
 return new Function(r?'b':'a',r?'a':'b',src);
},


 sortedIndex:function(arr,f,target){
 var low=0;
 var high=arr.length;
 while(low<high){
 var mid=(low+high)>>1;
 if(f(arr[mid],target)<0){
 low=mid+1;
}else{
 high=mid;
}
}
 return low;
},


 sortedIndexOf:function(arr,f,target){
 var i=Array.sortedIndex(arr,f,target);
 do{
 if(arr[i]===target)return i;
 i++;
}while(i<arr.length&&f(arr[i],target)==0);

 return-1;
}
});



 Object.extend(Number.prototype,{

 toPaddedString:function(length,radix){
 var s=this.toString(radix||10);
 while(s.length<length){s='0'+s;}
 return s;
}
});



 Object.extend(Date,{

 RFC_RE:/(\d{4})-(\d{1,2})-(\d{1,2})(?:T(\d{1,2}):(\d{2}):(\d{2})(?:\.\d+)?(Z|[+-](\d{2}):?(\d{2}))?)?/i,





 MONTHS:['January','February','March','April','May','June','July',
'August','September','October','November','December'],


 SHORT_MONTHS:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep',
'Oct','Nov','Dec'],


 DAYS:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday',
'Saturday'],


 SHORT_DAYS:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],


 VERY_SHORT_DAYS:['su','m','t','w','th','f','sa'],


 AMPM:['AM','PM','am','pm','a','p'],


 _FORMATS:[
[(/%A/g),'Date.DAYS[d.getDay()]'],
[(/%a/g),'Date.SHORT_DAYS[d.getDay()]'],
[(/%c/g),'Date.VERY_SHORT_DAYS[d.getDay()]'],
[(/%B/g),'Date.MONTHS[d.getMonth()]'],
[(/%b/g),'Date.SHORT_MONTHS[d.getMonth()]'],
[(/%d/g),'d.getDate().toPaddedString(2)'],
[(/%e/g),'d.getDate()'],
[(/%g/g),'d.getOffsetString()'],
[(/%H/g),'d.getHours().toPaddedString(2)'],
[(/%I/g),'((d.getHours() % 12) || 12).toPaddedString(2)'],
[(/%k/g),'d.getHours()'],
[(/%l/g),'(d.getHours() % 12) || 12'],
[(/%M/g),'d.getMinutes().toPaddedString(2)'],
[(/%m/g),'(d.getMonth()+1).toPaddedString(2)'],
[(/%n/g),'d.getMonth()+1'],
[(/%P/g),'d.getHours() < 12 ? Date.AMPM[0] : Date.AMPM[1]'],
[(/%p/g),'d.getHours() < 12 ? Date.AMPM[2] : Date.AMPM[3]'],
[(/%q/g),'d.getHours() < 12 ? Date.AMPM[4] : Date.AMPM[5]'],
[(/%S/g),'d.getSeconds().toPaddedString(2)'],
[(/%y/g),'(d.getFullYear() % 100).toPaddedString(2)'],
[(/%Y/g),'d.getFullYear()']
],


 getFormatter:function(f){
 f=f.replace(/\n/g,'\\n').replace(/"/g,'\\"');
 f='return "'+f.replace(/"/g,'\\"')+'"';
 Date._FORMATS.each(function(o){
 f=f.replace(o[0],'"\n+ ('+o[1]+') +\n"');
});
 return new Function('d',f);
},



 parseString:function(s){

 try{
 return Date.parseRfc(s);
}catch(e){


}


 if(s&&s.replace){
 s=s.replace(/(([^a-z])(a|p))(?=\s|$)/i,'$2 $3m');
}

 var ms=Date.parse(s);
 return isNaN(ms)?null:new Date(ms);
},


 parseRfc:function(rfcString){

 var v=Date.RFC_RE.exec(rfcString);
 if(!v)throw new Error('Invalid RFC Date string: "'+rfcString+'"');
 var h=v[4]||0,m=v[5]||0,s=v[6]||0;


 if(!v[7])return new Date(v[1],v[2]-1,v[3],h,m,s);


 var zh=(v[8]||0)*1,zm=(v[9]||0)*1;
 if(v[7].indexOf('-')>=0){
 zh=-zh;
 zm=-zm;
}
 h=h*1-zh;
 m=m*1-zm;

 return new Date(Date.UTC(v[1],v[2]-1,v[3],h,m,s));
}
});


 Object.extend(Date,{
 OFFHOUR_FMT:Date.getFormatter('%l:%M%q'),
 ONHOUR_FMT:Date.getFormatter('%l%q'),
 RFC_FMT:Date.getFormatter('%Y-%m-%dT%H:%M:%S%g'),
 RFC_DATE_FMT:Date.getFormatter('%Y-%m-%d'),
 SHORT_DATE_FMT:Date.getFormatter('%b %d')
});

 Object.extend(Date.prototype,{

 clone:function(){
 return new Date(this);
},


 offsetMinutes:function(n){
 this.setMinutes(this.getMinutes()+n);
 return this;
},


 offsetHours:function(n){
 this.setHours(this.getHours()+n);
 return this;
},


 offsetDays:function(n){
 this.setDate(this.getDate()+n);
 return this;
},


 offsetMonths:function(n){
 this.setMonth(this.getMonth()+n);
 return this;
},


 daysElapsed:function(date){
 var i=new Date(date).dayStart()-new Date(this).dayStart();
 return Math.round(i/86400e3);
},


 datehash:function(){
 return(this.getFullYear()<<9)|(this.getMonth()<<5)|this.getDate();
},


 dayStart:function(){
 this.setHours(0);
 this.setMinutes(0);
 this.setSeconds(0);
 this.setMilliseconds(0);
 return this;
},


 dayEnd:function(){
 this.setHours(23);
 this.setMinutes(59);
 this.setSeconds(59);
 this.setMilliseconds(999);
 return this;
},


 isMidnight:function(){
 return!this.getHours()&&!this.getMinutes()&&
!this.getSeconds()&&!this.getMilliseconds();
},


 isEqual:function(d){
 return this.getTime()==d.getTime();
},


 isEqualMonth:function(d){
 return this.getMonth()==d.getMonth()&&
 this.getFullYear()==d.getFullYear();
},


 isEqualDay:function(d){
 return this.getDate()==d.getDate()&&
 this.getMonth()==d.getMonth()&&
 this.getFullYear()==d.getFullYear();
},


 getOffsetString:function(){
 var g=this.getTimezoneOffset(),a=g<0?-g:g;
 var h=Math.floor(a/60),m=a%60;
 return g==0?"Z":((g<0?'+':'-')+
 h.toPaddedString(2)+m.toPaddedString(2));
},


 toTimeString:function(){
 return(this.getMinutes()?
 Date.OFFHOUR_FMT:Date.ONHOUR_FMT)(this);
},


 toRfcString:function(dateOnly){
 return dateOnly?Date.RFC_DATE_FMT(this):Date.RFC_FMT(this);
},


 tilNow:function(reset){
 var now=new Date().getTime();
 var elapsed=(now-this)/1000;
 if(reset)this.setTime(now);
 return elapsed;
},


 tilNowString:function(reset){
 return this.tilNow(reset)+' secs';
}
});



 Object.extend(Math,{

 rnd:function(m,n){
 if(arguments.length<2){n=m;m=0;}
 return Math.floor(m+(n-m)*Math.random());
},


 stdDev:function(list){
 var sum=0;
 var count=list.length;
 for(var i=0;i<count;i++){
 sum+=list[i];
}
 var avg=sum/count;
 var newSum=0;
 for(var i=0;i<count;i++){
 var x=list[i]-avg;
 newSum+=(x*x);
}
 return Math.sqrt(newSum/count);
},


 median:function(list){
 if(!list||list.length==0)return 0;
 list.sort();
 return list[Math.round(list.length/2)]||list[0];
},


 mean:function(list,sigDig){
 if(!list||list.length==0)return 0;
 var result=eval(list.join("+"))/list.length;
 if(sigDig){
 return Math.roundSig(result,sigDig);
}else{
 return result;
}
},


 roundSig:function(number,sigDig){
 var pot=Math.pow(10,sigDig);
 return Math.round(number*pot)/pot;
}


});



 Object.extend(String,{

 compareCaseless:function(a,b){
 a=a.toLowerCase();
 b=b.toLowerCase();
 return a<b?-1:(a>b?1:0);
}
});

 var Methods={

 compareCaseless:function(s){
 return String.compareCaseless(this,s);
},


 isEqualCaseless:function(s){
 return String.compareCaseless(this,s)==0;
},


 indexOfCaseless:function(s){
 return this.toLowerCase().indexOf(s.toLowerCase());
},


 hash:function(){
 for(var i=0,h=5381;i<this.length;i++){
 h=((h*33)^this.charCodeAt(i));
}
 return h&0x7fffffff;
},


 toIdString:function(prefix){
 var s=this.replace(/\W/g,'_').toLowerCase();
 return prefix?prefix+s:s;
},


 idToInt:function(){
 return parseInt(this.replace(/\D/g,''),10);
},


 escape:function(){
 return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
},


 escapeRegExp:function(){
 if(!arguments.callee.sRE){
 var specials=[
'/','.','*','+','?','|','$','^',
'(',')','[',']','{','}','\\'
];
 arguments.callee.sRE=new RegExp(
'(\\'+specials.join('|\\')+')','g'
);
}
 return this.replace(arguments.callee.sRE,'\\$1');
},


 autoLink:function(options){
 options=options||{safe:false};
 if(options.safe){
 var regex=/(?:[^"'])(https?:\/\/|mailto:\/\/|ftp:\/\/|www\.)[^\s]+\.(\w{2,3}(?=\W|\b))([\/|?][^\s]+)?/;
}else{
 var regex=/(https?:\/\/|mailto:\/\/|ftp:\/\/|www\.)?[^\s]+\.(\w{2,3}(?=\W|\b))([\/|?][^\s]+)?/;
}
 return this.gsub(regex,function(match){
 if((/@/).test(match[0])){
 return'<a href=mailto:"'+match[0]+'" target="_blank" class="zenbe_autolink email">'+match[0]+'</a>';
}else{
 return(!match[1]||match[1].indexOf("http://"))?'<a href="http://'+match[0]+'" target="_blank" class="zenbe_autolink web">'+match[0]+'</a>':'<a href="'+match[0]+'" target="_blank" class="zenbe_autolink web">'+match[0]+'</a>';
}
});
},


 isEmailAddress:function(a){
 return this.match(/^([\w\.\-\+]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)?true:false;
},


 toMd5:function(){
 return Md5(this);
}
};
 Object.extend(String.prototype,Methods);
 SafeString._addMethods(Object.keys(Methods));


 var invokers=[];


 Object.extend(Function.prototype,{

 apply2:(Prototype.Browser.IE?function(o,a){
 var l=a?a.length:0,invoker=invokers[l];
 if(!invoker){
 var js=['return f.call(o'];
 for(var i=0;i<l;i++)js.push(',a['+i+']');
 js.push(')');
 invoker=invokers[l]=new Function('f','o','a',js.join(''));
}
 return invoker(this,o,a);
}:Function.prototype.apply),


 run:function(aName){
 if(!this._runner){
 var runnable=this;
 this._runName=aName||'anonymous thread function';
 this._runner=function(){

 var again=!runnable._runTimer;
 try{

 again=again||runnable();
}catch(e){
 zen.logException(e,this._runName);
}finally{
 runnable._running=!!again;
}

 if(again){

 runnable._runTimer=setTimeout(runnable._runner,0);
}else{

 runnable.stopRunning();


 if(runnable.onStop)runnable.onStop();
}
};
};


 if(!this._runTimer){
 this._runner();
}
},


 stopRunning:function(){
 if(this._runTimer){
 clearTimeout(this._runTimer);
 delete this._runTimer;
}
},


 setLazy:function(ms,periodic){




 if(ms==0&&this._lz)return;

 this._lzMs=(ms=ms||0);
 this._lzPeriodic=periodic;


 if(this._lz){
 clearTimeout(this._lz);
 delete this._lz;
}


 this._lzFunction=this._lzFunction||function(){
 try{

 this();
}catch(e){
 zen.logException(e);
}finally{
 delete this._lz;


 if(this._lzPeriodic){
 this.setLazy(this._lzMs,true);
}else{

 this.clearLazy();
}
}
}.bind(this);


 this._lz=setTimeout(this._lzFunction,ms);

 return this;
},


 clearLazy:function(){
 if(this._lz){
 clearTimeout(this._lz);
}
 delete this._lz;
 delete this._lzFunction;
 delete this._lzPeriodic;
 delete this._lzMs;
 return this;
},


 isLazy:function(){
 return!!this._lz;
},


 lazy:function(ms){
 return{
 set:this.setLazy.bind(this,ms),
 clear:this.clearLazy.bind(this)
};
},


 bindShift:function(context,n){
 var f=this;
 return function(){f.apply(context,$A(arguments).splice(n||1));};
},


 after:function(before){
 var after=this;
 return before?function(){
 before.apply(this,arguments);
 after.apply(this,arguments);
}:this;
},


 before:function(after){
 var before=this;
 return after?function(){
 before.apply(this,arguments);
 after.apply(this,arguments);
}:this;
},


 pipe:function(dst){
 var src=this;
 return function(x){
 return dst(src.apply(this,arguments));
};
}

});


 Class.kreate=function(){
 var klass=Class.create.apply(this,arguments);

 klass.addMethods({
 redirect:function(fromMethod,to,toMethod){
 zen.deprecate('redirect()','TBD');
 console.assert(to,'redirect: to must be defined');
 this[fromMethod]=function(){
 if(typeof to=='string')
 to=this[to];
 return to[toMethod||fromMethod].apply(to,arguments);
};
}
});
 return klass;
};



 Hash.addMethods({

 hasKey:function(k){return k in this._object;}
});
});


zen.api('xArray',function(){zen.deprecate('!xArray','xNative');});
zen.api('xDate',function(){zen.deprecate('!xDate','xNative');});
zen.api('xNumber',function(){zen.deprecate('!xNumber','xNative');});
zen.api('xObject',function(){zen.deprecate('!xObject','xNative');});
zen.api('xMath',function(){zen.deprecate('!xMath','xNative');});
zen.api('xString',function(){zen.deprecate('!xString','xNative');});
zen.api('xFunction',function(){zen.deprecate('!xFunction','xNative');});
zen.api('xHash',function(){zen.deprecate('!xHash','xNative');});