// Spry.Effect.js - version 0.38 - Spry Pre-Release 1.6.1



//



// Copyright (c) 2006. Adobe Systems Incorporated.



// All rights reserved.



//



// Redistribution and use in source and binary forms, with or without



// modification, are permitted provided that the following conditions are met:



//



//   * Redistributions of source code must retain the above copyright notice,



//     this list of conditions and the following disclaimer.



//   * Redistributions in binary form must reproduce the above copyright notice,



//     this list of conditions and the following disclaimer in the documentation



//     and/or other materials provided with the distribution.



//   * Neither the name of Adobe Systems Incorporated nor the names of its



//     contributors may be used to endorse or promote products derived from this



//     software without specific prior written permission.



//



// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"



// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE



// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE



// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE



// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR



// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF



// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS



// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN



// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)



// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE



// POSSIBILITY OF SUCH DAMAGE.







var Spry;







if (!Spry) Spry = {};







Spry.forwards = 1; // const



Spry.backwards = 2; // const







if (!Spry.Effect) Spry.Effect = {};







Spry.Effect.Transitions = {



	linearTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + (time / duration) * change;



	},



	sinusoidalTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + ((-Math.cos((time/duration)*Math.PI)/2) + 0.5) * change;



	},



	squareTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + Math.pow(time/duration, 2) * change;



	},



	squarerootTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + Math.sqrt(time/duration) * change;



	},



	fifthTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + Math.sqrt((-Math.cos((time/duration)*Math.PI)/2) + 0.5) * change;



	},



	circleTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		var pos = time/duration;



		return begin + Math.sqrt(1 - Math.pow((pos-1), 2))* change;



	},



	pulsateTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		return begin + (0.5 + Math.sin(17*time/duration)/2) * change;



	},



	growSpecificTransition: function(time, begin, change, duration)



	{



		if (time > duration) return change+begin;



		var pos = time/duration;



		return begin + (5 * Math.pow(pos, 3) - 6.4 * Math.pow(pos, 2) + 2 * pos) * change;



	}



};



for (var trans in Spry.Effect.Transitions)



{



	Spry[trans] = Spry.Effect.Transitions[trans];



}



//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Registry



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Registry = function()



{



	this.effects = [];



};







Spry.Effect.Registry.prototype.getRegisteredEffect = function(element, options) 



{



	var a = {};



	a.element = Spry.Effect.getElement(element);



	a.options = options;







	for (var i=0; i<this.effects.length; i++)



		if (this.effectsAreTheSame(this.effects[i], a))



			return this.effects[i].effect;







	return false;



};







Spry.Effect.Registry.prototype.addEffect = function(effect, element, options)



{



	if (!this.getRegisteredEffect(element, options))



	{



		var len = this.effects.length;



		this.effects[len] = {};



		var eff = this.effects[len];



		eff.effect = effect;



		eff.element = Spry.Effect.getElement(element);



		eff.options = options;



	}



};







Spry.Effect.Registry.prototype.effectsAreTheSame = function(effectA, effectB)



{



	if (effectA.element != effectB.element)



		return false;







	var compare = Spry.Effect.Utils.optionsAreIdentical(effectA.options, effectB.options);



	// reset finish and setup functions



	if (compare)



	{



		if (typeof effectB.options.setup == 'function')



			effectA.options.setup = effectB.options.setup;







		if (typeof effectB.options.finish == 'function')



			effectA.options.finish = effectB.options.finish;



	}		







	return compare;



};







var SpryRegistry = new Spry.Effect.Registry;







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Utils



//



//////////////////////////////////////////////////////////////////////







if (!Spry.Effect.Utils) Spry.Effect.Utils = {};







Spry.Effect.Utils.showError = function(msg)



{



	alert('Spry.Effect ERR: ' + msg);



};



Spry.Effect.Utils.showInitError = function(effect){



	Spry.Effect.Utils.showError('The ' + effect + ' class can\'t be accessed as a static function anymore. '+ "\n" + 'Please read Spry Effects migration documentation.');



	return false;



};



Spry.Effect.Utils.Position = function()



{



	this.x = 0; // left



	this.y = 0; // top



	this.units = "px";



};







Spry.Effect.Utils.Rectangle = function()



{



	this.width = 0;



	this.height = 0;



	this.units = "px";



};







Spry.Effect.Utils.intToHex = function(integerNum) 



{



	var result = integerNum.toString(16);



	if (result.length == 1)



		result = "0" + result;



	return result;



};







Spry.Effect.Utils.hexToInt = function(hexStr)



{



	return parseInt(hexStr, 16);



};







Spry.Effect.Utils.rgb = function(redInt, greenInt, blueInt)



{



	var intToHex = Spry.Effect.Utils.intToHex;



	var redHex = intToHex(redInt);



	var greenHex = intToHex(greenInt);



	var blueHex = intToHex(blueInt);



	compositeColorHex = redHex.concat(greenHex, blueHex).toUpperCase();



	compositeColorHex = '#' + compositeColorHex;



	return compositeColorHex;



};







Spry.Effect.Utils.longColorVersion = function(color){



	if ( color.match(/^#[0-9a-f]{3}$/i) ){



		var tmp = color.split('');



		var color = '#';



		for (var i = 1; i < tmp.length; i++){



			color += tmp[i] + '' + tmp[i];	



		}



	}



	return color;



};







Spry.Effect.Utils.camelize = function(stringToCamelize)



{



	if (stringToCamelize.indexOf('-') == -1){



		return stringToCamelize;	



	}



	var oStringList = stringToCamelize.split('-');



	var isFirstEntry = true;



	var camelizedString = '';







	for(var i=0; i < oStringList.length; i++)



	{



		if(oStringList[i].length>0)



		{



			if(isFirstEntry)



			{



				camelizedString = oStringList[i];



				isFirstEntry = false;



			}



			else



			{



				var s = oStringList[i];



				camelizedString += s.charAt(0).toUpperCase() + s.substring(1);



			}



		}



	}







	return camelizedString;



};







Spry.Effect.Utils.isPercentValue = function(value)



{



	var result = false;



	if (typeof value == 'string' && value.length > 0 && value.lastIndexOf("%") > 0)



		result = true;







	return result;



};







Spry.Effect.Utils.getPercentValue = function(value)



{



	var result = 0;



	try



	{



		result = Number(value.substring(0, value.lastIndexOf("%")));



	}



	catch (e) {Spry.Effect.Utils.showError('Spry.Effect.Utils.getPercentValue: ' + e);}



	return result;



};







Spry.Effect.Utils.getPixelValue = function(value)



{



	var result = 0;



	if (typeof value == 'number') return value;



	var unitIndex = value.lastIndexOf("px");



	if ( unitIndex == -1)



		unitIndex = value.length;



	try



	{



		result = parseInt(value.substring(0, unitIndex), 10);



	}



	catch (e){}



	return result;



};







Spry.Effect.Utils.getFirstChildElement = function(node)



{



	if (node)



	{



		var childCurr = node.firstChild;



		while (childCurr)



		{



			if (childCurr.nodeType == 1) // Node.ELEMENT_NODE



				return childCurr;







			childCurr = childCurr.nextSibling;



		}



	}







	return null;



};







Spry.Effect.Utils.fetchChildImages = function(startEltIn, targetImagesOut)



{



	if(!startEltIn  || startEltIn.nodeType != 1 || !targetImagesOut)



		return;







	if(startEltIn.hasChildNodes())



	{



		var childImages = startEltIn.getElementsByTagName('img');



		var imageCnt = childImages.length;



		for(var i=0; i<imageCnt; i++)



		{



			var imgCurr = childImages[i];



			var dimensionsCurr = Spry.Effect.getDimensions(imgCurr);



			targetImagesOut.push([imgCurr,dimensionsCurr.width,dimensionsCurr.height]);



		}



	}



};







Spry.Effect.Utils.optionsAreIdentical = function(optionsA, optionsB)



{



	if(optionsA == null && optionsB == null)



		return true;







	if(optionsA != null && optionsB != null)



	{



		var objectCountA = 0;



		var objectCountB = 0;







		for (var propA in optionsA) objectCountA++;



		for (var propB in optionsB) objectCountB++;







		if(objectCountA != objectCountB)



			return false;







		for (var prop in optionsA)



		{



			var typeA = typeof optionsA[prop];



			var typeB = typeof optionsB[prop];



			if ( typeA != typeB || (typeA != 'undefined' && optionsA[prop] != optionsB[prop]))



				return false;



		}







		return true;



	}







	return false;



};







Spry.Effect.Utils.DoEffect = function (effectName, element, options)



{



	if (!options)



		var options = {};







	options.name = effectName;



	var ef = SpryRegistry.getRegisteredEffect(element, options);



	if (!ef)



	{



		ef = new Spry.Effect[effectName](element, options);



		SpryRegistry.addEffect(ef, element, options);



	}



	ef.start();



	return true;



};



//////////////////////////////////////////////////////////////////////



//



//  The notification class



//



//////////////////////////////////////////////////////////////////////



if (!Spry.Utils) Spry.Utils = {};







Spry.Utils.Notifier = function()



{



	this.observers = [];



	this.suppressNotifications = 0;



};







Spry.Utils.Notifier.prototype.addObserver = function(observer)



{



	if (!observer)



		return;







	// Make sure the observer isn't already on the list.







	var len = this.observers.length;



	for (var i = 0; i < len; i++)



		if (this.observers[i] == observer) return;







	this.observers[len] = observer;



};







Spry.Utils.Notifier.prototype.removeObserver = function(observer)



{



	if (!observer)



		return;







	for (var i = 0; i < this.observers.length; i++)



	{



		if (this.observers[i] == observer)



		{



			this.observers.splice(i, 1);



			break;



		}



	}



};







Spry.Utils.Notifier.prototype.notifyObservers = function(methodName, data)



{



	if (!methodName)



		return;







	if (!this.suppressNotifications)



	{



		var len = this.observers.length;



		for (var i = 0; i < len; i++)



		{



			var obs = this.observers[i];



			if (obs)



			{



				if (typeof obs == "function")



					obs(methodName, this, data);



				else if (obs[methodName])



					obs[methodName](this, data);



			}



		}



	}



};







Spry.Utils.Notifier.prototype.enableNotifications = function()



{



	if (--this.suppressNotifications < 0)



	{



		this.suppressNotifications = 0;



		Spry.Effect.Utils.showError("Unbalanced enableNotifications() call!\n");



	}



};







Spry.Utils.Notifier.prototype.disableNotifications = function()



{



	++this.suppressNotifications;



};







//////////////////////////////////////////////////////////////////////



//



// DHTML manipulation



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.getElement = function(ele)



{



	var element = ele;



	if (typeof ele == "string")



		element = document.getElementById(ele);







	if (element == null) 



		Spry.Effect.Utils.showError('Element "' + ele + '" not found.');



	



	return element;



};







Spry.Effect.getStyleProp = function(element, prop)



{



	var value;



	var camelized = Spry.Effect.Utils.camelize(prop);



	try



	{



		if (element.style)



			value = element.style[camelized];







		if (!value)



		{



			if (document.defaultView && document.defaultView.getComputedStyle)



			{



				var css = document.defaultView.getComputedStyle(element, null);



				value = css ? css.getPropertyValue(prop) : null;



			}



			else if (element.currentStyle) 



			{



					value = element.currentStyle[camelized];



			}



		}



	}



	catch (e) {Spry.Effect.Utils.showError('Spry.Effect.getStyleProp: ' + e);}







	return value == 'auto' ? null : value;



};







Spry.Effect.setStyleProp = function(element, prop, value)



{



	try



	{



		element.style[Spry.Effect.Utils.camelize(prop)] = value;



	}



	catch (e) {Spry.Effect.Utils.showError('Spry.Effect.setStyleProp: ' + e);}



};







Spry.Effect.getStylePropRegardlessOfDisplayState = function(element, prop, displayElement)



{



	var refElement = displayElement ? displayElement : element;



	var displayOrig = Spry.Effect.getStyleProp(refElement, 'display');



	var visibilityOrig = Spry.Effect.getStyleProp(refElement, 'visibility');







	if(displayOrig == 'none')



	{



		Spry.Effect.setStyleProp(refElement, 'visibility', 'hidden');



		Spry.Effect.setStyleProp(refElement, 'display', 'block');







		if(window.opera) // opera needs focus to calculate the size for hidden elements



			refElement.focus();



	}







	var styleProp = Spry.Effect.getStyleProp(element, prop);







	if(displayOrig == 'none') // reset the original values



	{



		Spry.Effect.setStyleProp(refElement, 'display', 'none');



		Spry.Effect.setStyleProp(refElement, 'visibility', visibilityOrig);



	}



	return styleProp;



};







Spry.Effect.makePositioned = function(element)



{



	var pos = Spry.Effect.getStyleProp(element, 'position');



	if (!pos || pos == 'static')



	{



		element.style.position = 'relative';







		// Opera returns the offset relative to the positioning context, when an



		// element is position relative but top and left have not been defined



		if (window.opera)



		{



			element.style.top = 0;



			element.style.left = 0;



		}



	}



};







Spry.Effect.isInvisible = function(element)



{



	var propDisplay = Spry.Effect.getStyleProp(element, 'display');



	if (propDisplay && propDisplay.toLowerCase() == 'none')



		return true;







	var propVisible = Spry.Effect.getStyleProp(element, 'visibility');



	if (propVisible && propVisible.toLowerCase() == 'hidden')



		return true;







	return false;



};







Spry.Effect.enforceVisible = function(element)



{



	var propDisplay = Spry.Effect.getStyleProp(element, 'display');



	if (propDisplay && propDisplay.toLowerCase() == 'none')



		Spry.Effect.setStyleProp(element, 'display', 'block');







	var propVisible = Spry.Effect.getStyleProp(element, 'visibility');



	if (propVisible && propVisible.toLowerCase() == 'hidden')



		Spry.Effect.setStyleProp(element, 'visibility', 'visible');



};







Spry.Effect.makeClipping = function(element)



{



	var overflow = Spry.Effect.getStyleProp(element, 'overflow');



	if (!overflow || (overflow.toLowerCase() != 'hidden' && overflow.toLowerCase() != 'scroll'))



	{



		// IE 7 bug: set overflow property to hidden changes the element height to 0



		// -> therefore we save the height before changing the overflow property and set the old size back



		var heightCache = 0;



		var needsCache = /MSIE 7.0/.test(navigator.userAgent) && /Windows NT/.test(navigator.userAgent);



		if(needsCache)



			heightCache = Spry.Effect.getDimensionsRegardlessOfDisplayState(element).height;







		Spry.Effect.setStyleProp(element, 'overflow', 'hidden');







		if(needsCache)



			Spry.Effect.setStyleProp(element, 'height', heightCache+'px');



	}



};







Spry.Effect.cleanWhitespace = function(element) 



{



	var childCountInit = element.childNodes.length;



  for (var i = childCountInit - 1; i >= 0; i--) {



  	var node = element.childNodes[i];



		if (node.nodeType == 3 && !/\S/.test(node.nodeValue))



			try



			{



				element.removeChild(node);



			}



			catch (e) {Spry.Effect.Utils.showError('Spry.Effect.cleanWhitespace: ' + e);}



	}



};







Spry.Effect.getComputedStyle = function(element)



{



	return /MSIE/.test(navigator.userAgent) ? element.currentStyle : document.defaultView.getComputedStyle(element, null);



};







Spry.Effect.getDimensions = function(element)



{



	var dimensions = new Spry.Effect.Utils.Rectangle;



	var computedStyle = null;







	if (element.style.width && /px/i.test(element.style.width))



		dimensions.width = parseInt(element.style.width, 10); // without padding



	else



	{



		computedStyle = Spry.Effect.getComputedStyle(element);



		var tryComputedStyle = computedStyle && computedStyle.width && /px/i.test(computedStyle.width);







		if (tryComputedStyle)



			dimensions.width = parseInt(computedStyle.width, 10); // without padding, includes css







		if (!tryComputedStyle || dimensions.width == 0) // otherwise we might run into problems on safari and opera (mac only)



			dimensions.width = element.offsetWidth;   // includes padding



	}







	if (element.style.height && /px/i.test(element.style.height))



		dimensions.height = parseInt(element.style.height, 10); // without padding



	else



	{



		if (!computedStyle)



			computedStyle = Spry.Effect.getComputedStyle(element);







		var tryComputedStyle = computedStyle && computedStyle.height && /px/i.test(computedStyle.height);







		if (tryComputedStyle)



			dimensions.height = parseInt(computedStyle.height, 10); // without padding, includes css







		if(!tryComputedStyle || dimensions.height == 0) // otherwise we might run into problems on safari and opera (mac only)



			dimensions.height = element.offsetHeight;   // includes padding



	}



	return dimensions;



};







Spry.Effect.getDimensionsRegardlessOfDisplayState = function(element, displayElement)



{



	// If the displayElement display property is set to 'none', we temporarily set its



	// visibility state to 'hidden' to be able to calculate the dimension.







	var refElement = displayElement ? displayElement : element;



	var displayOrig = Spry.Effect.getStyleProp(refElement, 'display');



	var visibilityOrig = Spry.Effect.getStyleProp(refElement, 'visibility');







	if(displayOrig == 'none')



	{



		Spry.Effect.setStyleProp(refElement, 'visibility', 'hidden');



		Spry.Effect.setStyleProp(refElement, 'display', 'block');







		if(window.opera) // opera needs focus to calculate the size for hidden elements



			refElement.focus();



	}







	var dimensions = Spry.Effect.getDimensions(element);







	if(displayOrig == 'none') // reset the original values



	{



		Spry.Effect.setStyleProp(refElement, 'display', 'none');



		Spry.Effect.setStyleProp(refElement, 'visibility', visibilityOrig);



	}



	return dimensions;



};







Spry.Effect.getOpacity = function(element)



{



  var o = Spry.Effect.getStyleProp(element, "opacity");



  if (typeof o == 'undefined' || o == null)



    o = 1.0;



  return o;



};







Spry.Effect.getBgColor = function(ele)



{



  return Spry.Effect.getStyleProp(ele, "background-color");



};







Spry.Effect.intPropStyle = function(e, prop){



		var i = parseInt(Spry.Effect.getStyleProp(e, prop), 10);



		if (isNaN(i))



			return 0;



		return i;



};







Spry.Effect.getPosition = function(element)



{



	var position = new Spry.Effect.Utils.Position;



	var computedStyle = null;







	if (element.style.left  && /px/i.test(element.style.left))



		position.x = parseInt(element.style.left, 10); // without padding



	else



	{



		computedStyle = Spry.Effect.getComputedStyle(element);



		var tryComputedStyle = computedStyle && computedStyle.left && /px/i.test(computedStyle.left);







		if (tryComputedStyle)



			position.x = parseInt(computedStyle.left, 10); // without padding, includes css







		if(!tryComputedStyle || position.x == 0) // otherwise we might run into problems on safari and opera (mac only)



			position.x = element.offsetLeft;   // includes padding



	}







	if (element.style.top && /px/i.test(element.style.top))



		position.y = parseInt(element.style.top, 10); // without padding



	else



	{



		if (!computedStyle)



			computedStyle = Spry.Effect.getComputedStyle(element);







    var tryComputedStyle = computedStyle && computedStyle.top && /px/i.test(computedStyle.top);







		if (tryComputedStyle)



			position.y = parseInt(computedStyle.top, 10); // without padding, includes css







		if(!tryComputedStyle || position.y == 0) // otherwise we might run into problems on safari and opera (mac only)



			position.y = element.offsetTop;   // includes padding



	}



	return position;



};







Spry.Effect.getOffsetPosition = Spry.Effect.getPosition; // deprecated







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Animator



// (base class)



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Animator = function(options)



{



	Spry.Utils.Notifier.call(this);



	



	this.name = 'Animator';



	this.element = null;



	this.startMilliseconds = 0;



	this.repeat = 'none';



	this.isRunning = false;



	this.timer = null;



	this.cancelRemaining = 0;







	if (!options)



		var options = {};







	if (options.toggle)



		this.direction = false;



	else



		this.direction = Spry.forwards;



	



	var self = this;



	if (options.setup != null)



		this.addObserver({onPreEffect: function(){try{self.options.setup(self.element, self);}catch(e){Spry.Effect.Utils.showError('Spry.Effect.Animator.prototype.start: setup callback: ' + e);}}});







	if (options.finish != null)



		this.addObserver({onPostEffect: function(){try{self.options.finish(self.element, self);}catch(e){Spry.Effect.Utils.showError('Spry.Effect.Animator.prototype.stop: finish callback: ' + e);}}});







	this.options = {



		duration: 1000,



		toggle: false,



		transition: Spry.linearTransition,



		interval: 16 // ca. 62 fps



	};







	this.setOptions(options);



	if (options.transition)



		this.setTransition(options.transition);







	if (options.fps)



		this.setFps(options.fps);



};



Spry.Effect.Animator.prototype = new Spry.Utils.Notifier();



Spry.Effect.Animator.prototype.constructor = Spry.Utils.Animator;







Spry.Effect.Animator.prototype.notStaticAnimator = true;







Spry.Effect.Animator.prototype.setOptions = function(options)



{



	if (!options)



		return;



	for (var prop in options)



		this.options[prop] = options[prop];



};



Spry.Effect.Animator.prototype.setTransition = function(transition){



	if (typeof transition == 'number' || transition == "1" || transition == "2")



		switch (parseInt(transition,10))



		{



			case 1: transition = Spry.linearTransition; break;



			case 2: transition = Spry.sinusoidalTransition; break;



			default: Spry.Effect.Utils.showError('unknown transition');



		}







	else if (typeof transition == 'string')



	{



		if (typeof window[transition] == 'function')



			transition = window[transition];



		else if (typeof Spry[transition] == 'function')



			transition = Spry[transition];



		else



			Spry.Effect.Utils.showError('unknown transition');



	}







	this.options.transition = transition;



	if (typeof this.effectsArray != 'undefined'){



		var l = this.effectsArray.length;



		for (var i = 0; i < l; i++)



				this.effectsArray[i].effect.setTransition(transition);



	}



};







Spry.Effect.Animator.prototype.setDuration = function(duration){



	this.options.duration = duration;



	if (typeof this.effectsArray != 'undefined')



	{



		var l = this.effectsArray.length;



		for (var i = 0; i < l; i++)



		{



			this.effectsArray[i].effect.setDuration(duration);



		}



	}



};







Spry.Effect.Animator.prototype.setFps = function(fps){



	this.options.interval = parseInt(1000 / fps, 10);



	this.options.fps = fps;



	if (typeof this.effectsArray != 'undefined')



	{



		var l = this.effectsArray.length;



		for (var i = 0; i < l; i++)



		{



			this.effectsArray[i].effect.setFps(fps);



		}



	}



};







Spry.Effect.Animator.prototype.start = function(withoutTimer)



{



	if (!this.element)



		return;







	if (arguments.length == 0)



		withoutTimer = false;







	if (this.isRunning)



		this.cancel();







	this.prepareStart();



	var currDate = new Date();



	this.startMilliseconds = currDate.getTime();







	if (this.element.id)



		this.element = document.getElementById(this.element.id);







	if (this.cancelRemaining != 0 && this.options.toggle)



	{



		if (this.cancelRemaining < 1 && typeof this.options.transition == 'function')



		{



			var startTime = 0;



			var stopTime = this.options.duration;



			var start = 0;



			var stop = 1;



			var emergency = 0;



			this.cancelRemaining = Math.round(this.cancelRemaining * 1000) / 1000;



			var found = false;



			var middle = 0;



			while (!found)



			{



				if (emergency++ > this.options.duration) break;



				var half = startTime + ((stopTime - startTime) / 2);



				middle = Math.round(this.options.transition(half, 1, -1, this.options.duration) * 1000) / 1000;



				if (middle == this.cancelRemaining)



				{



					this.startMilliseconds -= half;



					found = true;



				}



				if (middle < this.cancelRemaining)



				{



					stopTime = half;



					stop = middle;



				}



				else



				{



					startTime = half;



					start = middle;



				}



			}



		}



		this.cancelRemaining = 0;



	}



	this.notifyObservers('onPreEffect', this);







	if (withoutTimer == false)



	{



		var self = this;



		this.timer = setInterval(function() { self.drawEffect(); }, this.options.interval);



	}



	this.isRunning = true;



};



Spry.Effect.Animator.prototype.stopFlagReset = function()



{



	if (this.timer)



	{



		clearInterval(this.timer);



		this.timer = null;



	}



	this.startMilliseconds = 0;



};



Spry.Effect.Animator.prototype.stop = function()



{



	this.stopFlagReset();



	this.notifyObservers('onPostEffect', this);



	this.isRunning = false;



};







Spry.Effect.Animator.prototype.cancel = function()



{



	var elapsed = this.getElapsedMilliseconds();



	if (this.startMilliseconds > 0 && elapsed < this.options.duration)



		this.cancelRemaining = this.options.transition(elapsed, 0, 1, this.options.duration);







	this.stopFlagReset();



	this.notifyObservers('onCancel', this);



	this.isRunning = false;



};







Spry.Effect.Animator.prototype.drawEffect = function()



{



	var isRunning = true;







	this.notifyObservers('onStep', this);



	var timeElapsed = this.getElapsedMilliseconds();







	if (typeof this.options.transition != 'function'){



		Spry.Effect.Utils.showError('unknown transition');



		return;



	}



	this.animate();







	if (timeElapsed > this.options.duration)



	{



		isRunning = false;



		this.stop();



	}



	return isRunning;



};







Spry.Effect.Animator.prototype.getElapsedMilliseconds = function()



{



	if (this.startMilliseconds > 0)



	{



		var currDate = new Date();



		return (currDate.getTime() - this.startMilliseconds);



	}



	return 0;



};







Spry.Effect.Animator.prototype.doToggle = function()



{



	if (!this.direction)



	{



		this.direction = Spry.forwards;



		return;



	}



	if (this.options.toggle == true)



	{



		if (this.direction == Spry.forwards)



		{



			this.direction = Spry.backwards;



			this.notifyObservers('onToggle', this);



		} 



		else if (this.direction == Spry.backwards)



		{



			this.direction = Spry.forwards;



		}



	}



};







Spry.Effect.Animator.prototype.prepareStart = function()



{



		if (this.options && this.options.toggle)



			this.doToggle();



};







Spry.Effect.Animator.prototype.animate = function(){};



Spry.Effect.Animator.prototype.onStep = function(el)



{



	if (el != this)



		this.notifyObservers('onStep', this);



};



//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Move



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Move = function(element, fromPos, toPos, options)



{



	this.dynamicFromPos = false;



	if (arguments.length == 3)



	{



		options = toPos;



		toPos = fromPos;



		fromPos = Spry.Effect.getPosition(element);



		this.dynamicFromPos = true;



	}







	Spry.Effect.Animator.call(this, options);







	this.name = 'Move';



	this.element = Spry.Effect.getElement(element);



	if (!this.element)



		return;







	if (fromPos.units != toPos.units)



		Spry.Effect.Utils.showError('Spry.Effect.Move: Conflicting units (' + fromPos.units + ', ' + toPos.units + ')');







	this.units = fromPos.units;



	this.startX = Number(fromPos.x);



	this.stopX = Number(toPos.x);



	this.startY = Number(fromPos.y);



	this.stopY = Number(toPos.y);



};







Spry.Effect.Move.prototype = new Spry.Effect.Animator();



Spry.Effect.Move.prototype.constructor = Spry.Effect.Move;







Spry.Effect.Move.prototype.animate = function()



{



	var left = 0;



	var top = 0;



	var floor = Math.floor;



	var elapsed = this.getElapsedMilliseconds();



	if (this.direction == Spry.forwards)



	{



		left = floor(this.options.transition(elapsed, this.startX, this.stopX - this.startX, this.options.duration));



		top = floor(this.options.transition(elapsed, this.startY, this.stopY - this.startY, this.options.duration));



	}



	else if (this.direction == Spry.backwards)



	{



		left = floor(this.options.transition(elapsed, this.stopX, this.startX - this.stopX, this.options.duration));



		top = floor(this.options.transition(elapsed, this.stopY, this.startY - this.stopY, this.options.duration));



	}







	this.element.style.left = left + this.units;



	this.element.style.top = top + this.units;



};







Spry.Effect.Move.prototype.prepareStart = function()



{



	if (this.options && this.options.toggle)



		this.doToggle();







	if (this.dynamicFromPos == true)



	{



		var fromPos = Spry.Effect.getPosition(this.element);



		this.startX = fromPos.x;



		this.startY = fromPos.y;



		



		this.rangeMoveX = this.startX - this.stopX;



		this.rangeMoveY= this.startY - this.stopY;



	}



};







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Size



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Size = function(element, fromRect, toRect, options)



{



	this.dynamicFromRect = false;







	if (arguments.length == 3)



	{



		options = toRect;



		toRect = fromRect;



		fromRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);



		this.dynamicFromRect = true;



	}







	Spry.Effect.Animator.call(this, options);







	this.name = 'Size';



	this.element = Spry.Effect.getElement(element);



	if (!this.element)



		return;







	element = this.element;







	if (fromRect.units != toRect.units)



	{



		Spry.Effect.Utils.showError('Spry.Effect.Size: Conflicting units (' + fromRect.units + ', ' + toRect.units + ')');



		return false;



	}







	this.units = fromRect.units;







	var originalRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);



	this.originalWidth = originalRect.width;



	this.originalHeight = originalRect.height;







	this.startWidth = fromRect.width;



	this.startHeight = fromRect.height;



	this.stopWidth = toRect.width;



	this.stopHeight = toRect.height;



	this.childImages = new Array();







	if (this.options.useCSSBox){



		Spry.Effect.makePositioned(this.element);



		var intProp = Spry.Effect.intPropStyle;



		this.startFromBorder_top = intProp(element, 'border-top-width');



		this.startFromBorder_bottom = intProp(element, 'border-bottom-width');



		this.startFromBorder_left = intProp(element, 'border-left-width');



		this.startFromBorder_right = intProp(element, 'border-right-width');



		this.startFromPadding_top = intProp(element, 'padding-top');



		this.startFromPadding_bottom = intProp(element, 'padding-bottom');



		this.startFromPadding_left = intProp(element, 'padding-left');



		this.startFromPadding_right = intProp(element, 'padding-right');



		this.startFromMargin_top = intProp(element, 'margin-top');



		this.startFromMargin_bottom = intProp(element, 'margin-bottom');



		this.startFromMargin_right = intProp(element, 'margin-right');



		this.startFromMargin_left = intProp(element, 'margin-left');



		this.startLeft = intProp(element, 'left');



		this.startTop = intProp(element, 'top');



	}







	if(this.options.scaleContent)



		Spry.Effect.Utils.fetchChildImages(element, this.childImages);







	this.fontFactor = 1.0;



	var fontSize = Spry.Effect.getStyleProp(this.element, 'font-size');



	if(fontSize && /em\s*$/.test(fontSize))



		this.fontFactor = parseFloat(fontSize);







	var isPercent = Spry.Effect.Utils.isPercentValue;







	if (isPercent(this.startWidth))



	{



		var startWidthPercent = Spry.Effect.Utils.getPercentValue(this.startWidth);



		this.startWidth = originalRect.width * (startWidthPercent / 100);



	}







	if (isPercent(this.startHeight))



	{



		var startHeightPercent = Spry.Effect.Utils.getPercentValue(this.startHeight);



		this.startHeight = originalRect.height * (startHeightPercent / 100);



	}







	if (isPercent(this.stopWidth))



	{



		var stopWidthPercent = Spry.Effect.Utils.getPercentValue(this.stopWidth);



		this.stopWidth = originalRect.width * (stopWidthPercent / 100);



	}







	if (isPercent(this.stopHeight))



	{



		var stopHeightPercent = Spry.Effect.Utils.getPercentValue(this.stopHeight);



		this.stopHeight = originalRect.height * (stopHeightPercent / 100);



	}







	this.enforceVisible = Spry.Effect.isInvisible(this.element);



};







Spry.Effect.Size.prototype = new Spry.Effect.Animator();



Spry.Effect.Size.prototype.constructor = Spry.Effect.Size;







Spry.Effect.Size.prototype.animate = function()



{



	var width = 0;



	var height = 0;



	var fontSize = 0;



	var direction = 0;



	var floor = Math.floor;



	var elapsed = this.getElapsedMilliseconds();







	if (this.direction == Spry.forwards) {



		width = floor(this.options.transition(elapsed, this.startWidth, this.stopWidth - this.startWidth, this.options.duration));



		height = floor(this.options.transition(elapsed, this.startHeight, this.stopHeight - this.startHeight, this.options.duration));



		direction = 1;



	} else if (this.direction == Spry.backwards) {



		width = floor(this.options.transition(elapsed, this.stopWidth, this.startWidth - this.stopWidth, this.options.duration));



		height = floor(this.options.transition(elapsed, this.stopHeight, this.startHeight - this.stopHeight, this.options.duration));



		direction = -1;



	}







	var propFactor = width/this.originalWidth;



	fontSize = this.fontFactor * propFactor;







	var elStyle = this.element.style;



	if (width < 0)



		width = 0;



	



	if (height < 0)



		height = 0;







	elStyle.width = width + this.units;



	elStyle.height = height + this.units;







	if (typeof this.options.useCSSBox != 'undefined' && this.options.useCSSBox == true)



	{



		var intProp = Spry.Effect.intPropStyle;



		var origTop = intProp(this.element, 'top');



		var origLeft = intProp(this.element, 'left');



		var origMarginTop = intProp(this.element, 'margin-top');



		var origMarginLeft = intProp(this.element, 'margin-left');







		var widthFactor = propFactor;



		var heightFactor = height / this.originalHeight;



		var border_top = floor(this.startFromBorder_top * heightFactor);



		var border_bottom = floor(this.startFromBorder_bottom * heightFactor);



		var border_left = floor(this.startFromBorder_left * widthFactor);



		var border_right = floor(this.startFromBorder_right * widthFactor);



		var padding_top = floor(this.startFromPadding_top * heightFactor);



		var padding_bottom = floor(this.startFromPadding_bottom * heightFactor);



		var padding_left = floor(this.startFromPadding_left * widthFactor);



		var padding_right = floor(this.startFromPadding_right * widthFactor);



		var margin_top = floor(this.startFromMargin_top * heightFactor);



		var margin_bottom = floor(this.startFromMargin_bottom * heightFactor);



		var margin_right = floor(this.startFromMargin_right * widthFactor);



		var margin_left = floor(this.startFromMargin_left * widthFactor);







		elStyle.borderTopWidth = border_top + this.units;



		elStyle.borderBottomWidth = border_bottom + this.units;



		elStyle.borderLeftWidth = border_left + this.units;



		elStyle.borderRightWidth = border_right + this.units;



		elStyle.paddingTop = padding_top + this.units;



		elStyle.paddingBottom = padding_bottom + this.units;



		elStyle.paddingLeft = padding_left + this.units;



		elStyle.paddingRight = padding_right + this.units;



		elStyle.marginTop  = margin_top + this.units;



		elStyle.marginBottom = margin_bottom + this.units;



		elStyle.marginLeft = margin_left + this.units;




		elStyle.marginRight = margin_right + this.units;







		// compensate the margin shrinking



		elStyle.left = floor(origLeft + origMarginLeft - margin_left) + this.units;



		elStyle.top = floor(origTop + origMarginTop - margin_top) + this.units;



	}







	if (this.options.scaleContent)



	{







		for(var i=0; i < this.childImages.length; i++)



		{



			this.childImages[i][0].style.width = propFactor * this.childImages[i][1] + this.units;



			this.childImages[i][0].style.height = propFactor * this.childImages[i][2] + this.units;



		}



		this.element.style.fontSize = fontSize + 'em';



	}







	if(this.enforceVisible)



	{



		Spry.Effect.enforceVisible(this.element);



		this.enforceVisible = false;



	}



};







Spry.Effect.Size.prototype.prepareStart = function()



{



	if (this.options && this.options.toggle)



		this.doToggle();	







	if (this.dynamicFromRect == true)



	{



		var fromRect = Spry.Effect.getDimensions(this.element);



		this.startWidth = fromRect.width;



		this.startHeight = fromRect.height;







		this.widthRange = this.startWidth - this.stopWidth;



		this.heightRange = this.startHeight - this.stopHeight;



	}



};







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Opacity



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Opacity = function(element, startOpacity, stopOpacity, options)



{



	this.dynamicStartOpacity = false;



	if (arguments.length == 3)



	{



		options = stopOpacity;



		stopOpacity = startOpacity;



		startOpacity = Spry.Effect.getOpacity(element);



		this.dynamicStartOpacity = true;



	}







	Spry.Effect.Animator.call(this, options);







	this.name = 'Opacity';



	this.element = Spry.Effect.getElement(element);



	if (!this.element)



		return;







 	// make this work on IE on elements without 'layout'



	if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))



		Spry.Effect.setStyleProp(this.element, 'zoom', '1');







	this.startOpacity = startOpacity;



	this.stopOpacity = stopOpacity;



	this.enforceVisible = Spry.Effect.isInvisible(this.element);



};







Spry.Effect.Opacity.prototype = new Spry.Effect.Animator();



Spry.Effect.Opacity.prototype.constructor = Spry.Effect.Opacity;







Spry.Effect.Opacity.prototype.animate = function()



{



	var opacity = 0;



	var elapsed = this.getElapsedMilliseconds();



	if (this.direction == Spry.forwards) 



		opacity = this.options.transition(elapsed, this.startOpacity, this.stopOpacity - this.startOpacity, this.options.duration);



	else if (this.direction == Spry.backwards) 



		opacity = this.options.transition(elapsed, this.stopOpacity, this.startOpacity - this.stopOpacity, this.options.duration);







	if (opacity < 0)



		opacity = 0;







	if(/MSIE/.test(navigator.userAgent))



	{



		var tmpval = Spry.Effect.getStyleProp(this.element,'filter');



		if (tmpval){



			tmpval = tmpval.replace(/alpha\(opacity=[0-9]{1,3}\)/g, '');



		}



		this.element.style.filter = tmpval + "alpha(opacity=" + Math.floor(opacity * 100) + ")";

		if(opacity == 1) try{ this.element.style.removeAttribute("filter"); } catch(err) {}

	}



	else



		this.element.style.opacity = opacity;







	if(this.enforceVisible)



	{



		Spry.Effect.enforceVisible(this.element);



		this.enforceVisible = false;



	}



};







Spry.Effect.Opacity.prototype.prepareStart = function()



{



	if (this.options && this.options.toggle)



		this.doToggle();	







	if (this.dynamicStartOpacity == true)



	{



		this.startOpacity = Spry.Effect.getOpacity(this.element);



		this.opacityRange = this.startOpacity - this.stopOpacity;



	}





};







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Color



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Color = function(element, startColor, stopColor, options)



{



	this.dynamicStartColor = false;



	if (arguments.length == 3)



	{



		options = stopColor;



		stopColor = startColor;



		startColor = Spry.Effect.getBgColor(element);



		this.dynamicStartColor = true;



	}



	



	Spry.Effect.Animator.call(this, options);







	this.name = 'Color';



	this.element = Spry.Effect.getElement(element);



	if (!this.element)



		return;







	this.startColor = startColor;



	this.stopColor = stopColor;



	this.startRedColor = Spry.Effect.Utils.hexToInt(startColor.substr(1,2));



	this.startGreenColor = Spry.Effect.Utils.hexToInt(startColor.substr(3,2));



	this.startBlueColor = Spry.Effect.Utils.hexToInt(startColor.substr(5,2));



	this.stopRedColor = Spry.Effect.Utils.hexToInt(stopColor.substr(1,2));



	this.stopGreenColor = Spry.Effect.Utils.hexToInt(stopColor.substr(3,2));



	this.stopBlueColor = Spry.Effect.Utils.hexToInt(stopColor.substr(5,2));



};







Spry.Effect.Color.prototype = new Spry.Effect.Animator();



Spry.Effect.Color.prototype.constructor = Spry.Effect.Color;







Spry.Effect.Color.prototype.animate = function()



{



	var redColor = 0;



	var greenColor = 0;



	var blueColor = 0;



	var floor = Math.floor;



	var elapsed = this.getElapsedMilliseconds();







	if (this.direction == Spry.forwards)



	{



		redColor = floor(this.options.transition(elapsed, this.startRedColor, this.stopRedColor - this.startRedColor, this.options.duration));



		greenColor = floor(this.options.transition(elapsed, this.startGreenColor, this.stopGreenColor - this.startGreenColor, this.options.duration));



		blueColor = floor(this.options.transition(elapsed, this.startBlueColor, this.stopBlueColor - this.startBlueColor, this.options.duration));



	}



	else if (this.direction == Spry.backwards)



	{



		redColor = floor(this.options.transition(elapsed, this.stopRedColor, this.startRedColor - this.stopRedColor, this.options.duration));



		greenColor = floor(this.options.transition(elapsed, this.stopGreenColor, this.startGreenColor - this.stopGreenColor, this.options.duration));



		blueColor = floor(this.options.transition(elapsed, this.stopBlueColor, this.startBlueColor - this.stopBlueColor, this.options.duration));



	}







	this.element.style.backgroundColor = Spry.Effect.Utils.rgb(redColor, greenColor, blueColor);



};







Spry.Effect.Color.prototype.prepareStart = function() 



{



	if (this.options && this.options.toggle)



		this.doToggle();







	if (this.dynamicStartColor == true)



	{



		this.startColor = Spry.Effect.getBgColor(element);



		this.startRedColor = Spry.Effect.Utils.hexToInt(startColor.substr(1,2));



		this.startGreenColor = Spry.Effect.Utils.hexToInt(startColor.substr(3,2));



		this.startBlueColor = Spry.Effect.Utils.hexToInt(startColor.substr(5,2));



		this.redColorRange = this.startRedColor - this.stopRedColor;



		this.greenColorRange = this.startGreenColor - this.stopGreenColor;



		this.blueColorRange = this.startBlueColor - this.stopBlueColor;



	}



};







//////////////////////////////////////////////////////////////////////



//



// Spry.Effect.Cluster



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Cluster = function(options)



{



	Spry.Effect.Animator.call(this, options);







	this.name = 'Cluster';



	this.effectsArray = new Array();



	this.currIdx = -1;



	var _ClusteredEffect = function(effect, kind)



	{



		this.effect = effect;



		this.kind = kind; // "parallel" or "queue"



		this.isRunning = false;



	};







	this.ClusteredEffect = _ClusteredEffect;



};







Spry.Effect.Cluster.prototype = new Spry.Effect.Animator();



Spry.Effect.Cluster.prototype.constructor = Spry.Effect.Cluster;







Spry.Effect.Cluster.prototype.setInterval = function(interval){



	var l = this.effectsArray.length;



	this.options.interval = interval;



	for (var i = 0; i < l; i++)



	{



		this.effectsArray[i].effect.setInterval(interval);



	}



};



Spry.Effect.Cluster.prototype.drawEffect = function()



{



	var isRunning = true;



	var allEffectsDidRun = false;



	var baseEffectIsStillRunning = false;



	var evalNextEffectsRunning = false;







	if ((this.currIdx == -1 && this.direction == Spry.forwards) || (this.currIdx == this.effectsArray.length && this.direction == Spry.backwards))



		this.initNextEffectsRunning();







	var start = this.direction == Spry.forwards ? 0 : this.effectsArray.length-1;



	var stop = this.direction == Spry.forwards ? this.effectsArray.length : -1;



	var step = this.direction == Spry.forwards ? 1 : -1;



	for (var i = start; i != stop; i+=step)



	{



		if (this.effectsArray[i].isRunning == true)



		{



			baseEffectIsStillRunning = this.effectsArray[i].effect.drawEffect();



			if (baseEffectIsStillRunning == false && i == this.currIdx)



			{



				this.effectsArray[i].isRunning = false;



				evalNextEffectsRunning = true;



			}



		}



	}







	if (evalNextEffectsRunning == true)



		allEffectsDidRun = this.initNextEffectsRunning();







	if (allEffectsDidRun == true) {



		this.stop();



		isRunning = false;



		for (var i = 0; i < this.effectsArray.length; i++)



			this.effectsArray[i].isRunning = false;







		this.currIdx = this.direction == Spry.forwards ? this.effectsArray.length: -1;



	}



	return isRunning;



};







Spry.Effect.Cluster.prototype.initNextEffectsRunning = function()



{



	var allEffectsDidRun = false;



	var step = this.direction == Spry.forwards ? 1 : -1;



	var stop = this.direction == Spry.forwards ? this.effectsArray.length : -1;



	this.currIdx+=step;



	if ( (this.currIdx > (this.effectsArray.length - 1) && this.direction == Spry.forwards) || (this.currIdx < 0 && this.direction == Spry.backwards))



		allEffectsDidRun = true;



	else



		for (var i = this.currIdx; i != stop; i+=step)



		{



			if ((i > this.currIdx && this.direction == Spry.forwards || i < this.currIdx && this.direction == Spry.backwards) && this.effectsArray[i].kind == "queue")



				break;



			this.effectsArray[i].effect.start(true);



			this.effectsArray[i].isRunning = true;



			this.currIdx = i;



		}







	return allEffectsDidRun;



};







Spry.Effect.Cluster.prototype.toggleCluster = function()



{



	if (!this.direction)



	{



		this.direction = Spry.forwards;



		return;



	}







	if (this.options.toggle == true)



	{



		if (this.direction == Spry.forwards)



		{



			this.direction = Spry.backwards;



			this.notifyObservers('onToggle', this);



			this.currIdx = this.effectsArray.length;



		}



		else if (this.direction == Spry.backwards)



		{



			this.direction = Spry.forwards;



			this.currIdx = -1;



		}



	}



	else



	{



		if (this.direction == Spry.forwards)



			this.currIdx = -1;



		else if (this.direction == Spry.backwards)



			this.currIdx = this.effectsArray.length;



	}



};







Spry.Effect.Cluster.prototype.doToggle = function()



{



	this.toggleCluster();







	// toggle all effects of the cluster, too



	for (var i = 0; i < this.effectsArray.length; i++)



	{



		if (this.effectsArray[i].effect.options && (this.effectsArray[i].effect.options.toggle != null))



			if (this.effectsArray[i].effect.options.toggle == true)



				this.effectsArray[i].effect.doToggle();



	}



};







Spry.Effect.Cluster.prototype.cancel = function()



{



	for (var i = 0; i < this.effectsArray.length; i++)



		if (this.effectsArray[i].effect.isRunning)



			this.effectsArray[i].effect.cancel();



	



	var elapsed = this.getElapsedMilliseconds();



	if (this.startMilliseconds > 0 && elapsed < this.options.duration)



		this.cancelRemaining = this.options.transition(elapsed, 0, 1, this.options.duration);



	this.stopFlagReset();



	this.notifyObservers('onCancel', this);



	this.isRunning = false;



};







Spry.Effect.Cluster.prototype.addNextEffect = function(effect)



{



	effect.addObserver(this);



	this.effectsArray[this.effectsArray.length] = new this.ClusteredEffect(effect, "queue");



	if (this.effectsArray.length == 1)



	{



		// with the first added effect we know the element



		// that the cluster is working on



		this.element = effect.element;



	}



};







Spry.Effect.Cluster.prototype.addParallelEffect = function(effect)



{



	if (this.effectsArray.length == 0 || this.effectsArray[this.effectsArray.length-1].kind != 'parallel')



		effect.addObserver(this);







	this.effectsArray[this.effectsArray.length] = new this.ClusteredEffect(effect, "parallel");



	if (this.effectsArray.length == 1)



	{



		// with the first added effect we know the element



		// that the cluster is working on



		this.element = effect.element;



	}



};







Spry.Effect.Cluster.prototype.prepareStart = function()



{



	this.toggleCluster();



};







//////////////////////////////////////////////////////////////////////



//



// Combination effects



// Custom effects can be build by combining basic effect bahaviour



// like Move, Size, Color, Opacity



//



//////////////////////////////////////////////////////////////////////







Spry.Effect.Fade = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Fade');







	Spry.Effect.Cluster.call(this, options);







	this.name = 'Fade';



	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var durationInMilliseconds = 1000;



	var fromOpacity = 0.0;



	var toOpacity = 100.0;



	var doToggle = false;



	var transition = Spry.fifthTransition;



	var fps = 60;



	var originalOpacity = 0;



	if(/MSIE/.test(navigator.userAgent))



		originalOpacity = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(this.element, 'filter').replace(/alpha\(opacity=([0-9]{1,3})\)/g, '$1'), 10);



	else



		originalOpacity = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(this.element, 'opacity') * 100, 10);







	if (isNaN(originalOpacity))



		originalOpacity = 100;







	if (options)



	{



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.from != null){



			if (Spry.Effect.Utils.isPercentValue(options.from))



				fromOpacity = Spry.Effect.Utils.getPercentValue(options.from) * originalOpacity / 100;



			else



				fromOpacity = options.from;



		}



		if (options.to != null)



		{	



			if (Spry.Effect.Utils.isPercentValue(options.to))



				toOpacity = Spry.Effect.Utils.getPercentValue(options.to) * originalOpacity / 100;



			else



				toOpacity = options.to;



		}



		if (options.toggle != null) doToggle = options.toggle;



		if (options.transition != null) transition = options.transition;



		if (options.fps != null) fps = options.fps;



		else this.options.transition = transition;



	}







	fromOpacity = fromOpacity/ 100.0;



	toOpacity = toOpacity / 100.0;







	options = {duration: durationInMilliseconds, toggle: doToggle, transition: transition, from: fromOpacity, to: toOpacity, fps: fps};



	var fadeEffect = new Spry.Effect.Opacity(element, fromOpacity, toOpacity, options);



	this.addNextEffect(fadeEffect);



};







Spry.Effect.Fade.prototype = new Spry.Effect.Cluster();



Spry.Effect.Fade.prototype.constructor = Spry.Effect.Fade;







Spry.Effect.Blind = function (element, options)



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Blind'); 







	Spry.Effect.Cluster.call(this, options);







	this.name = 'Blind';



	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var durationInMilliseconds = 1000;



	var doToggle = false;



	var kindOfTransition = Spry.circleTransition;



	var fps = 60;



	var doScaleContent = false;







	Spry.Effect.makeClipping(element);







	var originalRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);



	var fromHeightPx  = originalRect.height;



	var toHeightPx    = 0;



	var optionFrom = options ? options.from : originalRect.height;



	var optionTo   = options ? options.to : 0;



	var fullCSSBox = false;











	if (options)



	{



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.from != null)



		{



			if (Spry.Effect.Utils.isPercentValue(options.from))



				fromHeightPx = Spry.Effect.Utils.getPercentValue(options.from) * originalRect.height / 100;



			else



				fromHeightPx = Spry.Effect.Utils.getPixelValue(options.from);



		}



		if (options.to != null)



		{



			if (Spry.Effect.Utils.isPercentValue(options.to))



				toHeightPx = Spry.Effect.Utils.getPercentValue(options.to) * originalRect.height / 100;



			else



				toHeightPx = Spry.Effect.Utils.getPixelValue(options.to);



		}



		if (options.toggle != null) doToggle = options.toggle;



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.fps != null) fps = options.fps;



		if (options.useCSSBox != null) fullCSSBox = options.useCSSBox;



	}







	var fromRect = new Spry.Effect.Utils.Rectangle;



	fromRect.width = originalRect.width;



	fromRect.height = fromHeightPx;







	var toRect = new Spry.Effect.Utils.Rectangle;



	toRect.width = originalRect.width;



	toRect.height = toHeightPx;







	options = {duration:durationInMilliseconds, toggle:doToggle, transition:kindOfTransition, scaleContent:doScaleContent, useCSSBox: fullCSSBox, from: optionFrom, to: optionTo, fps: fps};



	var blindEffect = new Spry.Effect.Size(element, fromRect, toRect, options);



	this.addNextEffect(blindEffect);



};







Spry.Effect.Blind.prototype = new Spry.Effect.Cluster();



Spry.Effect.Blind.prototype.constructor = Spry.Effect.Blind;







Spry.Effect.Highlight = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Highlight'); 







	Spry.Effect.Cluster.call(this, options);







	this.name = 'Highlight';



	var durationInMilliseconds = 1000;



	var toColor = "#ffffff";



	var doToggle = false;



	var kindOfTransition = Spry.sinusoidalTransition;



	var fps = 60;



	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var fromColor = Spry.Effect.getBgColor(element);



	if (fromColor == "transparent") fromColor = "#ffff99";







	if (options)



	{



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.from != null) fromColor = options.from;



		if (options.to != null) toColor = options.to;



		if (options.toggle != null) doToggle = options.toggle;



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.fps != null) fps = options.fps;



	}







	if ( fromColor.indexOf('rgb') != -1 )



		var fromColor = Spry.Effect.Utils.rgb(parseInt(fromColor.substring(fromColor.indexOf('(')+1, fromColor.indexOf(',')),10), parseInt(fromColor.substring(fromColor.indexOf(',')+1, fromColor.lastIndexOf(',')),10), parseInt(fromColor.substring(fromColor.lastIndexOf(',')+1, fromColor.indexOf(')')),10));







	if ( toColor.indexOf('rgb') != -1 )



		var toColor = Spry.Effect.Utils.rgb(parseInt(toColor.substring(toColor.indexOf('(')+1, toColor.indexOf(',')),10), parseInt(toColor.substring(toColor.indexOf(',')+1, toColor.lastIndexOf(',')),10), parseInt(toColor.substring(toColor.lastIndexOf(',')+1, toColor.indexOf(')')),10));







	var fromColor = Spry.Effect.Utils.longColorVersion(fromColor);



	var toColor = Spry.Effect.Utils.longColorVersion(toColor);







	this.restoreBackgroundImage = Spry.Effect.getStyleProp(element, 'background-image');







	options = {duration: durationInMilliseconds, toggle: doToggle, transition: kindOfTransition, fps: fps};



	var highlightEffect = new Spry.Effect.Color(element, fromColor, toColor, options);



	this.addNextEffect(highlightEffect);







	this.addObserver({



		onPreEffect:



		function(effect){



			Spry.Effect.setStyleProp(effect.element, 'background-image', 'none');



		},



		onPostEffect:



		function(effect){



			Spry.Effect.setStyleProp(effect.element, 'background-image', effect.restoreBackgroundImage);







			if (effect.direction == Spry.forwards && effect.options.restoreColor)



				Spry.Effect.setStyleProp(element, 'background-color', effect.options.restoreColor);		



		}



	});



};







Spry.Effect.Highlight.prototype = new Spry.Effect.Cluster();



Spry.Effect.Highlight.prototype.constructor = Spry.Effect.Highlight;







Spry.Effect.Slide = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Slide'); 







	Spry.Effect.Cluster.call(this, options);







	this.name = 'Slide';



	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var durationInMilliseconds = 1000;



	var doToggle = false;



	var kindOfTransition = Spry.sinusoidalTransition;



	var fps = 60;



	var slideHorizontally = false;



	var firstChildElt = Spry.Effect.Utils.getFirstChildElement(element);



	var direction = -1;







	// IE 7 does not clip static positioned elements -> make element position relative



	if(/MSIE 7.0/.test(navigator.userAgent) && /Windows NT/.test(navigator.userAgent))



		Spry.Effect.makePositioned(element);







	Spry.Effect.makeClipping(element);







	// for IE 6 on win: check if position is static or fixed -> not supported and would cause trouble



	if(/MSIE 6.0/.test(navigator.userAgent) && /Windows NT/.test(navigator.userAgent))



	{



		var pos = Spry.Effect.getStyleProp(element, 'position');



		if(pos && (pos == 'static' || pos == 'fixed'))



		{



			Spry.Effect.setStyleProp(element, 'position', 'relative');



			Spry.Effect.setStyleProp(element, 'top', '');



			Spry.Effect.setStyleProp(element, 'left', '');



		}



	}







	if(firstChildElt)



	{



		Spry.Effect.makePositioned(firstChildElt);



		Spry.Effect.makeClipping(firstChildElt);



  



		var childRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(firstChildElt, element);



		Spry.Effect.setStyleProp(firstChildElt, 'width', childRect.width + 'px');



	}







	var fromDim = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);







	var initDim = new Spry.Effect.Utils.Rectangle();



	var toDim = new Spry.Effect.Utils.Rectangle();



	initDim.width = toDim.width = fromDim.width;



	initDim.height = toDim.height = fromDim.height;







	if (!this.options.to){



		if (!options)



			options = {};







		options.to = '0%';



	}







	if (options && options.horizontal !== null && options.horizontal === true)



		slideHorizontally = true;







	if (options.duration != null) durationInMilliseconds = options.duration;







	if (options.from != null)



	{



		if(slideHorizontally)



		{



				if (Spry.Effect.Utils.isPercentValue(options.from))



					fromDim.width = initDim.width * Spry.Effect.Utils.getPercentValue(options.from) / 100;



				else



					fromDim.width = Spry.Effect.Utils.getPixelValue(options.from);



		}



		else



		{



				if (Spry.Effect.Utils.isPercentValue(options.from))



					fromDim.height = initDim.height * Spry.Effect.Utils.getPercentValue(options.from) / 100;



				else



					fromDim.height = Spry.Effect.Utils.getPixelValue(options.from);



		}



	}







	if (options.to != null)



	{



			if(slideHorizontally)



			{



				if (Spry.Effect.Utils.isPercentValue(options.to))



					toDim.width = initDim.width * Spry.Effect.Utils.getPercentValue(options.to) / 100;



				else



					toDim.width = Spry.Effect.Utils.getPixelValue(options.to);



			}



			else



			{



				if (Spry.Effect.Utils.isPercentValue(options.to))



					toDim.height = initDim.height * Spry.Effect.Utils.getPercentValue(options.to) / 100;



				else



					toDim.height = Spry.Effect.Utils.getPixelValue(options.to);



		}



	}



	if (options.toggle != null) doToggle = options.toggle;



	if (options.transition != null) kindOfTransition = options.transition;



	if (options.fps != null) fps = options.fps;







	options = {duration: durationInMilliseconds, transition: kindOfTransition, scaleContent: false, toggle:doToggle, fps: fps};



	var size = new Spry.Effect.Size(element, fromDim, toDim, options);



	this.addParallelEffect(size);







	if ( (fromDim.width < toDim.width && slideHorizontally) || (fromDim.height < toDim.height && !slideHorizontally))



		direction = 1;



	



	var fromPos = new Spry.Effect.Utils.Position();



	var toPos = new Spry.Effect.Utils.Position();



	toPos.x = fromPos.x = Spry.Effect.intPropStyle(firstChildElt, 'left');



	toPos.y = fromPos.y = Spry.Effect.intPropStyle(firstChildElt, 'top');



	toPos.units = fromPos.units;







	if (slideHorizontally)



		toPos.x = parseInt(fromPos.x + direction * (fromDim.width - toDim.width), 10);



	else



		toPos.y = parseInt(fromPos.y + direction * (fromDim.height - toDim.height), 10);







	if (direction == 1){



		var tmp = fromPos;



		var fromPos = toPos;



		var toPos = tmp;



	}







	options = {duration: durationInMilliseconds, transition: kindOfTransition, toggle:doToggle, from: fromPos, to: toPos, fps: fps};



	var move = new Spry.Effect.Move(firstChildElt, fromPos, toPos, options);



	this.addParallelEffect(move);



};







Spry.Effect.Slide.prototype = new Spry.Effect.Cluster();



Spry.Effect.Slide.prototype.constructor = Spry.Effect.Slide;







Spry.Effect.Grow = function (element, options) 



{



	if (!element)



		return;



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Grow');







	Spry.Effect.Cluster.call(this, options);







	this.name = 'Grow';



	var durationInMilliseconds = 1000;



	var doToggle = false;



	var doScaleContent = true;



	var calcHeight = false;



	var growFromCenter = true;



	var fullCSSBox = false;



	var kindOfTransition = Spry.squareTransition;



	var fps = 60;



	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;







	Spry.Effect.makeClipping(element);







	var dimRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);



	var originalWidth = dimRect.width;



	var originalHeight = dimRect.height;



	var propFactor = (originalWidth == 0) ? 1 :originalHeight/originalWidth;







	var fromRect = new Spry.Effect.Utils.Rectangle;



	fromRect.width = 0;



	fromRect.height = 0;







	var toRect = new Spry.Effect.Utils.Rectangle;



	toRect.width = originalWidth;



	toRect.height = originalHeight;







	var optionFrom = options ? options.from : dimRect.width;



	var optionTo   = options ? options.to : 0;



	var pixelValue = Spry.Effect.Utils.getPixelValue;







	if (options)



	{



		if (options.growCenter != null) growFromCenter = options.growCenter;



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.useCSSBox != null) fullCSSBox = options.useCSSBox;



		if (options.scaleContent != null) doScaleContent = options.scaleContent;



		if (options.from != null) 



		{



			if (Spry.Effect.Utils.isPercentValue(options.from))



			{



				fromRect.width = originalWidth * (Spry.Effect.Utils.getPercentValue(options.from) / 100);



				fromRect.height = originalHeight * (Spry.Effect.Utils.getPercentValue(options.from) / 100);



			}



			else



			{



				if(calcHeight)



				{



					fromRect.height = pixelValue(options.from);



					fromRect.width  = pixelValue(options.from) / propFactor;



				}



				else



				{



					fromRect.width = pixelValue(options.from);



					fromRect.height = propFactor * pixelValue(options.from);



				}



			}



		}



		if (options.to != null)



		{



			if (Spry.Effect.Utils.isPercentValue(options.to))



			{



				toRect.width = originalWidth * (Spry.Effect.Utils.getPercentValue(options.to) / 100);



				toRect.height = originalHeight * (Spry.Effect.Utils.getPercentValue(options.to) / 100);



			}



			else



			{



				if(calcHeight)



				{



					toRect.height = pixelValue(options.to);



					toRect.width  = pixelValue(options.to) / propFactor;



				}



				else



				{



					toRect.width = pixelValue(options.to);



					toRect.height = propFactor * pixelValue(options.to);



				}



			}



		}



		if (options.toggle != null) doToggle = options.toggle;



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.fps != null) fps = options.fps;



	}







	options = {duration:durationInMilliseconds, toggle:doToggle, transition:kindOfTransition, scaleContent:doScaleContent, useCSSBox: fullCSSBox, fps: fps};



	var sizeEffect = new Spry.Effect.Size(element, fromRect, toRect, options);



	this.addParallelEffect(sizeEffect);







	if(growFromCenter)



	{



		Spry.Effect.makePositioned(element);







		var startOffsetPosition = new Spry.Effect.Utils.Position();



		startOffsetPosition.x = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(element, "left"), 10);



		startOffsetPosition.y = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(element, "top"), 10);	



		if (!startOffsetPosition.x) startOffsetPosition.x = 0;



		if (!startOffsetPosition.y) startOffsetPosition.y = 0;







		options = {duration:durationInMilliseconds, toggle:doToggle, transition:kindOfTransition, from: optionFrom, to: optionTo, fps: fps};



		var fromPos = new Spry.Effect.Utils.Position;



		fromPos.x = startOffsetPosition.x + (originalWidth - fromRect.width) / 2.0;



		fromPos.y = startOffsetPosition.y + (originalHeight - fromRect.height) / 2.0;







		var toPos = new Spry.Effect.Utils.Position;



		toPos.x = startOffsetPosition.x + (originalWidth - toRect.width) / 2.0;



		toPos.y = startOffsetPosition.y + (originalHeight - toRect.height) / 2.0;







		var moveEffect = new Spry.Effect.Move(element, fromPos, toPos, options);



		this.addParallelEffect(moveEffect);



	}



};







Spry.Effect.Grow.prototype = new Spry.Effect.Cluster();



Spry.Effect.Grow.prototype.constructor = Spry.Effect.Grow;







Spry.Effect.Shake = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Shake'); 







	Spry.Effect.Cluster.call(this, options);







	// toggle is not supported



	this.options.direction = false;



	if (this.options.toggle)



		this.options.toggle = false;







	this.name = 'Shake';







	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var durationInMilliseconds = 100;



	var kindOfTransition = Spry.linearTransition;



	var fps = 60;



	var steps = 4;







	if (options)



	{



		if (options.duration != null) steps = Math.ceil(this.options.duration / durationInMilliseconds) - 1;



		if (options.fps != null) fps = options.fps;



		if (options.transition != null) kindOfTransition = options.transition;



	}







	Spry.Effect.makePositioned(element);



	



	var startOffsetPosition = new Spry.Effect.Utils.Position();



	startOffsetPosition.x = parseInt(Spry.Effect.getStyleProp(element, "left"), 10);



	startOffsetPosition.y = parseInt(Spry.Effect.getStyleProp(element, "top"), 10);



	if (!startOffsetPosition.x) startOffsetPosition.x = 0;



	if (!startOffsetPosition.y) startOffsetPosition.y = 0;







	var centerPos = new Spry.Effect.Utils.Position;



	centerPos.x = startOffsetPosition.x;



	centerPos.y = startOffsetPosition.y;







	var rightPos = new Spry.Effect.Utils.Position;



	rightPos.x = startOffsetPosition.x + 20;



	rightPos.y = startOffsetPosition.y + 0;







	var leftPos = new Spry.Effect.Utils.Position;



	leftPos.x = startOffsetPosition.x + -20;



	leftPos.y = startOffsetPosition.y + 0;







	options = {duration:Math.ceil(durationInMilliseconds / 2), toggle:false, fps: fps, transition: kindOfTransition};



	var effect = new Spry.Effect.Move(element, centerPos, rightPos, options);



	this.addNextEffect(effect);







	options = {duration:durationInMilliseconds, toggle:false, fps:fps, transition: kindOfTransition};



	var effectToRight = new Spry.Effect.Move(element, rightPos, leftPos, options);



	var effectToLeft = new Spry.Effect.Move(element, leftPos, rightPos, options);







	for (var i=0; i < steps; i++)



	{



		if (i % 2 == 0)



			this.addNextEffect(effectToRight);



		else



			this.addNextEffect(effectToLeft);



	}



	var pos = (steps % 2 == 0) ? rightPos: leftPos;







	options = {duration:Math.ceil(durationInMilliseconds / 2), toggle:false, fps: fps, transition: kindOfTransition};



	var effect = new Spry.Effect.Move(element, pos, centerPos, options);



	this.addNextEffect(effect);



};



Spry.Effect.Shake.prototype = new Spry.Effect.Cluster();



Spry.Effect.Shake.prototype.constructor = Spry.Effect.Shake;



Spry.Effect.Shake.prototype.doToggle = function(){};







Spry.Effect.Squish = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Squish');







	if (!options)



		options = {};



	if (!options.to)



		options.to = '0%';



	if (!options.from)



		options.from = '100%';







	options.growCenter = false;



	Spry.Effect.Grow.call(this, element, options);



	this.name = 'Squish';



};



Spry.Effect.Squish.prototype = new Spry.Effect.Grow();



Spry.Effect.Squish.prototype.constructor = Spry.Effect.Squish;







Spry.Effect.Pulsate = function (element, options) 



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Pulsate');







	Spry.Effect.Cluster.call(this, options);







	// toggle is not supported



	this.options.direction = false;



	if (this.options.toggle)



		this.options.toggle = false;







	var element = Spry.Effect.getElement(element);



	var originalOpacity = 0;



	this.element = element;



	if (!this.element)



		return;







	this.name = 'Pulsate';



	var durationInMilliseconds = 100;



	var fromOpacity = 100.0;



	var toOpacity = 0.0;



	var doToggle = false;



	var kindOfTransition = Spry.linearTransition;



	var fps = 60;



	if(/MSIE/.test(navigator.userAgent))



		originalOpacity = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(this.element, 'filter').replace(/alpha\(opacity=([0-9]{1,3})\)/g, '$1'), 10);



	else



		originalOpacity = parseInt(Spry.Effect.getStylePropRegardlessOfDisplayState(this.element, 'opacity') * 100, 10);







	if (isNaN(originalOpacity)){



		originalOpacity = 100;



	}







	if (options)



	{



		if (options.from != null){



			if (Spry.Effect.Utils.isPercentValue(options.from))



				fromOpacity = Spry.Effect.Utils.getPercentValue(options.from) * originalOpacity / 100;



			else



				fromOpacity = options.from;



		}



		if (options.to != null)



		{	



			if (Spry.Effect.Utils.isPercentValue(options.to))



				toOpacity = Spry.Effect.Utils.getPercentValue(options.to) * originalOpacity / 100;



			else



				toOpacity = options.to;



		}



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.fps != null) fps = options.fps;



	}







	options = {duration:durationInMilliseconds, toggle:doToggle, transition:kindOfTransition, fps:fps};



	fromOpacity = fromOpacity / 100.0;



	toOpacity = toOpacity / 100.0;







	var fadeEffect = new Spry.Effect.Opacity(element, fromOpacity, toOpacity, options);



	var appearEffect = new Spry.Effect.Opacity(element, toOpacity, fromOpacity, options);



	var steps = parseInt(this.options.duration / 200, 10);



	for (var i=0; i < steps; i++){ 



		this.addNextEffect(fadeEffect);



		this.addNextEffect(appearEffect);



	}



};



Spry.Effect.Pulsate.prototype = new Spry.Effect.Cluster();



Spry.Effect.Pulsate.prototype.constructor = Spry.Effect.Pulsate;



Spry.Effect.Pulsate.prototype.doToggle = function(){};







Spry.Effect.Puff = function (element, options)



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Puff'); 







	Spry.Effect.Cluster.call(this, options);







	var element = Spry.Effect.getElement(element);



	this.element = element;	



	if (!this.element)



		return;



	this.name = 'Puff';



	var doToggle = false;



	var doScaleContent = false;



	var durationInMilliseconds = 1000;



	var kindOfTransition = Spry.fifthTransition;



	var fps = 60;







	Spry.Effect.makePositioned(element); // for move







	if (options){



		if (options.toggle != null) doToggle = options.toggle;



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.fps != null) fps = options.fps;



	}



	var originalRect = Spry.Effect.getDimensions(element);



	var startWidth = originalRect.width;



	var startHeight = originalRect.height;







	options = {duration:durationInMilliseconds, toggle:doToggle, transition: kindOfTransition, fps: fps};







	var fromOpacity = 1.0;



	var toOpacity = 0.0;



	var opacityEffect = new Spry.Effect.Opacity(element, fromOpacity, toOpacity, options);



	this.addParallelEffect(opacityEffect);







	var fromPos = Spry.Effect.getPosition(element);







	var toPos = new Spry.Effect.Utils.Position;



	toPos.x = startWidth / 2.0 * -1.0;



	toPos.y = startHeight / 2.0 * -1.0;







	options = {duration:durationInMilliseconds, toggle:doToggle, transition:kindOfTransition, from: fromPos, to: toPos, fps: fps};



	var moveEffect = new Spry.Effect.Move(element, fromPos, toPos, options);



	this.addParallelEffect(moveEffect);







	var self = this;



	this.addObserver({



		onPreEffect:function(){if (self.direction == Spry.backwards){self.element.style.display = 'block';}},



		onPostEffect: function(){if (self.direction == Spry.forwards){self.element.style.display = 'none';}}



	});



};



Spry.Effect.Puff.prototype = new Spry.Effect.Cluster;



Spry.Effect.Puff.prototype.constructor = Spry.Effect.Puff;







Spry.Effect.DropOut = function (element, options)



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('DropOut');







	Spry.Effect.Cluster.call(this, options);







	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	var durationInMilliseconds = 1000;



	var fps = 60;



	var kindOfTransition = Spry.fifthTransition;



	var direction = Spry.forwards;



	var doToggle = false;



	this.name = 'DropOut';







	Spry.Effect.makePositioned(element);







	if (options)



	{



		if (options.duration != null) durationInMilliseconds = options.duration;



		if (options.toggle != null) doToggle = options.toggle;



		if (options.fps != null) fps = options.fps;



		if (options.transition != null) kindOfTransition = options.transition;



		if (options.dropIn != null) direction = -1;



	}







	var startOffsetPosition = new Spry.Effect.Utils.Position();



	startOffsetPosition.x = parseInt(Spry.Effect.getStyleProp(element, "left"), 10);



	startOffsetPosition.y = parseInt(Spry.Effect.getStyleProp(element, "top"), 10);	



	if (!startOffsetPosition.x) startOffsetPosition.x = 0;



	if (!startOffsetPosition.y) startOffsetPosition.y = 0;







	var fromPos = new Spry.Effect.Utils.Position;



	fromPos.x = startOffsetPosition.x + 0;



	fromPos.y = startOffsetPosition.y + 0;







	var toPos = new Spry.Effect.Utils.Position;



	toPos.x = startOffsetPosition.x + 0;



	toPos.y = startOffsetPosition.y + (direction * 160);







	options = {from:fromPos, to:toPos, duration:durationInMilliseconds, toggle:doToggle, transition: kindOfTransition, fps: fps};



	var moveEffect = new Spry.Effect.Move(element, options.from, options.to, options);



	this.addParallelEffect(moveEffect);







	var fromOpacity = 1.0;



	var toOpacity = 0.0;



	options = {duration:durationInMilliseconds, toggle:doToggle, transition: kindOfTransition, fps: fps};



	var opacityEffect = new Spry.Effect.Opacity(element, fromOpacity, toOpacity, options);



	this.addParallelEffect(opacityEffect);







	var self = this;



	this.addObserver({



		onPreEffect:function(){self.element.style.display = 'block';},



		onPostEffect: function(){if (self.direction == Spry.forwards){self.element.style.display = 'none';}}



	});







};



Spry.Effect.DropOut.prototype = new Spry.Effect.Cluster();



Spry.Effect.DropOut.prototype.constructor = Spry.Effect.DropOut;







Spry.Effect.Fold = function (element, options)



{



	if (!this.notStaticAnimator)



		return Spry.Effect.Utils.showInitError('Fold');







	Spry.Effect.Cluster.call(this, options);







	var element = Spry.Effect.getElement(element);



	this.element = element;



	if (!this.element)



		return;



	this.name = 'Fold';



	var durationInMilliseconds = 1000;



	var doToggle = false;



	var doScaleContent = true;



	var fullCSSBox = false;



	var kindOfTransition = Spry.fifthTransition;



	var fps = fps;



	



	Spry.Effect.makeClipping(element);







	var originalRect = Spry.Effect.getDimensionsRegardlessOfDisplayState(element);



	var startWidth = originalRect.width;



	var startHeight = originalRect.height;







	var stopWidth = startWidth;



	var stopHeight = startHeight / 5;







	var fromRect = new Spry.Effect.Utils.Rectangle;



	fromRect.width = startWidth;



	fromRect.height = startHeight;







	var toRect = new Spry.Effect.Utils.Rectangle;



	toRect.width = stopWidth;



	toRect.height = stopHeight;







	if (options)



	{



		if (options.duration != null) durationInMilliseconds = Math.ceil(options.duration/2);



		if (options.toggle != null) doToggle = options.toggle;



		if (options.useCSSBox != null) fullCSSBox = options.useCSSBox; 



		if (options.fps != null) fps = options.fps;



		if (options.transition != null) kindOfTransition = options.transition;



	}







	options = {duration:durationInMilliseconds, toggle:doToggle, scaleContent:doScaleContent, useCSSBox: fullCSSBox, transition: kindOfTransition, fps: fps};



	var sizeEffect = new Spry.Effect.Size(element, fromRect, toRect, options);



	this.addNextEffect(sizeEffect);







	fromRect.width = toRect.width;



	fromRect.height = toRect.height;



	toRect.width = '0%';



	var sizeEffect = new Spry.Effect.Size(element, fromRect, toRect, options);



	this.addNextEffect(sizeEffect);



};







Spry.Effect.Fold.prototype = new Spry.Effect.Cluster();



Spry.Effect.Fold.prototype.constructor = Spry.Effect.Fold;







//////////////////////////////////////////////////////////////



// 																													//



// The names of some of the static effect functions 		 		//



// changed in Spry 1.5. These wrappers will insure that we 	//



// remain compatible with previous versions of Spry.				//



// 																													//



//////////////////////////////////////////////////////////////







Spry.Effect.DoFade = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Fade', element, options);



};







Spry.Effect.DoBlind = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Blind', element, options);



};







Spry.Effect.DoHighlight = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Highlight', element, options);



};







Spry.Effect.DoSlide = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Slide', element, options);



};







Spry.Effect.DoGrow = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Grow', element, options);



};







Spry.Effect.DoShake = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Shake', element, options);



};







Spry.Effect.DoSquish = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Squish', element, options);



};







Spry.Effect.DoPulsate = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Pulsate', element, options);



};







Spry.Effect.DoPuff = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Puff', element, options);



};







Spry.Effect.DoDropOut = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('DropOut', element, options);



};







Spry.Effect.DoFold = function (element, options)



{



	return Spry.Effect.Utils.DoEffect('Fold', element, options);



};



