// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
String.prototype.parseColor=function() { var color='#'; if(this.slice(0,4)=='rgb(') { var cols=this.slice(4,this.length-1).split(','); var i=0; do { color+=parseInt(cols[i]).toColorPart() } while (++i<3);} else { if(this.slice(0,1)=='#') { if(this.length==4) for(var i=1;i<4;i++) color+=(this.charAt(i)+this.charAt(i)).toLowerCase(); if(this.length==7) color=this.toLowerCase();}
}
return(color.length==7 ? color : (arguments[0] || this));}
Element.collectTextNodes=function(element) { return $A($(element).childNodes).collect( function(node) { return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));}).flatten().join('');}
Element.collectTextNodesIgnoreClass=function(element, className) { return $A($(element).childNodes).collect( function(node) { return (node.nodeType==3 ? node.nodeValue :
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodes(node) : ''));}).flatten().join('');}
Element.setStyle=function(element, style) { element=$(element); for(k in style) element.style[k.camelize()]=style[k];}
Element.setContentZoom=function(element, percent) { Element.setStyle(element, {fontSize: (percent/100)+'em'}); if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);}
Element.getOpacity=function(element){ var opacity; if (opacity=Element.getStyle(element, 'opacity'))
return parseFloat(opacity); if (opacity=(Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
if(opacity[1]) return parseFloat(opacity[1]) / 100; return 1.0;}
Element.setOpacity=function(element, value){ element=$(element); if (value==1){ Element.setStyle(element, { opacity:
(/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
0.999999 : null }); if(/MSIE/.test(navigator.userAgent))
Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});} else { if(value <0.00001) value=0; Element.setStyle(element, {opacity: value}); if(/MSIE/.test(navigator.userAgent))
Element.setStyle(element, { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')+ 'alpha(opacity='+value*100+')' });}
}
Element.getInlineOpacity=function(element){ return $(element).style.opacity || '';}
Element.childrenWithClassName=function(element, className) { return $A($(element).getElementsByTagName('*')).select( function(c) { return Element.hasClassName(c, className) });}
Array.prototype.call=function() { var args=arguments; this.each(function(f){ f.apply(this, args) });}
var Effect={ tagifyText: function(element) { var tagifyStyle='position:relative'; if(/MSIE/.test(navigator.userAgent)) tagifyStyle+=';zoom:1'; element=$(element); $A(element.childNodes).each( function(child) { if(child.nodeType==3) { child.nodeValue.toArray().each( function(character) { element.insertBefore( Builder.node('span',{style: tagifyStyle}, character==' ' ? String.fromCharCode(160) : character), child);}); Element.remove(child);}});}, multiple: function(element, effect) { var elements; if(((typeof element=='object') || (typeof element=='function')) &&
(element.length))
elements=element; else
elements=$(element).childNodes; var options=Object.extend({ speed: 0.1, delay: 0.0
}, arguments[2] || {}); var masterDelay=options.delay; $A(elements).each( function(element, index) { new effect(element, Object.extend(options, { delay: index * options.speed+masterDelay }));});}, PAIRS: { 'slide': ['SlideDown','SlideUp'], 'blind': ['BlindDown','BlindUp'], 'appear': ['Appear','Fade']
}, toggle: function(element, effect) { element=$(element); effect=(effect || 'appear').toLowerCase(); var options=Object.extend({ queue: { position:'end', scope:(element.id || 'global') }}, arguments[2] || {}); Effect[Element.visible(element) ?
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);}}; var Effect2=Effect; Effect.Transitions={}
Effect.Transitions.linear=function(pos) { return pos;}
Effect.Transitions.sinoidal=function(pos) { return (-Math.cos(pos*Math.PI)/2)+0.5;}
Effect.Transitions.reverse=function(pos) { return 1-pos;}
Effect.Transitions.flicker=function(pos) { return ((-Math.cos(pos*Math.PI)/4)+0.75)+Math.random()/4;}
Effect.Transitions.wobble=function(pos) { return (-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;}
Effect.Transitions.pulse=function(pos) { return (Math.floor(pos*10) % 2==0 ?
(pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));}
Effect.Transitions.none=function(pos) { return 0;}
Effect.Transitions.full=function(pos) { return 1;}
Effect.ScopedQueue=Class.create(); Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { initialize: function() { this.effects=[]; this.interval=null;}, _each: function(iterator) { this.effects._each(iterator);}, add: function(effect) { var timestamp=new Date().getTime(); var position=(typeof effect.options.queue=='string') ?
effect.options.queue : effect.options.queue.position; switch(position) { case 'front':
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { e.startOn+=effect.finishOn; e.finishOn+=effect.finishOn;}); break; case 'end':
timestamp=this.effects.pluck('finishOn').max() || timestamp; break;}
effect.startOn+=timestamp; effect.finishOn+=timestamp; this.effects.push(effect); if(!this.interval)
this.interval=setInterval(this.loop.bind(this), 40);}, remove: function(effect) { this.effects=this.effects.reject(function(e) { return e==effect }); if(this.effects.length==0) { clearInterval(this.interval); this.interval=null;}}, loop: function() { var timePos=new Date().getTime(); this.effects.invoke('loop', timePos);}}); Effect.Queues={ instances: $H(), get: function(queueName) { if(typeof queueName !='string') return queueName; if(!this.instances[queueName])
this.instances[queueName]=new Effect.ScopedQueue(); return this.instances[queueName];}}
Effect.Queue=Effect.Queues.get('global'); Effect.DefaultOptions={ transition: Effect.Transitions.sinoidal, duration: 1.0, fps: 25.0, sync: false, from: 0.0, to: 1.0, delay: 0.0, queue: 'parallel'
}
Effect.Base=function() {}; Effect.Base.prototype={ position: null, start: function(options) { this.options=Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); this.currentFrame=0; this.state='idle'; this.startOn=this.options.delay*1000; this.finishOn=this.startOn+(this.options.duration*1000); this.event('beforeStart'); if(!this.options.sync)
Effect.Queues.get(typeof this.options.queue=='string' ?
'global' : this.options.queue.scope).add(this);}, loop: function(timePos) { if(timePos>=this.startOn) { if(timePos>=this.finishOn) { this.render(1.0); this.cancel(); this.event('beforeFinish'); if(this.finish) this.finish(); this.event('afterFinish'); return;}
var pos=(timePos - this.startOn) / (this.finishOn - this.startOn); var frame=Math.round(pos * this.options.fps * this.options.duration); if(frame> this.currentFrame) { this.render(pos); this.currentFrame=frame;}}}, render: function(pos) { if(this.state=='idle') { this.state='running'; this.event('beforeSetup'); if(this.setup) this.setup(); this.event('afterSetup');}
if(this.state=='running') { if(this.options.transition) pos=this.options.transition(pos); pos *=(this.options.to-this.options.from); pos+=this.options.from; this.position=pos; this.event('beforeUpdate'); if(this.update) this.update(pos); this.event('afterUpdate');}}, cancel: function() { if(!this.options.sync)
Effect.Queues.get(typeof this.options.queue=='string' ?
'global' : this.options.queue.scope).remove(this); this.state='finished';}, event: function(eventName) { if(this.options[eventName+'Internal']) this.options[eventName+'Internal'](this); if(this.options[eventName]) this.options[eventName](this);}, inspect: function() { return '#<Effect:'+$H(this).inspect()+',options:'+$H(this.options).inspect()+'>';}}
Effect.Opacity=Class.create(); Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { initialize: function(element) { this.element=$(element); if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
Element.setStyle(this.element, {zoom: 1}); var options=Object.extend({ from: Element.getOpacity(this.element) || 0.0, to: 1.0
}, arguments[1] || {}); this.start(options);}, update: function(position) { Element.setOpacity(this.element, position);}}); Effect.Scale=Class.create(); Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { initialize: function(element, percent) { this.element=$(element)
var options=Object.extend({ scaleX: true, scaleY: true, scaleContent: true, scaleFromCenter: false, scaleMode: 'box', scaleFrom: 100.0, scaleTo: percent
}, arguments[2] || {}); this.start(options);}, setup: function() { this.restoreAfterFinish=this.options.restoreAfterFinish || false; this.elementPositioning=Element.getStyle(this.element,'position'); this.originalStyle={}; ['top','left','width','height','fontSize'].each( function(k) { this.originalStyle[k]=this.element.style[k];}.bind(this)); this.originalTop=this.element.offsetTop; this.originalLeft=this.element.offsetLeft; var fontSize=Element.getStyle(this.element,'font-size') || '100%'; ['em','px','%'].each( function(fontSizeType) { if(fontSize.indexOf(fontSizeType)>0) { this.fontSize=parseFloat(fontSize); this.fontSizeType=fontSizeType;}}.bind(this)); this.factor=(this.options.scaleTo - this.options.scaleFrom)/100; this.dims=null; if(this.options.scaleMode=='box')
this.dims=[this.element.offsetHeight, this.element.offsetWidth]; if(/^content/.test(this.options.scaleMode))
this.dims=[this.element.scrollHeight, this.element.scrollWidth]; if(!this.dims)
this.dims=[this.options.scaleMode.originalHeight, this.options.scaleMode.originalWidth];}, update: function(position) { var currentScale=(this.options.scaleFrom/100.0)+(this.factor * position); if(this.options.scaleContent && this.fontSize)
Element.setStyle(this.element, {fontSize: this.fontSize * currentScale+this.fontSizeType }); this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);}, finish: function(position) { if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);}, setDimensions: function(height, width) { var d={}; if(this.options.scaleX) d.width=width+'px'; if(this.options.scaleY) d.height=height+'px'; if(this.options.scaleFromCenter) { var topd=(height - this.dims[0])/2; var leftd=(width - this.dims[1])/2; if(this.elementPositioning=='absolute') { if(this.options.scaleY) d.top=this.originalTop-topd+'px'; if(this.options.scaleX) d.left=this.originalLeft-leftd+'px';} else { if(this.options.scaleY) d.top=-topd+'px'; if(this.options.scaleX) d.left=-leftd+'px';}}
Element.setStyle(this.element, d);}}); Effect.Fade=function(element) { var oldOpacity=Element.getInlineOpacity(element); var options=Object.extend({ from: Element.getOpacity(element) || 1.0, to: 0.0, afterFinishInternal: function(effect) { with(Element) { if(effect.options.to!=0) return; hide(effect.element); setStyle(effect.element, {opacity: oldOpacity});}}}, arguments[1] || {}); return new Effect.Opacity(element,options);}
Effect.Appear=function(element) { var options=Object.extend({ from: (Element.getStyle(element, 'display')=='none' ? 0.0 : Element.getOpacity(element) || 0.0), to: 1.0, beforeSetup: function(effect) { with(Element) { setOpacity(effect.element, effect.options.from); show(effect.element);}}}, arguments[1] || {}); return new Effect.Opacity(element,options);}
Effect.BlindUp=function(element) { element=$(element); Element.makeClipping(element); return new Effect.Scale(element, 0, Object.extend({ scaleContent: false, scaleX: false, restoreAfterFinish: true, afterFinishInternal: function(effect) { with(Element) { [hide, undoClipping].call(effect.element);}}
}, arguments[1] || {}) );}
Effect.BlindDown=function(element) { element=$(element); var oldHeight=Element.getStyle(element, 'height'); var elementDimensions=Element.getDimensions(element); return new Effect.Scale(element, 100, Object.extend({ scaleContent: false, scaleX: false, scaleFrom: 0, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, restoreAfterFinish: true, afterSetup: function(effect) { with(Element) { makeClipping(effect.element); setStyle(effect.element, {height: '0px'}); show(effect.element);}}, afterFinishInternal: function(effect) { with(Element) { undoClipping(effect.element); setStyle(effect.element, {height: oldHeight});}}}, arguments[1] || {}) );}