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.collectTextNodesIgnoreClass(node,className):''));}).flatten().join('');}
Element.setContentZoom=function(element,percent){
element=$(element);
element.setStyle({fontSize:(percent/100)+'em'});
if(navigator.appVersion.indexOf('AppleWebKit')>0)window.scrollBy(0,0);
return element;}
Element.getOpacity=function(element){
return $(element).getStyle('opacity');}
Element.setOpacity=function(element,value){
return $(element).setStyle({opacity:value});}
Element.getInlineOpacity=function(element){
return $(element).style.opacity||'';}
Element.forceRerendering=function(element){
try{
element=$(element);
var n=document.createTextNode(' ');
element.appendChild(n);
element.removeChild(n);}catch(e){}};
Array.prototype.call=function(){
var args=arguments;
this.each(function(f){f.apply(this,args)});}
var Effect={
_elementDoesNotExistError:{
name:'ElementDoesNotExistError',
message:'The specified DOM element does not exist, but is required for this effect to operate'},
tagifyText:function(element){
if(typeof Builder=='undefined')
throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
var tagifyStyle='position:relative';
if(/MSIE/.test(navigator.userAgent)&&!window.opera)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'),limit:1}},arguments[2]||{});
Effect[element.visible()?
Effect.PAIRS[effect][1]:Effect.PAIRS[effect][0]](element,options);}};
var Effect2=Effect;
Effect.Transitions={
linear:Prototype.K,
sinoidal:function(pos){
return(-Math.cos(pos*Math.PI)/2)+0.5;},
reverse:function(pos){
return 1-pos;},
flicker:function(pos){
return((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;},
wobble:function(pos){
return(-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;},
pulse:function(pos,pulses){
pulses=pulses||5;
return(
Math.round((pos%(1/pulses))*pulses)==0?((pos*pulses*2)-Math.floor(pos*pulses*2)):
1-((pos*pulses*2)-Math.floor(pos*pulses*2)));},
none:function(pos){
return 0;},
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 'with-last':
timestamp=this.effects.pluck('startOn').max()||timestamp;
break;
case 'end':
timestamp=this.effects.pluck('finishOn').max()||timestamp;
break;}
effect.startOn+=timestamp;
effect.finishOn+=timestamp;
if(!effect.options.queue.limit||(this.effects.length<effect.options.queue.limit))
this.effects.push(effect);
if(!this.interval)
this.interval=setInterval(this.loop.bind(this),15);},
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();
for(var i=0,len=this.effects.length;i<len;i++)
if(this.effects[i])this.effects[i].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:60.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(){
var data=$H();
for(property in this)
if(typeof this[property]!='function')data[property]=this[property];
return '#<Effect:'+data.inspect()+',options:'+$H(this.options).inspect()+'>';}}
Effect.Parallel=Class.create();
Object.extend(Object.extend(Effect.Parallel.prototype,Effect.Base.prototype),{
initialize:function(effects){
this.effects=effects||[];
this.start(arguments[1]);},
update:function(position){
this.effects.invoke('render',position);},
finish:function(position){
this.effects.each(function(effect){
effect.render(1.0);
effect.cancel();
effect.event('beforeFinish');
if(effect.finish)effect.finish(position);
effect.event('afterFinish');});}});
Effect.Event=Class.create();
Object.extend(Object.extend(Effect.Event.prototype,Effect.Base.prototype),{
initialize:function(){
var options=Object.extend({
duration:0},arguments[0]||{});
this.start(options);},
update:Prototype.emptyFunction});
Effect.Opacity=Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype,Effect.Base.prototype),{
initialize:function(element){
this.element=$(element);
if(!this.element)throw(Effect._elementDoesNotExistError);
if(/MSIE/.test(navigator.userAgent)&&!window.opera&&(!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom:1});
var options=Object.extend({
from:this.element.getOpacity()||0.0,
to:1.0},arguments[1]||{});
this.start(options);},
update:function(position){
this.element.setOpacity(position);}});
Effect.Move=Class.create();
Object.extend(Object.extend(Effect.Move.prototype,Effect.Base.prototype),{
initialize:function(element){
this.element=$(element);
if(!this.element)throw(Effect._elementDoesNotExistError);
var options=Object.extend({
x:0,
y:0,
mode:'relative'},arguments[1]||{});
this.start(options);},
setup:function(){
this.element.makePositioned();
this.originalLeft=parseFloat(this.element.getStyle('left')||'0');
this.originalTop=parseFloat(this.element.getStyle('top')||'0');
if(this.options.mode=='absolute'){
this.options.x=this.options.x-this.originalLeft;
this.options.y=this.options.y-this.originalTop;}},
update:function(position){
this.element.setStyle({
left:Math.round(this.options.x*position+this.originalLeft)+'px',
top:Math.round(this.options.y*position+this.originalTop)+'px'});}});
Effect.MoveBy=function(element,toTop,toLeft){
return new Effect.Move(element,
Object.extend({x:toLeft,y:toTop},arguments[3]||{}));};
Effect.Scale=Class.create();
Object.extend(Object.extend(Effect.Scale.prototype,Effect.Base.prototype),{
initialize:function(element,percent){
this.element=$(element);
if(!this.element)throw(Effect._elementDoesNotExistError);
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=this.element.getStyle('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=this.element.getStyle('font-size')||'100%';['em','px','%','pt'].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)
this.element.setStyle({fontSize:this.fontSize*currentScale+this.fontSizeType});
this.setDimensions(this.dims[0]*currentScale,this.dims[1]*currentScale);},
finish:function(position){
if(this.restoreAfterFinish)this.element.setStyle(this.originalStyle);},
setDimensions:function(height,width){
var d={};
if(this.options.scaleX)d.width=Math.round(width)+'px';
if(this.options.scaleY)d.height=Math.round(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';}}
this.element.setStyle(d);}});
Effect.Highlight=Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype,Effect.Base.prototype),{
initialize:function(element){
this.element=$(element);
if(!this.element)throw(Effect._elementDoesNotExistError);
var options=Object.extend({startcolor:'#ffff99'},arguments[1]||{});
this.start(options);},
setup:function(){
if(this.element.getStyle('display')=='none'){this.cancel();return;}
this.oldStyle={};
if(!this.options.keepBackgroundImage){
this.oldStyle.backgroundImage=this.element.getStyle('background-image');
this.element.setStyle({backgroundImage:'none'});}
if(!this.options.endcolor)
this.options.endcolor=this.element.getStyle('background-color').parseColor('#ffffff');
if(!this.options.restorecolor)
this.options.restorecolor=this.element.getStyle('background-color');
this._base=$R(0,2).map(function(i){return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16)}.bind(this));
this._delta=$R(0,2).map(function(i){return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i]}.bind(this));},
update:function(position){
this.element.setStyle({backgroundColor:$R(0,2).inject('#',function(m,v,i){
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart());}.bind(this))});},
finish:function(){
this.element.setStyle(Object.extend(this.oldStyle,{
backgroundColor:this.options.restorecolor}));}});
Effect.ScrollTo=Class.create();
Object.extend(Object.extend(Effect.ScrollTo.prototype,Effect.Base.prototype),{
initialize:function(element){
this.element=$(element);
this.start(arguments[1]||{});},
setup:function(){
Position.prepare();
var offsets=Position.cumulativeOffset(this.element);
if(this.options.offset)offsets[1]+=this.options.offset;
var max=window.innerHeight?
window.height-window.innerHeight:
document.body.scrollHeight-(document.documentElement.clientHeight?
document.documentElement.clientHeight:document.body.clientHeight);
this.scrollStart=Position.deltaY;
this.delta=(offsets[1]>max?max:offsets[1])-this.scrollStart;},
update:function(position){
Position.prepare();
window.scrollTo(Position.deltaX,
this.scrollStart+(position*this.delta));}});
Effect.Fade=function(element){
element=$(element);
var oldOpacity=element.getInlineOpacity();
var options=Object.extend({
from:element.getOpacity()||1.0,
to:0.0,
afterFinishInternal:function(effect){
if(effect.options.to!=0)return;
effect.element.hide().setStyle({opacity:oldOpacity});}},arguments[1]||{});
return new Effect.Opacity(element,options);}
Effect.Appear=function(element){
element=$(element);
var options=Object.extend({
from:(element.getStyle('display')=='none'?0.0:element.getOpacity()||0.0),
to:1.0,
afterFinishInternal:function(effect){
effect.element.forceRerendering();},
beforeSetup:function(effect){
effect.element.setOpacity(effect.options.from).show();}},arguments[1]||{});
return new Effect.Opacity(element,options);}
Effect.Puff=function(element){
element=$(element);
var oldStyle={
opacity:element.getInlineOpacity(),
position:element.getStyle('position'),
top:element.style.top,
left:element.style.left,
width:element.style.width,
height:element.style.height};
return new Effect.Parallel([new Effect.Scale(element,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),
new Effect.Opacity(element,{sync:true,to:0.0})],
Object.extend({duration:1.0,
beforeSetupInternal:function(effect){
Position.absolutize(effect.effects[0].element)},
afterFinishInternal:function(effect){
effect.effects[0].element.hide().setStyle(oldStyle);}},arguments[1]||{}));}
Effect.BlindUp=function(element){
element=$(element);
element.makeClipping();
return new Effect.Scale(element,0,
Object.extend({scaleContent:false,
scaleX:false,
restoreAfterFinish:true,
afterFinishInternal:function(effect){
effect.element.hide().undoClipping();}},arguments[1]||{}));}
Effect.BlindDown=function(element){
element=$(element);
var elementDimensions=element.getDimensions();
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){
effect.element.makeClipping().setStyle({height:'0px'}).show();},
afterFinishInternal:function(effect){
effect.element.undoClipping();}},arguments[1]||{}));}
Effect.SwitchOff=function(element){
element=$(element);
var oldOpacity=element.getInlineOpacity();
return new Effect.Appear(element,Object.extend({
duration:0.4,
from:0,
transition:Effect.Transitions.flicker,
afterFinishInternal:function(effect){
new Effect.Scale(effect.element,1,{
duration:0.3,scaleFromCenter:true,
scaleX:false,scaleContent:false,restoreAfterFinish:true,
beforeSetup:function(effect){
effect.element.makePositioned().makeClipping();},
afterFinishInternal:function(effect){
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity:oldOpacity});}})}},arguments[1]||{}));}
Effect.DropOut=function(element){
element=$(element);
var oldStyle={
top:element.getStyle('top'),
left:element.getStyle('left'),
opacity:element.getInlineOpacity()};
return new Effect.Parallel([new Effect.Move(element,{x:0,y:100,sync:true}),
new Effect.Opacity(element,{sync:true,to:0.0})],
Object.extend({duration:0.5,
beforeSetup:function(effect){
effect.effects[0].element.makePositioned();},
afterFinishInternal:function(effect){
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);}},arguments[1]||{}));}
Effect.Shake=function(element){
element=$(element);
var oldStyle={
top:element.getStyle('top'),
left:element.getStyle('left')};
return new Effect.Move(element,{x:20,y:0,duration:0.05,afterFinishInternal:function(effect){
new Effect.Move(effect.element,{x:-40,y:0,duration:0.1,afterFinishInternal:function(effect){
new Effect.Move(effect.element,{x:40,y:0,duration:0.1,afterFinishInternal:function(effect){
new Effect.Move(effect.element,{x:-40,y:0,duration:0.1,afterFinishInternal:function(effect){
new Effect.Move(effect.element,{x:40,y:0,duration:0.1,afterFinishInternal:function(effect){
new Effect.Move(effect.element,{x:-20,y:0,duration:0.05,afterFinishInternal:function(effect){
effect.element.undoPositioned().setStyle(oldStyle);}})}})}})}})}})}});}
Effect.SlideDown=function(element){
element=$(element).cleanWhitespace();
var oldInnerBottom=element.down().getStyle('bottom');
var elementDimensions=element.getDimensions();
return new Effect.Scale(element,100,Object.extend({
scaleContent:false,
scaleX:false,
scaleFrom:window.opera?0:1,
scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},
restoreAfterFinish:true,
afterSetup:function(effect){
effect.element.makePositioned();
effect.element.down().makePositioned();
if(window.opera)effect.element.setStyle({top:''});
effect.element.makeClipping().setStyle({height:'0px'}).show();},
afterUpdateInternal:function(effect){
effect.element.down().setStyle({bottom:(effect.dims[0]-effect.element.clientHeight)+'px'});},
afterFinishInternal:function(effect){
effect.element.undoClipping().undoPositioned();
effect.element.down().undoPositioned().setStyle({bottom:oldInnerBottom});}},arguments[1]||{}));}
Effect.SlideUp=function(element){
element=$(element).cleanWhitespace();
var oldInnerBottom=element.down().getStyle('bottom');
return new Effect.Scale(element,window.opera?0:1,
Object.extend({scaleContent:false,
scaleX:false,
scaleMode:'box',
scaleFrom:100,
restoreAfterFinish:true,
beforeStartInternal:function(effect){
effect.element.makePositioned();
effect.element.down().makePositioned();
if(window.opera)effect.element.setStyle({top:''});
effect.element.makeClipping().show();},
afterUpdateInternal:function(effect){
effect.element.down().setStyle({bottom:(effect.dims[0]-effect.element.clientHeight)+'px'});},
afterFinishInternal:function(effect){
effect.element.hide().undoClipping().undoPositioned().setStyle({bottom:oldInnerBottom});
effect.element.down().undoPositioned();}},arguments[1]||{}));}
Effect.Squish=function(element){
return new Effect.Scale(element,window.opera?1:0,{
restoreAfterFinish:true,
beforeSetup:function(effect){
effect.element.makeClipping();},
afterFinishInternal:function(effect){
effect.element.hide().undoClipping();}});}
Effect.Grow=function(element){
element=$(element);
var options=Object.extend({
direction:'center',
moveTransition:Effect.Transitions.sinoidal,
scaleTransition:Effect.Transitions.sinoidal,
opacityTransition:Effect.Transitions.full},arguments[1]||{});
var oldStyle={
top:element.style.top,
left:element.style.left,
height:element.style.height,
width:element.style.width,
opacity:element.getInlineOpacity()};
var dims=element.getDimensions();
var initialMoveX,initialMoveY;
var moveX,moveY;
switch(options.direction){
case 'top-left':
initialMoveX=initialMoveY=moveX=moveY=0;
break;
case 'top-right':
initialMoveX=dims.width;
initialMoveY=moveY=0;
moveX=-dims.width;
break;
case 'bottom-left':
initialMoveX=moveX=0;
initialMoveY=dims.height;
moveY=-dims.height;
break;
case 'bottom-right':
initialMoveX=dims.width;
initialMoveY=dims.height;
moveX=-dims.width;
moveY=-dims.height;
break;
case 'center':
initialMoveX=dims.width/2;
initialMoveY=dims.height/2;
moveX=-dims.width/2;
moveY=-dims.height/2;
break;}
return new Effect.Move(element,{
x:initialMoveX,
y:initialMoveY,
duration:0.01,
beforeSetup:function(effect){
effect.element.hide().makeClipping().makePositioned();},
afterFinishInternal:function(effect){
new Effect.Parallel([new Effect.Opacity(effect.element,{sync:true,to:1.0,from:0.0,transition:options.opacityTransition}),
new Effect.Move(effect.element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition}),
new Effect.Scale(effect.element,100,{
scaleMode:{originalHeight:dims.height,originalWidth:dims.width},
sync:true,scaleFrom:window.opera?1:0,transition:options.scaleTransition,restoreAfterFinish:true})],Object.extend({
beforeSetup:function(effect){
effect.effects[0].element.setStyle({height:'0px'}).show();},
afterFinishInternal:function(effect){
effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);}},options))}});}
Effect.Shrink=function(element){
element=$(element);
var options=Object.extend({
direction:'center',
moveTransition:Effect.Transitions.sinoidal,
scaleTransition:Effect.Transitions.sinoidal,
opacityTransition:Effect.Transitions.none},arguments[1]||{});
var oldStyle={
top:element.style.top,
left:element.style.left,
height:element.style.height,
width:element.style.width,
opacity:element.getInlineOpacity()};
var dims=element.getDimensions();
var moveX,moveY;
switch(options.direction){
case 'top-left':
moveX=moveY=0;
break;
case 'top-right':
moveX=dims.width;
moveY=0;
break;
case 'bottom-left':
moveX=0;
moveY=dims.height;
break;
case 'bottom-right':
moveX=dims.width;
moveY=dims.height;
break;
case 'center':
moveX=dims.width/2;
moveY=dims.height/2;
break;}
return new Effect.Parallel([new Effect.Opacity(element,{sync:true,to:0.0,from:1.0,transition:options.opacityTransition}),
new Effect.Scale(element,window.opera?1:0,{sync:true,transition:options.scaleTransition,restoreAfterFinish:true}),
new Effect.Move(element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition})],Object.extend({
beforeStartInternal:function(effect){
effect.effects[0].element.makePositioned().makeClipping();},
afterFinishInternal:function(effect){
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle);}},options));}
Effect.Pulsate=function(element){
element=$(element);
var options=arguments[1]||{};
var oldOpacity=element.getInlineOpacity();
var transition=options.transition||Effect.Transitions.sinoidal;
var reverser=function(pos){return transition(1-Effect.Transitions.pulse(pos,options.pulses))};
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({duration:2.0,from:0,
afterFinishInternal:function(effect){effect.element.setStyle({opacity:oldOpacity});}},options),{transition:reverser}));}
Effect.Fold=function(element){
element=$(element);
var oldStyle={
top:element.style.top,
left:element.style.left,
width:element.style.width,
height:element.style.height};
element.makeClipping();
return new Effect.Scale(element,5,Object.extend({
scaleContent:false,
scaleX:false,
afterFinishInternal:function(effect){
new Effect.Scale(element,1,{
scaleContent:false,
scaleY:false,
afterFinishInternal:function(effect){
effect.element.hide().undoClipping().setStyle(oldStyle);}});}},arguments[1]||{}));};
Effect.Morph=Class.create();
Object.extend(Object.extend(Effect.Morph.prototype,Effect.Base.prototype),{
initialize:function(element){
this.element=$(element);
if(!this.element)throw(Effect._elementDoesNotExistError);
var options=Object.extend({
style:{}},arguments[1]||{});
if(typeof options.style=='string'){
if(options.style.indexOf(':')==-1){
var cssText='',selector='.'+options.style;
$A(document.styleSheets).reverse().each(function(styleSheet){
if(styleSheet.cssRules)cssRules=styleSheet.cssRules;
else if(styleSheet.rules)cssRules=styleSheet.rules;
$A(cssRules).reverse().each(function(rule){
if(selector==rule.selectorText){
cssText=rule.style.cssText;
throw $break;}});
if(cssText)throw $break;});
this.style=cssText.parseStyle();
options.afterFinishInternal=function(effect){
effect.element.addClassName(effect.options.style);
effect.transforms.each(function(transform){
if(transform.style!='opacity')
effect.element.style[transform.style.camelize()]='';});}}else this.style=options.style.parseStyle();}else this.style=$H(options.style)
this.start(options);},
setup:function(){
function parseColor(color){
if(!color||['rgba(0, 0, 0, 0)','transparent'].include(color))color='#ffffff';
color=color.parseColor();
return $R(0,2).map(function(i){
return parseInt(color.slice(i*2+1,i*2+3),16)});}
this.transforms=this.style.map(function(pair){
var property=pair[0].underscore().dasherize(),value=pair[1],unit=null;
if(value.parseColor('#zzzzzz')!='#zzzzzz'){
value=value.parseColor();
unit='color';}else if(property=='opacity'){
value=parseFloat(value);
if(/MSIE/.test(navigator.userAgent)&&!window.opera&&(!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom:1});}else if(Element.CSS_LENGTH.test(value))
var components=value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
value=parseFloat(components[1]),unit=(components.length==3)?components[2]:null;
var originalValue=this.element.getStyle(property);
return $H({
style:property,
originalValue:unit=='color'?parseColor(originalValue):parseFloat(originalValue||0),
targetValue:unit=='color'?parseColor(value):value,
unit:unit});}.bind(this)).reject(function(transform){
return((transform.originalValue==transform.targetValue)||(
transform.unit!='color'&&(isNaN(transform.originalValue)||isNaN(transform.targetValue))))});},
update:function(position){
var style=$H(),value=null;
this.transforms.each(function(transform){
value=transform.unit=='color'?
$R(0,2).inject('#',function(m,v,i){
return m+(Math.round(transform.originalValue[i]+(transform.targetValue[i]-transform.originalValue[i])*position)).toColorPart()}):
transform.originalValue+Math.round(((transform.targetValue-transform.originalValue)*position)*1000)/1000+transform.unit;
style[transform.style]=value;});
this.element.setStyle(style);}});
Effect.Transform=Class.create();
Object.extend(Effect.Transform.prototype,{
initialize:function(tracks){
this.tracks=[];
this.options=arguments[1]||{};
this.addTracks(tracks);},
addTracks:function(tracks){
tracks.each(function(track){
var data=$H(track).values().first();
this.tracks.push($H({
ids:$H(track).keys().first(),
effect:Effect.Morph,
options:{style:data}}));}.bind(this));
return this;},
play:function(){
return new Effect.Parallel(
this.tracks.map(function(track){
var elements=[$(track.ids)||$$(track.ids)].flatten();
return elements.map(function(e){return new track.effect(e,Object.extend({sync:true},track.options))});}).flatten(),
this.options);}});
Element.CSS_PROPERTIES=$w(
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle '+
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth '+
'borderRightColor borderRightStyle borderRightWidth borderSpacing '+
'borderTopColor borderTopStyle borderTopWidth bottom clip color '+
'fontSize fontWeight height left letterSpacing lineHeight '+
'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
'maxWidth minHeight minWidth opacity outlineColor outlineOffset '+
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop '+
'right textIndent top width wordSpacing zIndex');
Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.prototype.parseStyle=function(){
var element=Element.extend(document.createElement('div'));
element.innerHTML='<div style="'+this +'"></div>';
var style=element.down().style,styleRules=$H();
Element.CSS_PROPERTIES.each(function(property){
if(style[property])styleRules[property]=style[property];});
if(/MSIE/.test(navigator.userAgent)&&!window.opera&&this.indexOf('opacity')>-1){
styleRules.opacity=this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];}
return styleRules;};
Element.morph=function(element,style){
new Effect.Morph(element,Object.extend({style:style},arguments[2]||{}));
return element;};['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f){Element.Methods[f]=Element[f];});
Element.Methods.visualEffect=function(element,effect,options){
s=effect.gsub(/_/,'-').camelize();
effect_class=s.charAt(0).toUpperCase()+s.substring(1);
new Effect[effect_class](element,options);
return $(element);};
Element.addMethods();
