/* Prototype JavaScript framework,version 1.5.1.1 (c) 2005-2007 Sam Stephenson. MIT-style license. */

var Prototype={Version: '1.5.1.1',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},BrowserFeatures: {XPath: !!document.evaluate,ElementExtensions: !!window.HTMLElement,SpecificElementExtensions:(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}}
var Class={create:function(){return function(){this.initialize.apply(this,arguments);}}}
var Abstract=new Object();
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 === undefined) return 'undefined'; if (object === null) return 'null'; return object.inspect ? object.inspect() : object.toString();} 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.ownerDocument === document) return; var results=[]; for (var property in object) {var value=Object.toJSON(object[property]); if (value !== undefined) results.push(property.toJSON() + ': ' + value);} return '{' + results.join(',') + '}';},
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);}});

Function.prototype.bind=function(){var __method=this,args=$A(arguments),object=args.shift(); return function(){return __method.apply(object,args.concat($A(arguments)));}}
Function.prototype.bindAsEventListener=function(object) {var __method=this,args=$A(arguments),object=args.shift(); return function(event) {return __method.apply(object,[event||window.event].concat(args));}}
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';}});

Date.prototype.toJSON=function(){return '"' + this.getFullYear() + '-' + (this.getMonth() + 1).toPaddedString(2) + '-' + this.getDate().toPaddedString(2) + 'T' + this.getHours().toPaddedString(2) + ':' + this.getMinutes().toPaddedString(2) + ':' + this.getSeconds().toPaddedString(2) + '"';}; 
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;}}

var PeriodicalExecuter=Class.create(); PeriodicalExecuter.prototype={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);},
stop:function(){if (!this.timer) return; clearInterval(this.timer); this.timer=null;},
onTimerEvent:function(){if (!this.currentlyExecuting) {try {this.currentlyExecuting=true; this.callback(this);} 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=count === undefined ? 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 this;},
truncate:function(length,truncation) {length=length||30; truncation=truncation === undefined ? '...' : truncation; return this.length > length ? this.slice(0,length - truncation.length) + truncation : 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=document.createElement('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 (hash[key].constructor != Array) 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) {var result=''; for (var i=0; i < count; i++) result += this; return result;},
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.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);}});
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 (typeof replacement=='function') 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(); Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/; Template.prototype={initialize:function(template,pattern) {this.template=template.toString(); this.pattern =pattern||Template.Pattern;},
evaluate:function(object) {return this.template.gsub(this.pattern,function(match) {var before=match[1]; if (before=='\\') return match[2]; return before + String.interpret(object[match[3]]);});}}
var $break={},$continue=new Error('"throw $continue" is deprecated,use "return" instead');
var Enumerable={each:function(iterator) {var index=0; try {this._each(function(value) {iterator(value,index++);});} catch (e) {if (e != $break) throw e;} return this;},eachSlice:function(number,iterator) {var index=-number,slices=[],array=this.toArray(); while ((index += number) < array.length) slices.push(array.slice(index,index+number)); return slices.map(iterator);
},

all:function(iterator) {var result=true; this.each(function(value,index) {result=result && !!(iterator||Prototype.K)(value,index); if (!result) throw $break;}); return result;},
any:function(iterator) {var result=false; this.each(function(value,index) { if (result=!!(iterator||Prototype.K)(value,index)) throw $break;}); return result;},
collect:function(iterator) {var results=[]; this.each(function(value,index) {results.push((iterator||Prototype.K)(value,index));}); return results;},
detect:function(iterator) {var result; this.each(function(value,index) {if (iterator(value,index)) {result=value; throw $break;}}); return result;},

 findAll:function(iterator) {
 var results=[];
 this.each(function(value,index) {
 if (iterator(value,index))
 results.push(value);
});
 return results;
},

 grep:function(pattern,iterator) {
 var results=[];
 this.each(function(value,index) {
 var stringValue=value.toString();
 if (stringValue.match(pattern))
 results.push((iterator||Prototype.K)(value,index));
})
 return results;
},

 include:function(object) {
 var found=false;
 this.each(function(value) {
 if (value==object) {
 found=true;
 throw $break;
}
});
 return found;
},

 inGroupsOf:function(number,fillWith) {
 fillWith=fillWith === undefined ? null : fillWith;
 return this.eachSlice(number,function(slice) {
 while(slice.length < number) slice.push(fillWith);
 return slice;
});
},

 inject:function(memo,iterator) {
 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) {
 var result;
 this.each(function(value,index) {
 value=(iterator||Prototype.K)(value,index);
 if (result==undefined||value >= result)
 result=value;
});
 return result;
},

 min:function(iterator) {
 var result;
 this.each(function(value,index) {
 value=(iterator||Prototype.K)(value,index);
 if (result==undefined||value < result)
 result=value;
});
 return result;
},

 partition:function(iterator) {
 var trues=[],falses=[];
 this.each(function(value,index) {
 ((iterator||Prototype.K)(value,index) ?
 trues : falses).push(value);
});
 return [trues,falses];
},

 pluck:function(property) {
 var results=[];
 this.each(function(value,index) {
 results.push(value[property]);
});
 return results;
},

 reject:function(iterator) {
 var results=[];
 this.each(function(value,index) {
 if (!iterator(value,index))
 results.push(value);
});
 return results;
},

 sortBy:function(iterator) {
 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 (typeof args.last()=='function')
 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,
 member: Enumerable.include,
 entries: Enumerable.toArray
});
var $A=Array.from=function(iterable) {
 if (!iterable) return [];
 if (iterable.toArray) {
 return iterable.toArray();
} else {
 var results=[];
 for (var i=0,length=iterable.length; i < length; i++)
 results.push(iterable[i]);
 return results;
}
}

if (Prototype.Browser.WebKit) {
 $A=Array.from=function(iterable) {
 if (!iterable) return [];
 if (!(typeof iterable=='function' && iterable=='[object NodeList]') &&
 iterable.toArray) {
 return iterable.toArray();
} else {
 var results=[];
 for (var i=0,length=iterable.length; i < length; i++)
 results.push(iterable[i]);
 return results;
}
}
}

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(value && value.constructor==Array ?
 value.flatten() : [value]);
});
},

 without:function(){
 var values=$A(arguments);
 return this.select(function(value) {
 return !values.include(value);
});
},

 indexOf:function(object) {
 for (var i=0,length=this.length; i < length; i++)
 if (this[i]==object) return i;
 return -1;
},

 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;
});
},

 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 (value !== undefined) results.push(value);
});
 return '[' + results.join(',') + ']';
}
});

Array.prototype.toArray=Array.prototype.clone;

function $w(string) {
 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 (arguments[i].constructor==Array) {
 for (var j=0,arrayLength=arguments[i].length; j < arrayLength; j++)
 array.push(arguments[i][j]);
} else {
 array.push(arguments[i]);
}
}
 return array;
}
}
var Hash=function(object) {
 if (object instanceof Hash) this.merge(object);
 else Object.extend(this,object||{});
};

Object.extend(Hash,{
 toQueryString:function(obj) {
 var parts=[];
 parts.add=arguments.callee.addPair;

 this.prototype._each.call(obj,function(pair) {
 if (!pair.key) return;
 var value=pair.value;

 if (value && typeof value=='object') {
 if (value.constructor==Array) value.each(function(value) {
 parts.add(pair.key,value);
});
 return;
}
 parts.add(pair.key,value);
});

 return parts.join('&');
},

 toJSON:function(object) {
 var results=[];
 this.prototype._each.call(object,function(pair) {
 var value=Object.toJSON(pair.value);
 if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
});
 return '{' + results.join(',') + '}';
}
});

Hash.toQueryString.addPair=function(key,value,prefix) {
 key=encodeURIComponent(key);
 if (value === undefined) this.push(key);
 else this.push(key + '=' + (value==null ? '' : encodeURIComponent(value)));
}

Object.extend(Hash.prototype,Enumerable);
Object.extend(Hash.prototype,{
 _each:function(iterator) {
 for (var key in this) {
 var value=this[key];
 if (value && value==Hash.prototype[key]) continue;

 var pair=[key,value];
 pair.key=key;
 pair.value=value;
 iterator(pair);
}
},

 keys:function(){
 return this.pluck('key');
},

 values:function(){
 return this.pluck('value');
},

 merge:function(hash) {
 return $H(hash).inject(this,function(mergedHash,pair) {
 mergedHash[pair.key]=pair.value;
 return mergedHash;
});
},

 remove:function(){
 var result;
 for(var i=0,length=arguments.length; i < length; i++) {
 var value=this[arguments[i]];
 if (value !== undefined){
 if (result === undefined) result=value;
 else {
 if (result.constructor != Array) result=[result];
 result.push(value)
}
}
 delete this[arguments[i]];
}
 return result;
},

 toQueryString:function(){
 return Hash.toQueryString(this);
},

 inspect:function(){
 return '#<Hash:{' + this.map(function(pair) {
 return pair.map(Object.inspect).join(': ');
}).join(',') + '}>';
},

 toJSON:function(){
 return Hash.toJSON(this);
}
});

function $H(object) {
 if (object instanceof Hash) return object;
 return new Hash(object);
};

if (function(){
 var i=0,Test=function(value) {this.key=value};
 Test.prototype.key='foo';
 for (var property in new Test('bar')) i++;
 return i > 1;
}()) Hash.prototype._each=function(iterator) {
 var cache=[];
 for (var key in this) {
 var value=this[key];
 if ((value && value==Hash.prototype[key])||cache.include(key)) continue;
 cache.push(key);
 var pair=[key,value];
 pair.key=key;
 pair.value=value;
 iterator(pair);
}
};
ObjectRange=Class.create();
Object.extend(ObjectRange.prototype,Enumerable);
Object.extend(ObjectRange.prototype,{
 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 (typeof responder[callback]=='function') {
 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=function(){};
Ajax.Base.prototype={
 setOptions:function(options) {
 this.options={
 method: 'post',
 asynchronous: true,
 contentType: 'application/x-www-form-urlencoded',
 encoding: 'UTF-8',
 parameters: ''
}
 Object.extend(this.options,options||{});

 this.options.method=this.options.method.toLowerCase();
 if (typeof this.options.parameters=='string')
 this.options.parameters=this.options.parameters.toQueryParams();
}
}

Ajax.Request=Class.create();
Ajax.Request.Events =
 ['Uninitialized','Loading','Loaded','Interactive','Complete'];

Ajax.Request.prototype=Object.extend(new Ajax.Base(),{
 _complete: false,

 initialize:function(url,options) {
 this.transport=Ajax.getTransport();
 this.setOptions(options);
 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=Hash.toQueryString(params)) {
 if (this.method=='get')
 this.url += (this.url.include('?') ? '&' : '?') + params;
 else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
 params += '&_=';
}

 try {
 if (this.options.onCreate) this.options.onCreate(this.transport);
 Ajax.Responders.dispatch('onCreate',this,this.transport);

 this.transport.open(this.method.toUpperCase(),this.url,
 this.options.asynchronous);

 if (this.options.asynchronous)
 setTimeout(function(){this.respondToReadyState(1)}.bind(this),10);

 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 (typeof extras.push=='function')
 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(){
 return !this.transport.status
||(this.transport.status >= 200 && this.transport.status < 300);
},

 respondToReadyState:function(readyState) {
 var state=Ajax.Request.Events[readyState];
 var transport=this.transport,json=this.evalJSON();

 if (state=='Complete') {
 try {
 this._complete=true;
 (this.options['on' + this.transport.status]
||this.options['on' + (this.success() ? 'Success' : 'Failure')]
||Prototype.emptyFunction)(transport,json);
} catch (e) {
 this.dispatchException(e);
}

 var contentType=this.getHeader('Content-type');
 if (contentType && contentType.strip().
 match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
 this.evalResponse();
}

 try {
 (this.options['on' + state]||Prototype.emptyFunction)(transport,json);
 Ajax.Responders.dispatch('on' + state,this,transport,json);
} catch (e) {
 this.dispatchException(e);
}

 if (state=='Complete') {
 this.transport.onreadystatechange=Prototype.emptyFunction;
}
},

 getHeader:function(name) {
 try {
 return this.transport.getResponseHeader(name);
} catch (e) {return null}
},

 evalJSON:function(){
 try {
 var json=this.getHeader('X-JSON');
 return json ? json.evalJSON() : 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.Updater=Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype,Ajax.Request.prototype),{
 initialize:function(container,url,options) {
 this.container={
 success: (container.success||container),
 failure: (container.failure||(container.success ? null : container))
}

 this.transport=Ajax.getTransport();
 this.setOptions(options);

 var onComplete=this.options.onComplete||Prototype.emptyFunction;
 this.options.onComplete=(function(transport,param) {
 this.updateContent();
 onComplete(transport,param);
}).bind(this);

 this.request(url);
},

 updateContent:function(){
 var receiver=this.container[this.success() ? 'success' : 'failure'];
 var response=this.transport.responseText;

 if (!this.options.evalScripts) response=response.stripScripts();

 if (receiver=$(receiver)) {
 if (this.options.insertion)
 new this.options.insertion(receiver,response);
 else
 receiver.update(response);
}

 if (this.success()) {
 if (this.onComplete)
 setTimeout(this.onComplete.bind(this),10);
}
}
});

Ajax.PeriodicalUpdater=Class.create();
Ajax.PeriodicalUpdater.prototype=Object.extend(new Ajax.Base(),{
 initialize:function(container,url,options) {
 this.setOptions(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(request) {
 if (this.options.decay) {
 this.decay=(request.responseText==this.lastText ?
 this.decay * this.options.decay : 1);

 this.lastText=request.responseText;
}
 this.timer=setTimeout(this.onTimerEvent.bind(this),
 this.decay * this.frequency * 1000);
},

 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 (typeof element=='string')
 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(query.snapshotItem(i));
 return results;
};

 document.getElementsByClassName=function(className,parentElement) {
 var q=".//*[contains(concat(' ',@class,' '),' " + className + " ')]";
 return document._getElementsByXPath(q,parentElement);
}

} else document.getElementsByClassName=function(className,parentElement) {
 var children=($(parentElement)||document.body).getElementsByTagName('*');
 var elements=[],child,pattern=new RegExp("(^|\\s)" + className + "(\\s|$)");
 for (var i=0,length=children.length; i < length; i++) {
 child=children[i];
 var elementClassName=child.className;
 if (elementClassName.length==0) continue;
 if (elementClassName==className||elementClassName.match(pattern))
 elements.push(Element.extend(child));
}
 return elements;
};

if (!window.Element) var Element={};

Element.extend=function(element) {
 var F=Prototype.BrowserFeatures;
 if (!element||!element.tagName||element.nodeType==3 ||
 element._extended||F.SpecificElementExtensions||element==window)
 return element;

 var methods={},tagName=element.tagName,cache=Element.extend.cache,
 T=Element.Methods.ByTag;

 if (!F.ElementExtensions) {
 Object.extend(methods,Element.Methods),
 Object.extend(methods,Element.Methods.Simulated);
}

 if (T[tagName]) Object.extend(methods,T[tagName]);

 for (var property in methods) {
 var value=methods[property];
 if (typeof value=='function' && !(property in element))
 element[property]=cache.findOrStore(value);
}

 element._extended=Prototype.emptyFunction;
 return element;
};

Element.extend.cache={
 findOrStore:function(value) {
 return this[value]=this[value]||function(){
 return value.apply(null,[this].concat($A(arguments)));
}
}
};

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,html) {
 html=typeof html=='undefined' ? '' : html.toString();
 $(element).innerHTML=html.stripScripts();
 setTimeout(function(){html.evalScripts()},10);
 return element;
},

 replace:function(element,html) {
 element=$(element);
 html=typeof html=='undefined' ? '' : html.toString();
 if (element.outerHTML) {
 element.outerHTML=html.stripScripts();
} else {
 var range=element.ownerDocument.createRange();
 range.selectNodeContents(element);
 element.parentNode.replaceChild(
 range.createContextualFragment(html.stripScripts()),element);
}
 setTimeout(function(){html.evalScripts()},10);
 return element;
},

 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 $A($(element).getElementsByTagName('*')).each(Element.extend);
},

 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 (typeof selector=='string')
 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 expression ? Selector.findElement(ancestors,expression,index) :
 ancestors[index||0];
},

 down:function(element,expression,index) {
 element=$(element);
 if (arguments.length==1) return element.firstDescendant();
 var descendants=element.descendants();
 return expression ? Selector.findElement(descendants,expression,index) :
 descendants[index||0];
},

 previous:function(element,expression,index) {
 element=$(element);
 if (arguments.length==1) return $(Selector.handlers.previousElementSibling(element));
 var previousSiblings=element.previousSiblings();
 return expression ? Selector.findElement(previousSiblings,expression,index) :
 previousSiblings[index||0];
},

 next:function(element,expression,index) {
 element=$(element);
 if (arguments.length==1) return $(Selector.handlers.nextElementSibling(element));
 var nextSiblings=element.nextSiblings();
 return expression ? Selector.findElement(nextSiblings,expression,index) :
 nextSiblings[index||0];
},

 getElementsBySelector:function(){
 var args=$A(arguments),element=$(args.shift());
 return Selector.findChildElements(element,args);
},

 getElementsByClassName:function(element,className) {
 return document.getElementsByClassName(className,element);
},

 readAttribute:function(element,name) {
 element=$(element);
 if (Prototype.Browser.IE) {
 if (!element.attributes) return null;
 var t=Element._attributeTranslations;
 if (t.values[name]) return t.values[name](element,name);
 if (t.names[name]) name=t.names[name];
 var attribute=element.attributes[name];
 return attribute ? attribute.nodeValue : null;
}
 return element.getAttribute(name);
},

 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;
 if (elementClassName.length==0) return false;
 if (elementClassName==className ||
 elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
 return true;
 return false;
},

 addClassName:function(element,className) {
 if (!(element=$(element))) return;
 Element.classNames(element).add(className);
 return element;
},

 removeClassName:function(element,className) {
 if (!(element=$(element))) return;
 Element.classNames(element).remove(className);
 return element;
},

 toggleClassName:function(element,className) {
 if (!(element=$(element))) return;
 Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
 return element;
},

 observe:function(){
 Event.observe.apply(Event,arguments);
 return $A(arguments).first();
},

 stopObserving:function(){
 Event.stopObserving.apply(Event,arguments);
 return $A(arguments).first();
},

 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);
 while (element=element.parentNode)
 if (element==ancestor) return true;
 return false;
},

 scrollTo:function(element) {
 element=$(element);
 var pos=Position.cumulativeOffset(element);
 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,camelized) {
 element=$(element);
 var elementStyle=element.style;

 for (var property in styles)
 if (property=='opacity') element.setOpacity(styles[property])
 else
 elementStyle[(property=='float'||property=='cssFloat') ?
 (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
 (camelized ? property : property.camelize())]=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.style.overflow||'auto';
 if ((Element.getStyle(element,'overflow')||'visible') != '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;
}
};

Object.extend(Element.Methods,{
 childOf: Element.Methods.descendantOf,
 childElements: Element.Methods.immediateDescendants
});

if (Prototype.Browser.Opera) {
 Element.Methods._getStyle=Element.Methods.getStyle;
 Element.Methods.getStyle=function(element,style) {
 switch(style) {
 case 'left':
 case 'top':
 case 'right':
 case 'bottom':
 if (Element._getStyle(element,'position')=='static') return null;
 default: return Element._getStyle(element,style);
}
};
}
else if (Prototype.Browser.IE) {
 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) {
 element=$(element);
 var filter=element.getStyle('filter'),style=element.style;
 if (value==1||value === '') {
 style.filter=filter.replace(/alpha\([^\)]*\)/gi,'');
 return element;
} else if (value < 0.00001) value=0;
 style.filter=filter.replace(/alpha\([^\)]*\)/gi,'') +
 'alpha(opacity=' + (value * 100) + ')';
 return element;
};

 Element.Methods.update=function(element,html) {
 element=$(element);
 html=typeof html=='undefined' ? '' : html.toString();
 var tagName=element.tagName.toUpperCase();
 if (['THEAD','TBODY','TR','TD'].include(tagName)) {
 var div=document.createElement('div');
 switch (tagName) {
 case 'THEAD':
 case 'TBODY':
 div.innerHTML='<table><tbody>' + html.stripScripts() + '</tbody></table>';
 depth=2;
 break;
 case 'TR':
 div.innerHTML='<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
 depth=3;
 break;
 case 'TD':
 div.innerHTML='<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
 depth=4;
}
 $A(element.childNodes).each(function(node) {element.removeChild(node)});
 depth.times(function(){div=div.firstChild});
 $A(div.childNodes).each(function(node) {element.appendChild(node)});
} else {
 element.innerHTML=html.stripScripts();
}
 setTimeout(function(){html.evalScripts()},10);
 return element;
}
}
else if (Prototype.Browser.Gecko) {
 Element.Methods.setOpacity=function(element,value) {
 element=$(element);
 element.style.opacity=(value==1) ? 0.999999 :
 (value === '') ? '' : (value < 0.00001) ? 0 : value;
 return element;
};
}

Element._attributeTranslations={
 names: {
 colspan: "colSpan",
 rowspan: "rowSpan",
 valign: "vAlign",
 datetime: "dateTime",
 accesskey: "accessKey",
 tabindex: "tabIndex",
 enctype: "encType",
 maxlength: "maxLength",
 readonly: "readOnly",
 longdesc: "longDesc"
},
 values: {
 _getAttr:function(element,attribute) {
 return element.getAttribute(attribute,2);
},
 _flag:function(element,attribute) {
 return $(element).hasAttribute(attribute) ? attribute : null;
},
 style:function(element) {
 return element.style.cssText.toLowerCase();
},
 title:function(element) {
 var node=element.getAttributeNode('title');
 return node.specified ? node.nodeValue : null;
}
}
};

(function(){
 Object.extend(this,{
 href: this._getAttr,
 src: this._getAttr,
 type: this._getAttr,
 disabled: this._flag,
 checked: this._flag,
 readonly: this._flag,
 multiple: this._flag
});
}).call(Element._attributeTranslations.values);

Element.Methods.Simulated={
 hasAttribute:function(element,attribute) {
 var t=Element._attributeTranslations,node;
 attribute=t.names[attribute]||attribute;
 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.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 (tagName.constructor==Array) 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;
 var cache=Element.extend.cache;
 for (var property in methods) {
 var value=methods[property];
 if (!onlyIfAbsent||!(property in destination))
 destination[property]=cache.findOrStore(value);
}
}

 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 (typeof klass=="undefined") continue;
 copy(T[tag],klass.prototype);
}
}

 Object.extend(Element,Element.Methods);
 delete Element.ByTag;
};

var Toggle={display: Element.toggle};

Abstract.Insertion=function(adjacency) {
 this.adjacency=adjacency;
}

Abstract.Insertion.prototype={
 initialize:function(element,content) {
 this.element=$(element);
 this.content=content.stripScripts();

 if (this.adjacency && this.element.insertAdjacentHTML) {
 try {
 this.element.insertAdjacentHTML(this.adjacency,this.content);
} catch (e) {
 var tagName=this.element.tagName.toUpperCase();
 if (['TBODY','TR'].include(tagName)) {
 this.insertContent(this.contentFromAnonymousTable());
} else {
 throw e;
}
}
} else {
 this.range=this.element.ownerDocument.createRange();
 if (this.initializeRange) this.initializeRange();
 this.insertContent([this.range.createContextualFragment(this.content)]);
}

 setTimeout(function(){content.evalScripts()},10);
},

 contentFromAnonymousTable:function(){
 var div=document.createElement('div');
 div.innerHTML='<table><tbody>' + this.content + '</tbody></table>';
 return $A(div.childNodes[0].childNodes[0].childNodes);
}
}

var Insertion=new Object();

Insertion.Before=Class.create();
Insertion.Before.prototype=Object.extend(new Abstract.Insertion('beforeBegin'),{
 initializeRange:function(){
 this.range.setStartBefore(this.element);
},

 insertContent:function(fragments) {
 fragments.each((function(fragment) {
 this.element.parentNode.insertBefore(fragment,this.element);
}).bind(this));
}
});

Insertion.Top=Class.create();
Insertion.Top.prototype=Object.extend(new Abstract.Insertion('afterBegin'),{
 initializeRange:function(){
 this.range.selectNodeContents(this.element);
 this.range.collapse(true);
},

 insertContent:function(fragments) {
 fragments.reverse(false).each((function(fragment) {
 this.element.insertBefore(fragment,this.element.firstChild);
}).bind(this));
}
});

Insertion.Bottom=Class.create();
Insertion.Bottom.prototype=Object.extend(new Abstract.Insertion('beforeEnd'),{
 initializeRange:function(){
 this.range.selectNodeContents(this.element);
 this.range.collapse(this.element);
},

 insertContent:function(fragments) {
 fragments.each((function(fragment) {
 this.element.appendChild(fragment);
}).bind(this));
}
});

Insertion.After=Class.create();
Insertion.After.prototype=Object.extend(new Abstract.Insertion('afterEnd'),{
 initializeRange:function(){
 this.range.setStartAfter(this.element);
},

 insertContent:function(fragments) {
 fragments.each((function(fragment) {
 this.element.parentNode.insertBefore(fragment,
 this.element.nextSibling);
}).bind(this));
}
});

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);
var Selector=Class.create();

Selector.prototype={
 initialize:function(expression) {
 this.expression=expression.strip();
 this.compileMatcher();
},

 compileMatcher:function(){
 if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
 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(typeof c[i]=='function' ? 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(typeof x[i]=='function' ? 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) {
 return this.findElements(document).include(element);
},

 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: "[@#{1}]",attr:function(m) {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 (typeof h === 'function') 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,m,v; var exclusion=[]; while (e && le != e && (/\S/).test(e)) {le=e; for (var i in p) {if (m=e.match(p[i])) {v=typeof x[i]=='function' ? 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=false;',attr:function(m) {m[3]=(m[5]||m[6]); return new Template('n=h.attr(n,r,"#{1}","#{3}","#{2}"); 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|([^'"][^\]]*?)))?\]/},handlers: {concat:function(a,b) {for (var i=0,node; node=b[i]; i++) a.push(node); return a;},mark:function(nodes) {for (var i=0,node; node=nodes[i]; i++) node._counted=true; return nodes;},unmark:function(nodes) {for (var i=0,node; node=nodes[i]; i++) node._counted=undefined; return nodes;},index:function(parentNode,reverse,ofType) {parentNode._counted=true; if (reverse) {for (var nodes=parentNode.childNodes,i=nodes.length - 1,j=1; i >= 0; i--) {node=nodes[i]; if (node.nodeType==1 && (!ofType||node._counted)) node.nodeIndex=j++;}} else {for (var i=0,j=1,nodes=parentNode.childNodes; node=nodes[i]; i++) if (node.nodeType==1 && (!ofType||node._counted)) 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])._counted) {n._counted=true; 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,children=[],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) {tagName=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()==tagName) results.push(node); return results;} else return root.getElementsByTagName(tagName);},id:function(nodes,root,id,combinator) {var targetNode=$(id),h=Selector.handlers; if (!nodes && root==document) return targetNode ? [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) {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) {if (!nodes) nodes=root.getElementsByTagName("*"); 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._counted) {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._counted) 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() + '-');}},matchElements:function(elements,expression) {var matches=new Selector(expression).findElements(),h=Selector.handlers; h.mark(matches); for (var i=0,results=[],element; element=elements[i]; i++) if (element._counted) results.push(element); h.unmark(matches); return results;},findElement:function(elements,expression,index) {if (typeof expression=='number') {index=expression; expression=false;} return Selector.matchElements(elements,expression||'*')[index||0];},findChildElements:function(element,expressions) {var exprs=expressions.join(','),expressions=[]; exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m) {expressions.push(m[1].strip());}); 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;}}); function $$(){return Selector.findChildElements(document,$A(arguments));} var Form={reset:function(form) {$(form).reset(); return form;},serializeElements:function(elements,getHash) {var data=elements.inject({},function(result,element) {if (!element.disabled && element.name) {var key=element.name,value=$(element).getValue(); if (value != null) {	if (key in result) {if (result[key].constructor != Array) result[key]=[result[key]]; result[key].push(value);} else result[key]=value;}} return result;}); return getHash ? data : Hash.toQueryString(data);}};

Form.Methods={serialize:function(form,getHash) {return Form.serializeElements(Form.getElements(form),getHash);},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) {return $(form).getElements().find(function(element) {return element.type != 'hidden' && !element.disabled && ['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;
 options.parameters=form.serialize(true);

 if (params) {
 if (typeof params=='string') params=params.toQueryParams();
 Object.extend(options.parameters,params);
}

 if (form.hasAttribute('method') && !options.method)
 options.method=form.method;

 return new Ajax.Request(form.readAttribute('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 Hash.toQueryString(pair);
}
}
 return '';
},

 getValue:function(element) {
 element=$(element);
 var method=element.tagName.toLowerCase();
 return Form.Element.Serializers[method](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) {
 switch (element.type.toLowerCase()) {
 case 'checkbox':
 case 'radio':
 return Form.Element.Serializers.inputSelector(element);
 default:
 return Form.Element.Serializers.textarea(element);
}
},

 inputSelector:function(element) {
 return element.checked ? element.value : null;
},

 textarea:function(element) {
 return element.value;
},

 select:function(element) {
 return this[element.type=='select-one' ?
 'selectOne' : 'selectMany'](element);
},

 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=function(){}
Abstract.TimedObserver.prototype={
 initialize:function(element,frequency,callback) {
 this.frequency=frequency;
 this.element =$(element);
 this.callback =callback;

 this.lastValue=this.getValue();
 this.registerCallback();
},

 registerCallback:function(){
 setInterval(this.onTimerEvent.bind(this),this.frequency * 1000);
},

 onTimerEvent:function(){
 var value=this.getValue();
 var changed=('string'==typeof this.lastValue && 'string'==typeof value
 ? this.lastValue != value : String(this.lastValue) != String(value));
 if (changed) {
 this.callback(this.element,value);
 this.lastValue=value;
}
}
}

Form.Element.Observer=Class.create();
Form.Element.Observer.prototype=Object.extend(new Abstract.TimedObserver(),{
 getValue:function(){
 return Form.Element.getValue(this.element);
}
});

Form.Observer=Class.create();
Form.Observer.prototype=Object.extend(new Abstract.TimedObserver(),{
 getValue:function(){
 return Form.serialize(this.element);
}
});

Abstract.EventObserver=function(){}
Abstract.EventObserver.prototype={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.bind(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(); Form.Element.EventObserver.prototype=Object.extend(new Abstract.EventObserver(),{getValue:function(){return Form.Element.getValue(this.element);}});
Form.EventObserver=Class.create(); Form.EventObserver.prototype=Object.extend(new Abstract.EventObserver(),{getValue:function(){return Form.serialize(this.element);}}); if (!window.Event) {var Event=new Object();} 
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,
element:function(event) {return $(event.target||event.srcElement);},
isLeftClick:function(event) {return (((event.which) && (event.which==1))||((event.button) && (event.button==1)));},
pointerX:function(event) {return event.pageX||(event.clientX + (document.documentElement.scrollLeft||document.body.scrollLeft));},
pointerY:function(event) {return event.pageY||(event.clientY + (document.documentElement.scrollTop||document.body.scrollTop));},
stop:function(event) {if (event.preventDefault) {event.preventDefault(); event.stopPropagation();} else {event.returnValue=false; event.cancelBubble=true;}},
findElement:function(event,tagName) {var element=Event.element(event); while (element.parentNode && (!element.tagName||(element.tagName.toUpperCase() != tagName.toUpperCase()))) element=element.parentNode; return element;},

observers: false,
_observeAndCache:function(element,name,observer,useCapture) {if (!this.observers) this.observers=[]; if (element.addEventListener) {this.observers.push([element,name,observer,useCapture]); element.addEventListener(name,observer,useCapture);} else if (element.attachEvent) {this.observers.push([element,name,observer,useCapture]); element.attachEvent('on' + name,observer);}},
unloadCache:function(){if (!Event.observers) return; for (var i=0,length=Event.observers.length; i < length; i++) {Event.stopObserving.apply(this,Event.observers[i]); Event.observers[i][0]=null;} Event.observers=false;},
observe:function(element,name,observer,useCapture) {element=$(element); useCapture=useCapture||false; if (name=='keypress' && (Prototype.Browser.WebKit||element.attachEvent)) name='keydown'; Event._observeAndCache(element,name,observer,useCapture);},
stopObserving:function(element,name,observer,useCapture) {element=$(element); useCapture=useCapture||false; if (name=='keypress' && (Prototype.Browser.WebKit||element.attachEvent)) name='keydown'; if (element.removeEventListener) {element.removeEventListener(name,observer,useCapture);} else if (element.detachEvent) {try {element.detachEvent('on' + name,observer);} catch (e) {}}}}); if (Prototype.Browser.IE) Event.observe(window,'unload',Event.unloadCache,false); 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;},
realOffset:function(element) {var valueT=0,valueL=0; do {valueT += element.scrollTop||0; valueL += element.scrollLeft||0; element=element.parentNode;} while (element); return [valueL,valueT];},
cumulativeOffset:function(element) {var valueT=0,valueL=0; do {valueT += element.offsetTop||0; valueL += element.offsetLeft||0; element=element.offsetParent;} while (element); return [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=='relative'||p=='absolute') break;}} while (element); return [valueL,valueT];},
offsetParent: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;},
within:function(element,x,y) {if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(element,x,y); this.xcomp=x; this.ycomp=y; this.offset=this.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=this.realOffset(element); this.xcomp=x + offsetcache[0] - this.deltaX; this.ycomp=y + offsetcache[1] - this.deltaY; this.offset=this.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;},
page:function(forElement) {var valueT=0,valueL=0; var element=forElement; do {valueT += element.offsetTop||0; valueL += element.offsetLeft||0; if (element.offsetParent==document.body) if (Element.getStyle(element,'position')=='absolute') break;} while (element=element.offsetParent); element=forElement; do {if (!window.opera||element.tagName=='BODY') {valueT -= element.scrollTop||0; valueL -= element.scrollLeft||0;}} while (element=element.parentNode); return [valueL,valueT];},
clone:function(source,target) {
 var options=Object.extend({setLeft: true,setTop: true,setWidth: true,setHeight: true,offsetTop: 0,offsetLeft: 0},arguments[2]||{})
 source=$(source); var p=Position.page(source);
 target=$(target); var delta=[0,0]; var parent=null;
 if (Element.getStyle(target,'position')=='absolute') {parent=Position.offsetParent(target); delta=Position.page(parent);}
 if (parent==document.body) {delta[0] -= document.body.offsetLeft; delta[1] -= document.body.offsetTop;} 
 if(options.setLeft) target.style.left =(p[0] - delta[0] + options.offsetLeft) + 'px'; if(options.setTop) target.style.top =(p[1] - delta[1] + options.offsetTop) + 'px'; if(options.setWidth) target.style.width=source.offsetWidth + 'px'; if(options.setHeight) target.style.height=source.offsetHeight + 'px';
},

absolutize:function(element) {element=$(element); if (element.style.position=='absolute') return; Position.prepare(); var offsets=Position.positionedOffset(element); 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';},
relativize:function(element) {element=$(element); if (element.style.position=='relative') return; Position.prepare(); 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;}}

if (Prototype.Browser.WebKit) {Position.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 [valueL,valueT];}}
Element.addMethods();