/*
 Script: Moo.js
	My Object Oriented javascript.
	
 Dependancies:
 Has no dependancies.
	
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 
 Credits:
	- Class is slightly based on Base.js  <http://dean.edwards.name/weblog/2006/03/base/> (c) 2006 Dean Edwards, License <http://creativecommons.org/licenses/LGPL/2.1/>
	- Some functions are based on those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
	- Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti.
 */

/*
 Class: Class
	The base class object of the <http://mootools.net> framework.
	
 Arguments:
	properties - the collection of properties that apply to the class. Creates a new class, its initialize method will fire upon class instantiation.
	
 Example:
	>var Cat = new Class({
		>	initialize: function(name){
			>		this.name = name;
			>	}
		>});
	>var myCat = new Cat('Micia');
	>alert myCat.name; //alerts 'Micia'
 */

var Class = function(properties){
	var klass = function(){
		for (var p in this){
			if (this[p]) this[p]._proto_ = this;
		}
		if (arguments[0] != 'noinit' && this.initialize) return this.initialize.apply(this, arguments);
	};
	klass.extend = this.extend;
	klass.implement = this.implement;
	klass.prototype = properties;
	return klass;
};

/*
 Property: empty
	Returns an empty function
 */

Class.empty = function(){};

/*
 Property: create
	same as new Class. see <Class>
 */

Class.create = function(properties){
	return new Class(properties);
};

Class.prototype = {
	
	/*
	 Property: extend
	 Returns the copy of the Class extended with the passed in properties.
	 
	 Arguments:
	 properties - the properties to add to the base class in this new Class.
	 
	 Example:
	 >var Animal = new Class({
		 >	initialize: function(age){
			 >		this.age = age;
			 >	}
		 >});
	 >var Cat = Animal.extend({
		 >	initialize: function(name, age){
			 >		this.parent(age); //will call the previous initialize;
			 >		this.name = name;
			 >	}
		 >});
	 >var myCat = new Cat('Micia', 20);
	 >alert myCat.name; //alerts 'Micia'
	 >alert myCat.age; //alerts 20
	 */
	
extend: function(properties){
	var pr0t0typ3 = new this('noinit');
	for (var property in properties){
		var previous = pr0t0typ3[property];
		var current = properties[property];
		if (previous && previous != current) current = previous.parentize(current) || current;
		pr0t0typ3[property] = current;
	}
	return new Class(pr0t0typ3);
},

/*	
Property: implement
 Implements the passed in properties to the base Class prototypes, altering the base class, unlike <Class.extend>.
 
	Arguments:
 properties - the properties to add to the base class.
 
	Example:
 >var Animal = new Class({
	 >	initialize: function(age){
		 >		this.age = age;
		 >	}
	 >});
 >Animal.implement({
	 >	setName: function(name){
		 >		this.name = name
		 >	}
	 >});
 >var myAnimal = new Animal(20);
 >myAnimal.setName('Micia');
 >alert(myAnimal.name); //alerts 'Micia'
	*/

implement: function(properties){
	for (var property in properties) this.prototype[property] = properties[property];
}

};

/* Section: Object related Functions  */

/*
 Function: Object.extend
	Copies all the properties from the second passed object to the first passed Object.
	If you do myWhatever.extend = Object.extend the first parameter will become myWhatever, and your extend function will only need one parameter.
 
 Example:
	>var firstOb = {
		>	'name': 'John',
		>	'lastName': 'Doe'
		>};
	>var secondOb = {
		>	'age': '20',
		>	'sex': 'male',
		>	'lastName': 'Dorian'
		>};
	>Object.extend(firstOb, secondOb);
	>//firstOb will become: 
	>{
		>	'name': 'John',
		>	'lastName': 'Dorian',
		>	'age': '20',
		>	'sex': 'male'
		>};
	
 Returns:
	The first object, extended.
 */

Object.extend = function(){
	var args = arguments;
	if (args[1]) args = [args[0], args[1]];
	else args = [this, args[0]];
	for (var property in args[1]) args[0][property] = args[1][property];
	return args[0];
};

/*
 Function: Object.Native
	Will add a .extend method to the objects passed as a parameter, equivalent to <Class.implement>
 
 Arguments:
	a number of classes/native javascript objects
 
 */

Object.Native = function(){
	for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement;
};

new Object.Native(Function, Array, String, Number);

Function.extend({
	
parentize: function(current){
	var previous = this;
	return function(){
		this.parent = previous;
		return current.apply(this, arguments);
	};
}

});
/* 
Script: Function.js
	Contains Function prototypes, utility functions and Chain.
 
 Dependencies: 
	<Moo.js>
 
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 
 Credits:
	- Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
 */

/*
 Class: Function
	A collection of The Function Object prototype methods.
 */

Function.extend({
	
	/*
	 Property: pass
	 Shortcut to create closures with arguments and bind.
	 
	 Returns:
	 a function.
	 
	 Arguments:
	 args - the arguments to pass to that function (array or single variable)
	 bind - optional, the object that the "this" of the function will refer to.
	 
	 Example:
	 >myFunction.pass([arg1, arg2], myElement);
	 */
	
pass: function(args, bind){
	var fn = this;
	if ($type(args) != 'array') args = [args];
	return function(){
		return fn.apply(bind || fn._proto_ || fn, args);
	};
},

/*
	Property: bind
 method to easily create closures with "this" altered.
	
	Arguments:
 bind - optional, the object that the "this" of the function will refer to.
	
	Returns:
 a function.
	
	Example:
 >function myFunction(){
	 >	this.setStyle('color', 'red');
	 >	// note that 'this' here refers to myFunction, not an element
		 >	// we'll need to bind this function to the element we want to alter
		 >};
 >var myBoundFunction = myFunction.bind(myElement);
 >myBoundFunction(); // this will make the element myElement red.
	*/

bind: function(bind){
	var fn = this;
	return function(){
		return fn.apply(bind, arguments);
	};
},

/*
	Property: bindAsEventListener
 cross browser method to pass event firer
	
	Arguments:
 bind - optional, the object that the "this" of the function will refer to.
	
	Returns:
 a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser.
	
	Example:
 >function myFunction(event){
	 >	alert(event.clientx) //returns the coordinates of the mouse..
	 >};
 >myElement.onclick = myFunction.bindAsEventListener(myElement);
	*/

bindAsEventListener: function(bind){
	var fn = this;
	return function(event){
		fn.call(bind, event || window.event);
		return false;
	};
},

/*
	Property: delay
 Delays the execution of a function by a specified duration.
	
	Arguments:
 ms - the duration to wait in milliseconds
 bind - optional, the object that the "this" of the function will refer to.
	
	Example:
 >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it
 >(function(){alert('one second later...')}).delay(1000); //wait a second and alert
	*/

delay: function(ms, bind){
	return setTimeout(this.bind(bind || this._proto_ || this), ms);
},

/*
	Property: periodical
 Executes a function in the specified intervals of time
 
	Arguments:
 ms - the duration of the intervals between executions.
 bind - optional, the object that the "this" of the function will refer to.
	*/

periodical: function(ms, bind){
	return setInterval(this.bind(bind || this._proto_ || this), ms);
}

});

/* Section: Utility Functions  */

/*
 Function: $clear
	clears a timeout or an Interval.
 
 Returns:
	null
 
 Arguments:
	timer - the setInterval or setTimeout to clear.
 
 Example:
	>var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function.
	>myTimer = $clear(myTimer); //nevermind
 
 See also:
	<Function.delay>, <Function.periodical>
 */

function $clear(timer){
	clearTimeout(timer);
	clearInterval(timer);
	return null;
};

/*
 Function: $type
	Returns the type of object that matches the element passed in.
 
 Arguments:
	obj - the object to inspect.
 
 Example:
	>var myString = 'hello';
	>$type(myString); //returns "string"
 
 Returns:
	'function' - if obj is a function
	'textnode' - if obj is a node but not an element
	'element' - if obj is a DOM element
	'array' - if obj is an array
	'object' - if obj is an object
	'string' - if obj is a string
	'number' - if obj is a number
	false - (boolean) if the object is not defined or none of the above, or if it's an empty string.
 */

function $type(obj){
	if (!obj) return false;
	var type = false;
	if (obj instanceof Function) type = 'function';
	else if (obj.nodeName){
		if (obj.nodeType == 3 && !/\S/.test(obj.nodeValue)) type = 'textnode';
		else if (obj.nodeType == 1) type = 'element';
	}
	else if (obj instanceof Array) type = 'array';
	else if (typeof obj == 'object') type = 'object';
	else if (typeof obj == 'string') type = 'string';
	else if (typeof obj == 'number' && isFinite(obj)) type = 'number';
	return type;
};

/*Class: Chain*/

var Chain = new Class({
	
	/*
	 Property: chain
	 adds a function to the Chain instance stack.
	 
	 Arguments:
	 fn - the function to append.
	 
	 Returns:
	 the instance of the <Chain> class.
	 
	 Example:
	 >var myChain = new Chain();
	 >myChain.chain(myFunction).chain(myFunction2);
	 */
	
chain: function(fn){
	this.chains = this.chains || [];
	this.chains.push(fn);
	return this;
},

/*
	Property: callChain
 Executes the first function of the Chain instance stack, then removes it. The first function will then become the second.
 
	Example:
 >myChain.callChain(); //executes myFunction
 >myChain.callChain(); //executes myFunction2
	*/

callChain: function(){
	if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this);
},

/*
	Property: clearChain
 Clears the stack of a Chain instance.
	*/

clearChain: function(){
	this.chains = [];
}

});
/*
 Script: Array.js
	Contains Array prototypes and the function <$A>;
 
 Dependencies:
	<Moo.js>
	
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 */

/*
 Class: Array
	A collection of The Array Object prototype methods.
 */

if (!Array.prototype.forEach){
	
	/*	
Mehod: forEach
	 Iterates through an array; note: <Array.each> is the preferred syntax for this funciton.
	 
	 Arguments:
	 fn - the function to execute with each item in the array
	 bind - optional, the object that the "this" of the function will refer to.
	 
	 Example:
	 >var Animals = ['Cat', 'Dog', 'Coala'];
	 >Animals.forEach(function(animal){
		 >	document.write(animal)
		 >});
	 
	 See also:
	 <Function.bind>
	 <Array.each>
	 */
	
	Array.prototype.forEach = function(fn, bind){
		for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
	};
}

Array.extend({
	
	/*
	 Property: each
	 Same as <Array.each>.
	 */
	
each: Array.prototype.forEach,
	
	/*	
Property: copy
	 Copy the array and returns it.
	 
	 Returns:
	 an Array
	 
	 Example:
	 >var letters = ["a","b","c"];
	 >var copy = ["a","b","c"].copy();
	 */
	
copy: function(){
	var newArray = [];
	for (var i = 0; i < this.length; i++) newArray.push(this[i]);
	return newArray;
},

/*	
Property: remove
 Removes an item from the array.
 
	Arguments:
 item - the item to remove
 
	Returns:
 the Array without the item removed.
 
	Example:
 >["1","2","3"].remove("2") // ["1","3"];
	*/

remove: function(item){
	for (var i = 0; i < this.length; i++){
		if (this[i] == item) this.splice(i, 1);
	}
	return this;
},

/*	
Property: test
 Tests an array for the presence of an item.
 
	Arguments:
 item - the item to search for in the array.
 
	Returns:
 true - the item was found
 false - it wasn't
 
	Example:
 >["a","b","c"].test("a"); // true
 >["a","b","c"].test("d"); // false
	*/

test: function(item){
	for (var i = 0; i < this.length; i++){
		if (this[i] == item) return true;
	};
	return false;
},

/*	
Property: extend
 Extends an array with another
 
	Arguments:
 newArray - the array to extend ours with
 
	Example:
 >var Animals = ['Cat', 'Dog', 'Coala'];
 >Animals.extend(['Lizard']);
 >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard'];
	*/

extend: function(newArray){
	for (var i = 0; i < newArray.length; i++) this.push(newArray[i]);
	return this;
},

/*	
Property: associate
 Creates an associative array based on the array of keywords passed in.
 
	Arguments:
 keys - the array of keywords.
 
	Example:
 (sart code)
 var Animals = ['Cat', 'Dog', 'Coala', 'Lizard'];
 var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute'];
 var Speeches = Animals.associate(speech);
 //Speeches['Miao'] is now Cat.
 //Speeches['Bau'] is now Dog.
 //...
 (end)
	*/

associate: function(keys){
	var newArray = [];
	for (var i =0; i < this.length; i++) newArray[keys[i]] = this[i];
	return newArray;
}

});

/* Section: Utility Functions  */

/*
 Function: $A()
	Same as <Array.copy>, but as function. 
	Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object.
	
 Example:
	>function myFunction(){
		>	$A(arguments).each(argument, function(){
			>		alert(argument);
			>	});
		>};
	>//the above will alert all the arguments passed to the function myFunction.
 */

function $A(array){
	return Array.prototype.copy.call(array);
};
/*
 Script: String.js
	Contains String prototypes and Number prototypes.
 
 Dependencies:
	<Moo.js>
	
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 */

/*
 Class: String
	A collection of The String Object prototype methods.
 */

String.extend({
	
	/*	
Property: test
	 Tests a string with a regular expression.
	 
	 Arguments:
	 regex - the regular expression you want to match the string with
	 params - optional, any parameters you want to pass to the regex
	 
	 Returns:
	 an array with the instances of the value searched for or empty array.
	 
	 Example:
	 >"I like cookies".test("cookie"); // returns ["I like cookies", "cookie"]
	 >"I like cookies".test("COOKIE", "i") //ignore case
	 >"I like cookies because cookies are good".test("COOKIE", "ig"); //ignore case, find all instances.
	 >"I like cookies".test("cake"); //returns empty array
	 */
	
test: function(regex, params){
	return this.match(new RegExp(regex, params));
},

/*	
Property: toInt
 parses a string to an integer.
 
 Returns:
 either an int or "NaN" if the string is not a number.
 
 Example:
 >var value = "10px".toInt(); // value is 10
	*/
toInt: function(){
	return parseInt(this);
},

/*	
Property: camelCase
 Converts a hiphenated string to a camelcase string.
 
	Example:
 >"I-like-cookies".camelCase(); //"ILikeCookies"
 
	Returns:
 the camel cased string
	*/

camelCase: function(){
	return this.replace(/-\D/gi, function(match){
		return match.charAt(match.length - 1).toUpperCase();
	});
},

/*	
Property: capitalize
 Converts the first letter in each word of a string to Uppercase.
 
	Example:
 >"i like cookies".capitalize(); //"I Like Cookies"
 
	Returns:
 the capitalized string
	*/
capitalize: function(){
	return this.toLowerCase().replace(/\b[a-z]/g, function(match){
		return match.toUpperCase();
	});
},

/*	
Property: trim
 Trims the leading and trailing spaces off a string.
 
	Example:
 >"    i like cookies     ".trim() //"i like cookies"
 
	Returns:
 the trimmed string
	*/

trim: function(){
	return this.replace(/^\s*|\s*$/g, '');
},

/*	
Property: clean
 trims (<String.trim>) a string AND removes all the double spaces in a string.
 
	Returns:
 the cleaned string
 
	Example:
 >" i      like     cookies      \n\n".clean() //"i like cookies"
	*/

clean: function(){
	return this.replace(/\s\s/g, ' ').trim();
},

/*	
Property: rgbToHex
 Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255, 255, 255)" or "rgba(255, 255, 255, 1)";
 
	Arguments:
 array - boolean value, defaults to false. Use true if you want the array ['FF', '33', '00'] as output instead of #FF3300
 
	Returns:
 hex string or array. returns transparent if the fourth value of rgba in input string is 0,
 
	Example:
 >"rgb(17,34,51)".rgbToHex(); //"#112233"
 >"rgba(17,34,51,0)".rgbToHex(); //"transparent"
 >"rgb(17,34,51)".rgbToHex(true); //[11,22,33]
	*/

rgbToHex: function(array){
	var rgb = this.test('([\\d]{1,3})', 'g');
	if (rgb[3] == 0) return 'transparent';
	var hex = [];
	for (var i = 0; i < 3; i++){
		var bit = (rgb[i]-0).toString(16);
		hex.push(bit.length == 1 ? '0'+bit : bit);
	}
	var hexText = '#'+hex.join('');
	if (array) return hex;
	else return hexText;
},

/*	
Property: hexToRgb
 Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333');
 
	Arguments:
 array - boolean value, defaults to false. Use true if you want the array ['255', '255', '255'] as output instead of "rgb(255,255,255)";
 
	Returns:
 rgb string or array.
 
	Example:
 >"#112233".hexToRgb(); //"rgb(17,34,51)"
 >"#112233".hexToRgb(true); //[17,34,51]
	*/

hexToRgb: function(array){
	var hex = this.test('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$');
	var rgb = [];
	for (var i = 1; i < hex.length; i++){
		if (hex[i].length == 1) hex[i] += hex[i];
		rgb.push(parseInt(hex[i], 16));
	}
	var rgbText = 'rgb('+rgb.join(',')+')';
					   if (array) return rgb;
					   else return rgbText;
	}

});

/*
 Class: Number
	contains the internal method toInt.
 */

Number.extend({
	
	/*
	 Property: toInt
	 Returns this number; useful because toInt must work on both Strings and Numbers.
	 */
	
toInt: function(){
	return this;
}

});
/*
 Script: Element.js
	Contains useful Element prototypes, to be used with the dollar function <$>.
	
 Dependencies:
	<Moo.js>, <Function.js>, <Array.js>, <String.js>
 
 Author:
	Valerio Proietti, <http://mad4milk.net>
	
 License:
	MIT-style license.
	
 Credits:
	- Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
 */

/*
 Class: Element
	Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
 */

var Element = new Class({
	
	/*
	 Property: initialize
	 Creates a new element of the type passed in.
	 
	 Arguments:
	 el - the tag name for the element you wish to create.
	 
	 Example:
	 >var div = new Element('div');
	 */
	
initialize: function(el){
	if ($type(el) == 'string') el = document.createElement(el);
	return $(el);
},

inject: function(el, where){
	el = $(el) || new Element(el);
	switch(where){
		case "before": $(el.parentNode).insertBefore(this, el); break;
		case "after": {
			if (!el.getNext()) $(el.parentNode).appendChild(this);
			else $(el.parentNode).insertBefore(this, el.getNext());
		} break;
		case "inside": el.appendChild(this); break;
	}
	return this;
},

/*
	Property: injectBefore
 Inserts the Element before the passed element.
 
	Parameteres:
 el - a string representing the element to be injected in (myElementId, or div), or an element reference.
 If you pass div or another tag, the element will be created.
 
	Example:
 >html: 
 ><div id="myElement"></div>
 ><div id="mySecondElement"></div>
 >js:
 >$('mySecondElement').injectBefore('myElement');
 >resulting html
 ><div id="myElement"></div>
 ><div id="mySecondElement"></div>
 
	*/

injectBefore: function(el){
	return this.inject(el, 'before');
},

/*  
Property: injectAfter
Same as <Element.injectBefore>, but inserts the element after.
*/

injectAfter: function(el){
	return this.inject(el, 'after');
},

/*  
Property: injectInside
Same as <Element.injectBefore>, but inserts the element inside.
*/

injectInside: function(el){
	return this.inject(el, 'inside');
},

/*  
Property: adopt
Inserts the passed element inside the Element. Works as <Element.injectInside> but in reverse.

Parameteres:
el - a string representing the element to be injected in (myElementId, or div), or an element reference.
If you pass div or another tag, the element will be created.
*/

adopt: function(el){
	this.appendChild($(el) || new Element(el));
	return this;
},

/*  
Property: remove
Removes the Element from the DOM.

Example:
>$('myElement').remove() //bye bye
*/

remove: function(){
	this.parentNode.removeChild(this);
},

/*  
Property: clone
Clones the Element and returns the cloned one.

Returns: 
the cloned element

Example:
>var clone = $('myElement').clone().injectAfter('myElement');
>//clones the Element and append the clone after the Element.
*/

clone: function(contents){
	return $(this.cloneNode(contents || true));
},

/*  
Property: replaceWith
Replaces the Element with an element passed.

Parameteres:
el - a string representing the element to be injected in (myElementId, or div), or an element reference.
If you pass div or another tag, the element will be created.

Returns:
the passed in element

Example:
>$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place.
*/

replaceWith: function(el){
	var el = $(el) || new Element(el);
	this.parentNode.replaceChild(el, this);
	return el;
},

/*  
Property: appendText
Appends text node to a DOM element.

Arguments:
text - the text to append.

Example:
><div id="myElement">hey</div>
>$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy"
*/

appendText: function(text){
	if (this.getTag() == 'style' && window.ActiveXObject) this.styleSheet.cssText = text;
	else this.appendChild(document.createTextNode(text));
	return this;
},

/*
	Property: hasClass
 Tests the Element to see if it has the passed in className.
 
	Returns:
 true - the Element has the class
 false - it doesn't
 
	Arguments:
 className - the class name to test.
 
	Example:
 ><div id="myElement" class="testClass"></div>
 >$('myElement').hasClass('testClass'); //returns true
	*/

hasClass: function(className){
	return !!this.className.test("\\b"+className+"\\b");
},

/*	
Property: addClass
 Adds the passed in class to the Element, if the element doesnt already have it.
 
	Arguments:
 className - the class name to add
 
	Example: 
 ><div id="myElement" class="testClass"></div>
 >$('myElement').addClass('newClass'); //<div id="myElement" class="testClass newClass"></div>
	*/

addClass: function(className){
	if (!this.hasClass(className)) this.className = (this.className+' '+className.trim()).clean();
	return this;
},

/*	
Property: removeClass
 works like <Element.addClass>, but removes the class from the element.
	*/

removeClass: function(className){
	if (this.hasClass(className)) this.className = this.className.replace(className.trim(), '').clean();
	return this;
},

/*	
Property: toggleClass
 Adds or removes the passed in class name to the element, depending on if it's present or not.
 
	Arguments:
 className - the class to add or remove
 
	Example:
 ><div id="myElement" class="myClass"></div>
 >$('myElement').toggleClass('myClass');
 ><div id="myElement" class=""></div>
 >$('myElement').toggleClass('myClass');
 ><div id="myElement" class="myClass"></div>
	*/

toggleClass: function(className){
	if (this.hasClass(className)) return this.removeClass(className);
	else return this.addClass(className);
},

/*
	Property: setStyle	
 Sets a css property to the Element.
 
 Arguments:
 property - the property to set
 value - the value to which to set it
 
 Example:
 >$('myElement').setStyle('width', '300px'); //the width is now 300px
	*/

setStyle: function(property, value){
	if (property == 'opacity') this.setOpacity(parseFloat(value));
	else this.style[property.camelCase()] = value;
	return this;
},

/*
	Property: setStyles
 Applies a collection of styles to the Element.
 
	Arguments:
 source - an object or string containing all the styles to apply
 
	Examples:
 >$('myElement').setStyles({
	 >	border: '1px solid #000',
	 >	width: '300px',
	 >	height: '400px'
	 >});
 
 OR
 
 >$('myElement').setStyle('border: 1px solid #000; width: 300px; height: 400px;');
	*/

setStyles: function(source){
	if ($type(source) == 'object') {
		for (var property in source) this.setStyle(property, source[property]);
	} else if ($type(source) == 'string') {
		if (window.ActiveXObject) this.cssText = source;
		else this.setAttribute('style', source);
	}
	return this;
},

/*	
Property: setOpacity
 Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity == 1.
 
	Arguments:
 opacity - Accepts numbers from 0 to 1.
 
	Example:
 >$('myElement').setOpacity(0.5) //make it 50% transparent
	*/

setOpacity: function(opacity){
	if (opacity == 0){
		if(this.style.visibility != "hidden") this.style.visibility = "hidden";
	} else {
		if(this.style.visibility != "visible") this.style.visibility = "visible";
	}
	if (window.ActiveXObject) this.style.filter = "alpha(opacity=" + opacity*100 + ")";
	this.style.opacity = opacity;
	return this;
},

/*	
Property: getStyle
 Returns the style of the Element given the property passed in.
 
	Arguments:
 property - the css style property you want to retrieve
 
	Example:
 >$('myElement').getStyle('width'); //returns "400px"
 >//but you can also use
 >$('myElement').getStyle('width').toInt(); //returns "400"
 
	Returns:
 the style as a string
	*/

getStyle: function(property){
	var proPerty = property.camelCase();
	var style = this.style[proPerty] || false;
	if (!style) {
		if (document.defaultView) style = document.defaultView.getComputedStyle(this,null).getPropertyValue(property);
		else if (this.currentStyle) style = this.currentStyle[proPerty];
	}
	if (style && ['color', 'backgroundColor', 'borderColor'].test(proPerty) && style.test('rgb')) style = style.rgbToHex();
	return style;
},

/*	
Property: addEvent
 Attaches an event listener to a DOM element.
 
	Arguments:
 action - the event to monitor ('click', 'load', etc)
 fn - the function to execute
 
	Example:
 >$('myElement').addEvent('click', function(){alert('clicked!')});
	*/

addEvent: function(action, fn){
	this[action+fn] = fn.bind(this);
	if (this.addEventListener) this.addEventListener(action, fn, false);
	else this.attachEvent('on'+action, this[action+fn]);
	var el = this;
	if (this != window) Unload.functions.push(function(){
		el.removeEvent(action, fn);
		el[action+fn] = null;
	});
	return this;
},

/*	
Property: removeEvent
 Works as Element.addEvent, but instead removes the previously added event listener.
	*/

removeEvent: function(action, fn){
	if (this.removeEventListener) this.removeEventListener(action, fn, false);
	else this.detachEvent('on'+action, this[action+fn]);
	return this;
},

getBrother: function(what){
	var el = this[what+'Sibling'];
	while ($type(el) == 'textnode') el = el[what+'Sibling'];
	return $(el);
},

/*
	Property: getPrevious
 Returns the previousSibling of the Element, excluding text nodes.
 
	Example:
 >$('myElement').getPrevious(); //get the previous DOM element from myElement
 
	Returns:
 the sibling element or undefined if none found.
	*/

getPrevious: function(){
	return this.getBrother('previous');
},

/*
	Property: getNext
 Works as Element.getPrevious, but tries to find the nextSibling.
	*/

getNext: function(){
	return this.getBrother('next');
},

/*
	Property: getNext
 Works as <Element.getPrevious>, but tries to find the firstChild.
	*/

getFirst: function(){
	var el = this.firstChild;
	while ($type(el) == 'textnode') el = el.nextSibling;
	return $(el);
},

/*
	Property: getLast
 Works as <Element.getPrevious>, but tries to find the lastChild.
	*/

getLast: function(){
	var el = this.lastChild;
	while ($type(el) == 'textnode')
		el = el.previousSibling;
	return $(el);
},

/*	
Property: setProperty
 Sets an attribute for the Element.
 
	Arguments:
 property - the property to assign the value passed in
 value - the value to assign to the property passed in
 
	Example:
 >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source
	*/

setProperty: function(property, value){
	var el = false;
	switch(property){
		case 'class': this.className = value; break;
		case 'style': this.setStyles(value); break;
		case 'name': if (window.ActiveXObject && this.getTag() == 'input'){
			el = $(document.createElement('<input name="'+value+'" />'));
			$A(this.attributes).each(function(attribute){
				if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value);
				
			});
			if (this.parentNode) this.replaceWith(el);
		};
		default: this.setAttribute(property, value);
	}
	return el || this;
},

/*	
Property: setProperties
 Sets numerous attributes for the Element.
 
	Arguments:
 source - an object with key/value pairs.
 
	Example:
 >$('myElement').setProperties({
	 >	src: 'whatever.gif',
	 >	alt: 'whatever dude'
	 >});
 ><img src="whatever.gif" alt="whatever dude">
	*/

setProperties: function(source){
	for (var property in source) this.setProperty(property, source[property]);
	return this;
},

/*
	Property: setHTML
 Sets the innerHTML of the Element.
 
	Arguments:
 html - the new innerHTML for the element.
 
	Example:
 >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML
	*/

setHTML: function(html){
	this.innerHTML = html;
	return this;
},

/*	
Property: getProperty
 Gets the an attribute of the Element.
 
	Arguments:
 property - the attribute to retrieve
 
	Example:
 >$('myImage').getProperty('src') // returns whatever.gif
 
	Returns:
 the value, or an empty string
	*/

getProperty: function(property){
	return this.getAttribute(property);
},

/*
	Property: getTag
 Returns the tagName of the element in lower case.
 
	Example:
 >$('myImage').getTag() // returns 'img'
 
	Returns:
 The tag name in lower case
	*/

getTag: function(){
	return this.tagName.toLowerCase();
},

getOffset: function(what){
	what = what.capitalize();
	var el = this;
	var offset = 0;
	do {
		offset += el['offset'+what] || 0;
		el = el.offsetParent;
	} while (el);
	return offset;
},

/*	
Property: getTop
 Returns the distance from the top of the window to the Element.
	*/

getTop: function(){
	return this.getOffset('top');
},

/*	
Property: getLeft
 Returns the distance from the left of the window to the Element.
	*/

getLeft: function(){
	return this.getOffset('left');
},

/*	
Property: getValue
 Returns the value of the Element, if its tag is textarea, select or input.
	*/

getValue: function(){
	var value = false;
	switch(this.getTag()){
		case 'select': value = this.getElementsByTagName('option')[this.selectedIndex].value; break;
		case 'input': if ( (this.checked && ['checkbox', 'radio'].test(this.type)) || (['hidden', 'text', 'password'].test(this.type)) ) 
			value = this.value; break;
		case 'textarea': value = this.value;
	}
	return value;
}

});

new Object.Native(Element);

Element.extend({
hasClassName: Element.prototype.hasClass,
addClassName: Element.prototype.addClass,
removeClassName: Element.prototype.removeClass,
toggleClassName: Element.prototype.toggleClass
});

/* Section: Utility Functions  */

/*
 Function: $Element
	Applies a method with the passed in args to the passed in element. Useful if you dont want to extend the element
 
	Arguments:
 el - the element
 method - a string representing the Element Class method to execute on that element
 args - an array representing the arguments to pass to that method
 
	Example:
 >$Element(el, 'hasClass', className) //true or false
 */

function $Element(el, method, args){
	if ($type(args) != 'array') args = [args];
	return Element.prototype[method].apply(el, args);
};

/*
 Function: $()
	returns the element passed in with all the Element prototypes applied.
	
 Arguments:
	el - a reference to an actual element or a string representing the id of an element
 
 Example:
	>$('myElement') // gets a DOM element by id with all the Element prototypes applied.
	>var div = document.getElementById('myElement');
	>$(div) //returns an Element also with all the mootools extentions applied.
 
	You'll use this when you aren't sure if a variable is an actual element or an id, as
	well as just shorthand for document.getElementById().
 
 Returns:
	a DOM element or false (if no id was found)
 
 Note:
	you need to call $ on an element only once to get all the prototypes.
	But its no harm to call it multiple times, as it will detect if it has been already extended.
 */

function $(el){
	if ($type(el) == 'string') el = document.getElementById(el);
	if ($type(el) == 'element'){
		if (!el.extend){
			Unload.elements.push(el);
			el.extend = Object.extend;
			el.extend(Element.prototype);
		}
		return el;
	} else return false;
};

window.addEvent = document.addEvent = Element.prototype.addEvent;
window.removeEvent = document.removeEvent = Element.prototype.removeEvent;

var Unload = {
	
elements: [], functions: [], vars: [],
	
unload: function(){
	Unload.functions.each(function(fn){
		fn();
	});
	
	window.removeEvent('unload', window.removeFunction);
	
	Unload.elements.each(function(el){
		for(var p in Element.prototype){
			window[p] = null;
			document[p] = null;
			el[p] = null;
		}
		el.extend = null;
	});
}

};

window.removeFunction = Unload.unload;
window.addEvent('unload', window.removeFunction);
/*
 Script: Fx.js
	Applies visual transitions to any element. Contains Fx.Base, Fx.Style and Fx.Styles
 
 Dependencies:
	<Moo.js>, <Function.js>, <Array.js>, <String.js>, <Element.js>
 
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 */

var Fx = fx = {};

/*
 Class: Fx.Base
	Base class for the Mootools fx library.
	
 Options:
	onStart - the function to execute as the effect begins; nothing (<Class.empty>) by default.
	onComplete - the function to execute after the effect has processed; nothing (<Class.empty>) by default.
	transition - the equation to use for the effect see <Fx.Transitions>; default is <Fx.Transitions.sineInOut>
	duration - the duration of the effect in ms; 500 is the default.
	unit - the unit is 'px' by default (other values include things like 'em' for fonts or '%').
	wait - boolean: to wait or not to wait for a current transition to end before running another of the same instance. defaults to true.
	fps - the frames per second for the transition; default is 30
 */

Fx.Base = new Class({
	
setOptions: function(options){
	this.options = Object.extend({
onStart: Class.empty,
onComplete: Class.empty,
transition: Fx.Transitions.sineInOut,
duration: 500,
unit: 'px',
wait: true,
fps: 50
	}, options || {});
},

step: function(){
	var time = new Date().getTime();
	if (time < this.time + this.options.duration){
		this.cTime = time - this.time;
		this.setNow();
	} else {
		this.options.onComplete.pass(this.element, this).delay(10);
		this.clearTimer();
		this.callChain();
		this.now = this.to;
	}
	this.increase();
},

/*	
Property: set
 Immediately sets the value with no transition.
	
	Arguments:
 to - the point to jump to
	
	Example:
 >var myFx = new Fx.Style('myElement', 'opacity').set(0); //will make it immediately transparent
	*/

set: function(to){
	this.now = to;
	this.increase();
	return this;
},

setNow: function(){
	this.now = this.compute(this.from, this.to);
},

compute: function(from, to){
	return this.options.transition(this.cTime, from, (to - from), this.options.duration);
},

/*
	Property: custom
 Executes an effect from one position to the other.
	
	Arguments:
 from - integer:  staring value
 to - integer: the ending value
	
	Examples:
 >var myFx = new Fx.Style('myElement', 'opacity').custom(0,1); //display a transition from transparent to opaque.
	*/

custom: function(from, to){
	if (!this.options.wait) this.clearTimer();
	if (this.timer) return;
	this.options.onStart.pass(this.element, this).delay(10);
	this.from = from;
	this.to = to;
	this.time = new Date().getTime();
	this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
	return this;
},

/*
	Property: clearTimer
 Stops processing the transition.
	*/
clearTimer: function(){
	this.timer = $clear(this.timer);
	return this;
},

setStyle: function(element, property, value){
	element.setStyle(property, value + this.options.unit);
}

});

Fx.Base.implement(new Chain);

/*	
Class: Fx.Style
	The Style effect; Extends <Fx.Base>, inherits all its properties. Used to transition any css property from one value to another.
 
 Arguments:
	el - the $(element) to apply the style transition to
	property - the property to transition
	options - the Fx.Base options (see: <Fx.Base>)
	
 Example:
	>var marginChange = new fx.Style('myElement', 'margin-top', {duration:500});
	>marginChange.custom(10, 100);
 */

Fx.Style = Fx.Base.extend({
	
initialize: function(el, property, options){
	this.element = $(el);
	this.setOptions(options);
	this.property = property.camelCase();
},

/*	
Property: hide
 Same as <Fx.Base.set>(0)
	*/

hide: function(){
	return this.set(0);
},

/*	
Property: goTo
 will apply <Fx.Base.custom>, setting the starting point to the current position.
 
	Arguments:
 val - the ending value
	*/

goTo: function(val){
	return this.custom(this.now || 0, val);
},

increase: function(){
	this.setStyle(this.element, this.property, this.now);
}

});

/*
 Class: Fx.Styles
	Allows you to animate multiple css properties at once; Extends <Fx.Base>, inherits all its properties.
	
 Arguments:
	el - the $(element) to apply the styles transition to
	options - the fx options (see: <Fx.Base>)
 
 Example:
	>var myEffects = new fx.Styles('myElement', {duration: 1000, transition: fx.linear});
	>myEffects.custom({
		>	'height': [10, 100],
		>	'width': [900, 300]
		>});
 */

Fx.Styles = Fx.Base.extend({
	
initialize: function(el, options){
	this.element = $(el);
	this.setOptions(options);
	this.now = {};
},

setNow: function(){
	for (var p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]);
},

/*
	Property:	custom
 The function you'll actually use to execute a transition.
	
	Arguments:
 an object
 
	Example:
 see <Fx.Styles>
	*/

custom: function(objFromTo){
	if (this.timer && this.options.wait) return;
	var from = {};
	var to = {};
	for (var p in objFromTo){
		from[p] = objFromTo[p][0];
		to[p] = objFromTo[p][1];
	}
	return this.parent(from, to);
},

increase: function(){
	for (var p in this.now) this.setStyle(this.element, p, this.now[p]);
}

});

/*
 Class: Element
	Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
 */

Element.extend({
	
	/*
	 Property: effect
	 Applies an <Fx.Style> to the Element; This a shortcut for <Fx.Style>.
	 
	 Example:
	 >var myEffect = $('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear});
	 >myEffect.custom(10, 100);
	 */
	
effect: function(property, options){
	return new Fx.Style(this, property, options);
},

/*	
Property: effects
 Applies an <Fx.Styles> to the Element; This a shortcut for <Fx.Styles>.
 
	Example:
 >var myEffects = $(myElement).effects({duration: 1000, transition: Fx.Transitions.sineInOut});
 >myEffects.custom({'height': [10, 100], 'width': [900, 300]});
	*/

effects: function(options){
	return new Fx.Styles(this, options);
}

});

/*
 Class: Fx.Transitions
	A collection of transition equations for use with the <Fx> Class.
 
 See Also:
	<Fxtransitions.js> for a whole bunch of transitions.
 
 Credits:
	Easing Equations, (c) 2003 Robert Penner (http://www.robertpenner.com/easing/), Open Source BSD License.
											  */

Fx.Transitions = {
	
	/* Property: linear */
linear: function(t, b, c, d){
	return c*t/d + b;
},

/* Property: sineInOut */
sineInOut: function(t, b, c, d){
	return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
}

};
/*
 Script: Window.js
	Window methods, as those to get the size or a better onload.
 
 Dependencies:
	<Moo.js>, <Function.js>, <String.js>
 
 Author:
	Valerio Proietti, <http://mad4milk.net>
 
 License:
	MIT-style license.
 */

/*
 Class: Window
	Cross browser methods to get the window size, onDomReady method.
 */

var Window = {
	
	/*	
Property: disableImageCache
	 Disables background image chache for internex explorer, to prevent flickering. 
	 To be called if you have effects with background images, and they flicker.
	 
	 Example:
	 Window.disableImageCache();
	 */
	
disableImageCache: function(){
	if (window.ActiveXObject) document.execCommand("BackgroundImageCache", false, true);
},

extend: Object.extend,

/*	
Property: getWidth
 Returns an integer representing the width of the browser.
	*/

getWidth: function(){
	return window.innerWidth || document.documentElement.clientWidth || 0;
},

/*
	Property: getHeight
 Returns an integer representing the height of the browser.
	*/

getHeight: function(){
	return window.innerHeight || document.documentElement.clientHeight || 0;
},

/*
	Property: getScrollHeight
 Returns an integer representing the scrollHeight of the window.
 
	See Also:
 <http://developer.mozilla.org/en/docs/DOM:element.scrollHeight>
	*/

getScrollHeight: function(){
	return document.documentElement.scrollHeight;
},

/*
	Property: getScrollWidth
 Returns an integer representing the scrollWidth of the window.
 
	See Also:
 <http://developer.mozilla.org/en/docs/DOM:element.scrollWidth>
	*/

getScrollWidth: function(){
	return document.documentElement.scrollWidth;
},

/*	
Property: getScrollTop
 Returns an integer representing the scrollTop of the window (the number of pixels the window has scrolled from the top).
 
	See Also:
 <http://developer.mozilla.org/en/docs/DOM:element.scrollTop>
	*/

getScrollTop: function(){
	return document.documentElement.scrollTop || window.pageYOffset || 0;
},

/*
	Property: getScrollLeft
 Returns an integer representing the scrollLeft of the window (the number of pixels the window has scrolled from the left).
 
	See Also:
 <http://developer.mozilla.org/en/docs/DOM:element.scrollLeft>
	*/

getScrollLeft: function(){
	return document.documentElement.scrollLeft || window.pageXOffset || 0;
},

/*
	Property: onDomReady
 Executes the passed in function when the DOM is ready (when the document tree has loaded, not waiting for images).
 
	Credits:
 (c) Dean Edwards/Matthias Miller/John Resig, remastered for mootools. Later touched up by Christophe Beyls <http://digitalia.be>.
 
	Arguments:
 init - the function to execute when the DOM is ready
 
	Example:
 > Window.onDomReady(function(){alert('the dom is ready');});
	*/

onDomReady: function(init){
	var state = document.readyState;
	if (state && document.childNodes && !document.all && !navigator.taintEnabled){ //khtml
		if (state.test(/loaded|complete/)) return init();
		else return Window.onDomReady.pass(init).delay(100);
	} else if (state && window.ActiveXObject){ //ie
		var script = $('_ie_ready_');
		if (!script) document.write("<script id='_ie_ready_' defer='true' src='://'></script>");
		$('_ie_ready_').addEvent('readystatechange', function(){
			if (this.readyState == 'complete') init();
		});
		return;
	} else { //others
		var myInit = function() {
			if (arguments.callee.done) return;
			arguments.callee.done = true;
			init();
		};
		window.addEvent("load", myInit);
		document.addEvent("DOMContentLoaded", myInit);
	}
}

};
