var Prototype={
  Version: '1.4.1',
  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',

  emptyFunction: function() {},
  K: function(x) {return x},
  _mouse: [0,0]
}

var Class={ create: function() { return function() { this.initialize.apply(this,arguments); } } }
var Abstract=new Object();

Object.extend=function(destination,source) { for (property in source) { destination[property]=source[property]; } return destination; }
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; } }

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; return function(event) { return __method.call(object, event || window.event); } }

Object.extend(Number.prototype, {
	toColorPart: function() { var digits=this.toString(16); if (this<16) return '0'+digits; return digits; },
	succ: function() { return this+1; },
	times: function(iterator) { $R(0, this, true).each(iterator); return this; }
});

var Try={ these: function() { var returnValue; for (var i=0;i<arguments.length;i++) { var lambda=arguments[i]; try { returnValue=lambda(); break; } catch (e) {} } return returnValue; } }

/*--------------------------------------------------------------------------*/

function $() { var elements=new Array(); for (var i=0; i < arguments.length; i++) { var element=arguments[i]; if (typeof element == 'string') element=document.getElementById(element); if (arguments.length==1) return element; elements.push(element); } return elements; }

function $XA(element_xa,attr_xa) { return element_xa.getAttribute(attr_xa); }
function $XC(parentNode) { var contentStr=""; if (parentNode.xml!=undefined) { for (var i=0;i<parentNode.childNodes.length;i++) { var n=parentNode.childNodes[i]; if (n.nodeType==4) contentStr+=n.nodeValue; else contentStr+=n.xml; } } else { var xmlSerializer=new XMLSerializer(); for (var i=0;i<parentNode.childNodes.length;i++) { var n=parentNode.childNodes[i]; if (n.nodeType==4) contentStr+=n.nodeValue; else contentStr+=xmlSerializer.serializeToString(n); } } return contentStr; }
function $XML(xml_element,value_name) { var out_elm={}; if (value_name!='') eval('out_elm.'+value_name+'=$XC(xml_element);'); if (arguments.length>2) { for (var i=2;i<arguments.length;i++) { eval('out_elm.'+arguments[i]+'=$XA(xml_element,"'+arguments[i]+'");'); } } return out_elm; }

/*--------------------------------------------------------------------------*/

Object.extend(String.prototype, {
	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(eval); },
	escapeHTML: function() { var div=document.createElement('div'); var text=document.createTextNode(this); div.appendChild(text); return div.innerHTML; },
	unescapeHTML: function() { var div=document.createElement('div'); div.innerHTML=this.stripTags(); return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; },
	toQueryParams: function() { var pairs=this.match(/^\??(.*)$/)[1].split('&'); return pairs.inject({}, function(params, pairString) { var pair=pairString.split('='); params[pair[0]]=pair[1]; return params; }); },
	toArray: function() { return this.split(''); },
	camelize: function() { var oStringList=this.split('-'); if (oStringList.length == 1) return oStringList[0]; var camelizedString=this.indexOf('-') == 0 ? oStringList[0].charAt(0).toUpperCase()+oStringList[0].substring(1) : oStringList[0]; for (var i=1, len=oStringList.length; i < len; i++) { var s=oStringList[i]; camelizedString += s.charAt(0).toUpperCase()+s.substring(1); } return camelizedString; },
	inspect: function() { return "'"+this.replace('\\', '\\\\').replace("'", '\\\'')+"'"; }
});

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

var $break=new Object();
var $continue=new Object();

var Enumerable={
	each: function(iterator) { var index=0; try { this._each(function(value) { try { iterator(value, index++); } catch (e) { if (e != $continue) throw e; } }); } catch (e) { if (e!=$break) throw e; } },
	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=true; 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(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; },
	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.collect(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 (value>=(result || value)) result=value; }); return result; },
	min: function(iterator) { var result; this.each(function(value, index) { value=(iterator || Prototype.K)(value, index); if (value <= (result || value)) 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.collect(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.collect(Prototype.K); },
	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) { iterator(value=collections.pluck(index)); return value; }); },
	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; i < iterable.length; i++) results.push(iterable[i]); return results; } }

Object.extend(Array.prototype,Enumerable);
Array.prototype._reverse=Array.prototype.reverse;
Object.extend(Array.prototype, {
	_each: function(iterator) { for (var i=0;i<this.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 != undefined || value != null; }); },
	flatten: function() { return this.inject([], function(array, value) { return array.concat(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; i < this.length; i++) if (this[i] == object) return i; return -1; },
	reverse: function(inline) { return (inline !== false ? this : this.toArray())._reverse(); },
	shift: function() { var result=this[0]; for (var i=0; i < this.length-1; i++) this[i]=this[i+1]; this.length--; return result; },
	inspect: function() { return '['+this.map(Object.inspect).join(', ')+']'; }
});

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; do { iterator(value); value=value.succ(); } while (this.include(value)); },
	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 ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')}, function() {return new XMLHttpRequest()} ) || false; },
	activeRequestCount: 0
}

Ajax.Responders={
	responders: [],
	_each: function(iterator) { this.responders._each(iterator); },
	register: function(responderToAdd) { if (!this.include(responderToAdd)) this.responders.push(responderToAdd); },
	unregister: function(responderToRemove) { this.responders=this.responders.without(responderToRemove); },
	dispatch: function(callback, request, transport, json) { this.each(function(responder) { if (responder[callback] && 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, parameters:   '' }; Object.extend(this.options, options || {}); },
	responseIsSuccess: function() { return this.transport.status == undefined || this.transport.status == 0 || (this.transport.status >= 200 && this.transport.status < 300); },
	responseIsFailure: function() { return !this.responseIsSuccess(); }
}

Ajax.Request=Class.create();
Ajax.Request.Events=['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype=Object.extend(new Ajax.Base(), {
	initialize: function(url, options) { this.transport=Ajax.getTransport(); this.setOptions(options); this.request(url); },
	request: function(url) { var parameters=this.options.parameters || ''; if (parameters.length>0) parameters+='&_='; try { this.url=url; if (this.options.method=='get' && parameters.length>0) this.url+=(this.url.match(/\?/) ? '&' : '?')+parameters; Ajax.Responders.dispatch('onCreate', this, this.transport); this.transport.open(this.options.method, this.url,this.options.asynchronous); if (this.options.asynchronous) { this.transport.onreadystatechange=this.onStateChange.bind(this); setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); } this.setRequestHeaders(); var body=this.options.postBody ? this.options.postBody : parameters; this.transport.send(this.options.method == 'post' ? body : null); } catch (e) { this.dispatchException(e); } },
	setRequestHeaders: function() { var requestHeaders=['X-Requested-With', 'XMLHttpRequest','X-Prototype-Version', Prototype.Version]; if (this.options.method == 'post') { requestHeaders.push('Content-type','application/x-www-form-urlencoded'); if (this.transport.overrideMimeType) requestHeaders.push('Connection', 'close'); } if (this.options.requestHeaders) requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); for (var i=0; i < requestHeaders.length; i += 2) this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); },
	onStateChange: function() { var readyState=this.transport.readyState; if (readyState != 1) this.respondToReadyState(this.transport.readyState); },
	header: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) {} },
	evalJSON: function() { try { return eval(this.header('X-JSON')); } catch (e) {} },
	evalResponse: function() { try { return eval(this.transport.responseText); } catch (e) { this.dispatchException(e); } },
	respondToReadyState: function(readyState) { var event=Ajax.Request.Events[readyState]; var transport=this.transport, json=this.evalJSON(); if (event == 'Complete') { try { (this.options['on'+this.transport.status] || this.options['on'+(this.responseIsSuccess() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(transport, json); } catch (e) { this.dispatchException(e); } if ((this.header('Content-type') || '').match(/^text\/javascript/i)) this.evalResponse(); } try { (this.options['on'+event] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on'+event, this, transport, json); } catch (e) { this.dispatchException(e); } if (event == 'Complete') this.transport.onreadystatechange=Prototype.emptyFunction; },
	dispatchException: function(exception) { (this.options.onException || Prototype.emptyFunction)(this, exception); Ajax.Responders.dispatch('onException', this, exception); }
});

/*--------------------------------------------------------------------------*/

if (!window.Element) var Element=new Object();
Object.extend(Element, {
	visible: function(element) { return $(element).style.display!='none'; },
	toggle: function() { for (var i=0;i<arguments.length;i++) { var element=$(arguments[i]); Element[Element.visible(element) ? 'hide' : 'show'](element); } },
	hide: function() { for (var i=0;i<arguments.length;i++) { var element=$(arguments[i]); element.style.display='none'; } },
	show: function() { for (var i=0;i<arguments.length;i++) { var element=$(arguments[i]); element.style.display=''; } },
	remove: function(element) { element=$(element); element.parentNode.removeChild(element); },
	update: function(element,html) { $(element).innerHTML=html.stripScripts(); setTimeout(function() {html.evalScripts()},10); },
	getHeight: function(element) { element=$(element); return element.offsetHeight; },
	classNames: function(element) { return new Element.ClassNames(element); },
	hasClassName: function(element,className) { if (!(element=$(element))) return; return Element.classNames(element).include(className); },
	addClassName: function(element,className) { if (!(element=$(element))) return; return Element.classNames(element).add(className); },
	removeClassName: function(element,className) { if (!(element=$(element))) return; return Element.classNames(element).remove(className); },
	cleanWhitespace: function(element) { element=$(element); for (var i=0;i<element.childNodes.length;i++) { var node=element.childNodes[i]; if (node.nodeType==3 && !/\S/.test(node.nodeValue)) Element.remove(node); } },
	empty: function(element) { return $(element).innerHTML.match(/^\s*$/); },
	scrollTo: function(element) { element=$(element); var x=element.x ? element.x : element.offsetLeft, y=element.y ? element.y : element.offsetTop; window.scrollTo(x,y); },
	getStyle: function(element,style) { element=$(element); var value=element.style[style.camelize()]; if (!value) { if (document.defaultView && document.defaultView.getComputedStyle) { var css=document.defaultView.getComputedStyle(element,null); value=css ? css.getPropertyValue(style) : null; } else if (element.currentStyle) { value=element.currentStyle[style.camelize()]; } } if (window.opera && ['left','top','right','bottom'].include(style)) if (Element.getStyle(element,'position')=='static') value='auto'; return value=='auto' ? null : value; },
	setStyle: function(element,style) { element=$(element); for (name in style) element.style[name.camelize()]=style[name]; },
	getDimensions: function(element) { element=$(element); if (Element.getStyle(element,'display')!='none') return {width: element.offsetWidth, height: element.offsetHeight}; var els=element.style; var originalVisibility=els.visibility; var originalPosition=els.position; els.visibility='hidden'; els.position='absolute'; els.display=''; var originalWidth=element.clientWidth; var originalHeight=element.clientHeight; els.display='none'; 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; } } },
	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=''; } },
	makeClipping: function(element) { element=$(element); if (element._overflow) return; element._overflow=element.style.overflow; if ((Element.getStyle(element,'overflow') || 'visible')!='hidden') element.style.overflow='hidden'; },
	undoClipping: function(element) { element=$(element); if (element._overflow) return; element.style.overflow=element._overflow; element._overflow=undefined; }
});

var Toggle=new Object();
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) { if (this.element.tagName.toLowerCase()=='tbody') { 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.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)); }
});

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)); }
});

/*--------------------------------------------------------------------------*/

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(this.toArray().concat(classNameToAdd).join(' ')); },
	remove: function(classNameToRemove) { if (!this.include(classNameToRemove)) return; this.set(this.select(function(className) { return className != classNameToRemove; }).join(' ')); },
	toString: function() { return this.toArray().join(' '); }
}
Object.extend(Element.ClassNames.prototype,Enumerable);

/*--------------------------------------------------------------------------*/

if (!window.Event) var Event=new Object();

Object.extend(Event, {
	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;i<Event.observers.length;i++) { Event.stopObserving.apply(this,Event.observers[i]); Event.observers[i][0]=null; } Event.observers=false; },
	observe: function(element,name,observer,useCapture) { var element=$(element); useCapture=useCapture || false; this._observeAndCache(element,name,observer,useCapture); },
	stopObserving: function(element,name,observer,useCapture) { var element=$(element); useCapture=useCapture || false; if (element.removeEventListener) { element.removeEventListener(name,observer,useCapture); } else if (element.detachEvent) { element.detachEvent('on'+name,observer); } }
});

/*--------------------------------------------------------------------------*/

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) { 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; },
	clone: function(source,target) { source=$(source); target=$(target); target.style.position='absolute'; var offsets=this.cumulativeOffset(source); target.style.top=offsets[1]+'px'; target.style.left=offsets[0]+'px'; target.style.width=source.offsetWidth+'px'; target.style.height=source.offsetHeight+'px'; },
	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 { 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 (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) 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]; }
