140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikMooTools: the javascript framework
440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikweb build:
640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik - http://mootools.net/core/8423c12ffd6a6bfcde9ea22554aec795
740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikpackager build:
940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Delegation Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady
1040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
1140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
1240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
1340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
1440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
1540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
1640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
1740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Core
1840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
1940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: The heart of MooTools.
2040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
2140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
2240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
2340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikcopyright: Copyright (c) 2006-2014 [Valerio Proietti](http://mad4milk.net/).
2440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
2540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikauthors: The MooTools production team (http://mootools.net/developers/)
2640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
2740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikinspiration:
2840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
2940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
3040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
3140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Core, MooTools, Type, typeOf, instanceOf, Native]
3240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
3340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
3440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
3540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
3640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
3740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
3840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.MooTools = {
3940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	version: '1.5.0',
4040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	build: '0f7b690afee9349b15909f33016a25d2e4d9f4e3'
4140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
4240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
4340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// typeOf, instanceOf
4440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
4540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar typeOf = this.typeOf = function(item){
4640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item == null) return 'null';
4740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item.$family != null) return item.$family();
4840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
4940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item.nodeName){
5040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (item.nodeType == 1) return 'element';
5140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
5240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (typeof item.length == 'number'){
5340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if ('callee' in item) return 'arguments';
5440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if ('item' in item) return 'collection';
5540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
5640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
5740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return typeof item;
5840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
5940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
6040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar instanceOf = this.instanceOf = function(item, object){
6140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item == null) return false;
6240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var constructor = item.$constructor || item.constructor;
6340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (constructor){
6440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (constructor === object) return true;
6540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		constructor = constructor.parent;
6640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
6740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<ltIE8>*/
6840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!item.hasOwnProperty) return false;
6940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</ltIE8>*/
7040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return item instanceof object;
7140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
7240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
7340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Function overloading
7440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
7540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Function = this.Function;
7640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
7740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar enumerables = true;
7840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfor (var i in {toString: 1}) enumerables = null;
7940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
8040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
8140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.prototype.overloadSetter = function(usePlural){
8240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var self = this;
8340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return function(a, b){
8440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (a == null) return this;
8540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (usePlural || typeof a != 'string'){
8640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var k in a) self.call(this, k, a[k]);
8740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (enumerables) for (var i = enumerables.length; i--;){
8840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				k = enumerables[i];
8940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
9040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
9140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
9240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			self.call(this, a, b);
9340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
9440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
9540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
9640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
9740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
9840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.prototype.overloadGetter = function(usePlural){
9940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var self = this;
10040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return function(a){
10140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var args, result;
10240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof a != 'string') args = a;
10340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else if (arguments.length > 1) args = arguments;
10440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else if (usePlural) args = [a];
10540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (args){
10640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			result = {};
10740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
10840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
10940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			result = self.call(this, a);
11040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
11140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return result;
11240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
11340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
11440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
11540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.prototype.extend = function(key, value){
11640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this[key] = value;
11740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}.overloadSetter();
11840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
11940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.prototype.implement = function(key, value){
12040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.prototype[key] = value;
12140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}.overloadSetter();
12240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
12340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// From
12440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
12540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar slice = Array.prototype.slice;
12640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
12740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.from = function(item){
12840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (typeOf(item) == 'function') ? item : function(){
12940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return item;
13040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
13140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
13240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
13340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.from = function(item){
13440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item == null) return [];
13540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
13640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
13740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
13840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikNumber.from = function(item){
13940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var number = parseFloat(item);
14040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return isFinite(number) ? number : null;
14140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
14240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
14340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikString.from = function(item){
14440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return item + '';
14540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
14640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
14740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// hide, protect
14840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
14940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.implement({
15040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
15140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hide: function(){
15240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$hidden = true;
15340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
15440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
15540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
15640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	protect: function(){
15740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$protected = true;
15840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
15940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
16040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
16140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
16240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
16340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Type
16440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
16540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Type = this.Type = function(name, object){
16640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (name){
16740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var lower = name.toLowerCase();
16840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var typeCheck = function(item){
16940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (typeOf(item) == lower);
17040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
17140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
17240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Type['is' + name] = typeCheck;
17340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (object != null){
17440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			object.prototype.$family = (function(){
17540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return lower;
17640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}).hide();
17740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
17840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
17940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
18040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
18140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (object == null) return null;
18240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
18340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	object.extend(this);
18440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	object.$constructor = Type;
18540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	object.prototype.$constructor = object;
18640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
18740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return object;
18840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
18940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
19040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar toString = Object.prototype.toString;
19140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
19240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikType.isEnumerable = function(item){
19340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
19440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
19540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
19640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hooks = {};
19740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
19840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hooksOf = function(object){
19940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var type = typeOf(object.prototype);
20040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return hooks[type] || (hooks[type] = []);
20140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
20240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
20340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar implement = function(name, method){
20440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (method && method.$hidden) return;
20540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
20640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var hooks = hooksOf(this);
20740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
20840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = 0; i < hooks.length; i++){
20940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var hook = hooks[i];
21040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(hook) == 'type') implement.call(hook, name, method);
21140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else hook.call(this, name, method);
21240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
21340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
21440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var previous = this.prototype[name];
21540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (previous == null || !previous.$protected) this.prototype[name] = method;
21640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
21740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
21840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return method.apply(item, slice.call(arguments, 1));
21940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
22040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
22140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
22240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar extend = function(name, method){
22340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (method && method.$hidden) return;
22440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var previous = this[name];
22540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (previous == null || !previous.$protected) this[name] = method;
22640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
22740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
22840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikType.implement({
22940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
23040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	implement: implement.overloadSetter(),
23140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
23240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	extend: extend.overloadSetter(),
23340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
23440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	alias: function(name, existing){
23540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		implement.call(this, name, this.prototype[existing]);
23640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.overloadSetter(),
23740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
23840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mirror: function(hook){
23940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		hooksOf(this).push(hook);
24040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
24140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
24240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
24340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
24440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
24540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiknew Type('Type', Type);
24640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
24740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Default Types
24840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
24940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar force = function(name, object, methods){
25040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var isType = (object != Object),
25140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		prototype = object.prototype;
25240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
25340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (isType) object = new Type(name, object);
25440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
25540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = 0, l = methods.length; i < l; i++){
25640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var key = methods[i],
25740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			generic = object[key],
25840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			proto = prototype[key];
25940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
26040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (generic) generic.protect();
26140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isType && proto) object.implement(key, proto.protect());
26240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
26340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
26440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (isType){
26540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
26640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		object.forEachMethod = function(fn){
26740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
26840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				fn.call(prototype, prototype[methods[i]], methods[i]);
26940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
27040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var key in prototype) fn.call(prototype, prototype[key], key);
27140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
27240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
27340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
27440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return force;
27540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
27640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
27740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikforce('String', String, [
27840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'charAt', 'charCodeAt', 'concat', 'contains', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
27940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
28040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('Array', Array, [
28140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
28240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
28340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('Number', Number, [
28440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
28540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('Function', Function, [
28640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'apply', 'call', 'bind'
28740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('RegExp', RegExp, [
28840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'exec', 'test'
28940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('Object', Object, [
29040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'create', 'defineProperty', 'defineProperties', 'keys',
29140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
29240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
29340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik])('Date', Date, ['now']);
29440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
29540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.extend = extend.overloadSetter();
29640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
29740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDate.extend('now', function(){
29840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return +(new Date);
29940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
30040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
30140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiknew Type('Boolean', Boolean);
30240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
30340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// fixes NaN returning as Number
30440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
30540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikNumber.prototype.$family = function(){
30640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return isFinite(this) ? 'number' : 'null';
30740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}.hide();
30840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
30940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Number.random
31040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
31140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikNumber.extend('random', function(min, max){
31240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return Math.floor(Math.random() * (max - min + 1) + min);
31340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
31440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
31540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// forEach, each
31640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
31740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasOwnProperty = Object.prototype.hasOwnProperty;
31840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.extend('forEach', function(object, fn, bind){
31940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var key in object){
32040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
32140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
32240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
32340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
32440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.each = Object.forEach;
32540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
32640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.implement({
32740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
32840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<!ES5>*/
32940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	forEach: function(fn, bind){
33040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length; i < l; i++){
33140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (i in this) fn.call(bind, this[i], i, this);
33240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
33340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
33440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</!ES5>*/
33540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
33640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	each: function(fn, bind){
33740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.forEach(this, fn, bind);
33840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
33940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
34040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
34140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
34240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
34340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Array & Object cloning, Object merging and appending
34440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
34540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar cloneOf = function(item){
34640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	switch (typeOf(item)){
34740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'array': return item.clone();
34840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'object': return Object.clone(item);
34940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		default: return item;
35040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
35140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
35240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
35340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.implement('clone', function(){
35440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var i = this.length, clone = new Array(i);
35540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (i--) clone[i] = cloneOf(this[i]);
35640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return clone;
35740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
35840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
35940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar mergeOne = function(source, key, current){
36040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	switch (typeOf(current)){
36140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'object':
36240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
36340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else source[key] = Object.clone(current);
36440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		break;
36540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'array': source[key] = current.clone(); break;
36640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		default: source[key] = current;
36740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
36840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return source;
36940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
37040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
37140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.extend({
37240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
37340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	merge: function(source, k, v){
37440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(k) == 'string') return mergeOne(source, k, v);
37540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 1, l = arguments.length; i < l; i++){
37640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var object = arguments[i];
37740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var key in object) mergeOne(source, key, object[key]);
37840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
37940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return source;
38040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
38140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
38240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clone: function(object){
38340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var clone = {};
38440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object) clone[key] = cloneOf(object[key]);
38540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return clone;
38640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
38740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
38840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	append: function(original){
38940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 1, l = arguments.length; i < l; i++){
39040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var extended = arguments[i] || {};
39140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var key in extended) original[key] = extended[key];
39240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
39340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return original;
39440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
39540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
39640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
39740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
39840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Object-less types
39940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
40040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
40140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	new Type(name);
40240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
40340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
40440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Unique ID
40540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
40640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar UID = Date.now();
40740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
40840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikString.extend('uniqueID', function(){
40940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (UID++).toString(36);
41040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
41140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
41240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
41340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
41440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
41540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
41640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
41740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
41840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
41940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
42040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Array
42140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
42240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains Array Prototypes like each, contains, and erase.
42340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
42440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
42540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
42640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Type]
42740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
42840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Array
42940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
43040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
43140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
43240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
43340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.implement({
43440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
43540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<!ES5>*/
43640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	every: function(fn, bind){
43740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length >>> 0; i < l; i++){
43840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
43940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
44040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
44140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
44240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
44340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	filter: function(fn, bind){
44440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var results = [];
44540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){
44640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value = this[i];
44740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (fn.call(bind, value, i, this)) results.push(value);
44840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
44940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return results;
45040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
45140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
45240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	indexOf: function(item, from){
45340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var length = this.length >>> 0;
45440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){
45540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this[i] === item) return i;
45640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
45740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return -1;
45840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
45940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
46040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	map: function(fn, bind){
46140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var length = this.length >>> 0, results = Array(length);
46240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < length; i++){
46340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (i in this) results[i] = fn.call(bind, this[i], i, this);
46440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
46540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return results;
46640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
46740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
46840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	some: function(fn, bind){
46940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length >>> 0; i < l; i++){
47040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if ((i in this) && fn.call(bind, this[i], i, this)) return true;
47140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
47240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return false;
47340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
47440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</!ES5>*/
47540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
47640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clean: function(){
47740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.filter(function(item){
47840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return item != null;
47940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
48040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
48140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
48240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	invoke: function(methodName){
48340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var args = Array.slice(arguments, 1);
48440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.map(function(item){
48540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return item[methodName].apply(item, args);
48640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
48740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
48840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
48940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	associate: function(keys){
49040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var obj = {}, length = Math.min(this.length, keys.length);
49140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
49240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return obj;
49340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
49440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
49540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	link: function(object){
49640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var result = {};
49740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length; i < l; i++){
49840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var key in object){
49940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (object[key](this[i])){
50040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					result[key] = this[i];
50140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					delete object[key];
50240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					break;
50340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
50440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
50540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
50640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return result;
50740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
50840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
50940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	contains: function(item, from){
51040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.indexOf(item, from) != -1;
51140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
51240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
51340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	append: function(array){
51440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.push.apply(this, array);
51540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
51640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
51740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
51840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getLast: function(){
51940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.length) ? this[this.length - 1] : null;
52040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
52140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
52240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getRandom: function(){
52340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.length) ? this[Number.random(0, this.length - 1)] : null;
52440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
52540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
52640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	include: function(item){
52740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.contains(item)) this.push(item);
52840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
52940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
53040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
53140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	combine: function(array){
53240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
53340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
53440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
53540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
53640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	erase: function(item){
53740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = this.length; i--;){
53840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this[i] === item) this.splice(i, 1);
53940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
54040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
54140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
54240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
54340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	empty: function(){
54440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.length = 0;
54540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
54640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
54740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
54840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	flatten: function(){
54940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var array = [];
55040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length; i < l; i++){
55140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var type = typeOf(this[i]);
55240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (type == 'null') continue;
55340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
55440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
55540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return array;
55640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
55740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
55840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pick: function(){
55940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length; i < l; i++){
56040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this[i] != null) return this[i];
56140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
56240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
56340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
56440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
56540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hexToRgb: function(array){
56640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.length != 3) return null;
56740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var rgb = this.map(function(value){
56840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (value.length == 1) value += value;
56940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return parseInt(value, 16);
57040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
57140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (array) ? rgb : 'rgb(' + rgb + ')';
57240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
57340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
57440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	rgbToHex: function(array){
57540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.length < 3) return null;
57640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
57740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var hex = [];
57840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < 3; i++){
57940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var bit = (this[i] - 0).toString(16);
58040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			hex.push((bit.length == 1) ? '0' + bit : bit);
58140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
58240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (array) ? hex : '#' + hex.join('');
58340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
58440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
58540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
58640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
58740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
58840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
58940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
59040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
59140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
59240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
59340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: String
59440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
59540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains String Prototypes like camelCase, capitalize, test, and toInt.
59640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
59740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
59840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
59940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Type, Array]
60040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
60140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: String
60240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
60340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
60440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
60540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
60640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikString.implement({
60740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
60840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//<!ES6>
60940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	contains: function(string, index){
61040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
61140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
61240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//</!ES6>
61340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
61440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	test: function(regex, params){
61540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
61640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
61740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
61840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	trim: function(){
61940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/^\s+|\s+$/g, '');
62040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
62140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
62240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clean: function(){
62340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/\s+/g, ' ').trim();
62440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
62540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
62640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	camelCase: function(){
62740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/-\D/g, function(match){
62840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return match.charAt(1).toUpperCase();
62940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
63040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
63140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
63240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hyphenate: function(){
63340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/[A-Z]/g, function(match){
63440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return ('-' + match.charAt(0).toLowerCase());
63540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
63640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
63740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
63840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	capitalize: function(){
63940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/\b[a-z]/g, function(match){
64040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return match.toUpperCase();
64140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
64240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
64340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
64440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	escapeRegExp: function(){
64540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
64640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
64740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
64840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toInt: function(base){
64940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return parseInt(this, base || 10);
65040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
65140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
65240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toFloat: function(){
65340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return parseFloat(this);
65440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
65540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
65640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hexToRgb: function(array){
65740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
65840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (hex) ? hex.slice(1).hexToRgb(array) : null;
65940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
66040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
66140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	rgbToHex: function(array){
66240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var rgb = String(this).match(/\d{1,3}/g);
66340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (rgb) ? rgb.rgbToHex(array) : null;
66440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
66540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
66640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	substitute: function(object, regexp){
66740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
66840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (match.charAt(0) == '\\') return match.slice(1);
66940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (object[name] != null) ? object[name] : '';
67040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
67140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
67240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
67340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
67440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
67540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
67640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
67740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
67840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
67940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
68040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
68140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Number
68240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
68340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains Number Prototypes like limit, round, times, and ceil.
68440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
68540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
68640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
68740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Type
68840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
68940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Number
69040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
69140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
69240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
69340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
69440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikNumber.implement({
69540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
69640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	limit: function(min, max){
69740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.min(max, Math.max(min, this));
69840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
69940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
70040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	round: function(precision){
70140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
70240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.round(this * precision) / precision;
70340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
70440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
70540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	times: function(fn, bind){
70640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < this; i++) fn.call(bind, i, this);
70740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
70840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
70940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toFloat: function(){
71040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return parseFloat(this);
71140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
71240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
71340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toInt: function(base){
71440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return parseInt(this, base || 10);
71540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
71640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
71740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
71840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
71940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikNumber.alias('each', 'times');
72040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
72140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(math){
72240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var methods = {};
72340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	math.each(function(name){
72440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!Number[name]) methods[name] = function(){
72540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return Math[name].apply(null, [this].concat(Array.from(arguments)));
72640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
72740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
72840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Number.implement(methods);
72940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
73040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
73140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
73240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
73340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
73440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
73540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Function
73640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
73740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains Function Prototypes like create, bind, pass, and delay.
73840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
73940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
74040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
74140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Type
74240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
74340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Function
74440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
74540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
74640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
74740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
74840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.extend({
74940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
75040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attempt: function(){
75140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = arguments.length; i < l; i++){
75240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
75340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return arguments[i]();
75440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch (e){}
75540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
75640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
75740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
75840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
75940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
76040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
76140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFunction.implement({
76240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
76340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attempt: function(args, bind){
76440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
76540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this.apply(bind, Array.from(args));
76640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch (e){}
76740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
76840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
76940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
77040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
77140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<!ES5-bind>*/
77240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	bind: function(that){
77340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var self = this,
77440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
77540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			F = function(){};
77640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
77740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var bound = function(){
77840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var context = that, length = arguments.length;
77940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this instanceof bound){
78040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				F.prototype = self.prototype;
78140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				context = new F;
78240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
78340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var result = (!args && !length)
78440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				? self.call(context)
78540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				: self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
78640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return context == that ? result : context;
78740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
78840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return bound;
78940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
79040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</!ES5-bind>*/
79140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
79240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pass: function(args, bind){
79340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var self = this;
79440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (args != null) args = Array.from(args);
79540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return function(){
79640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return self.apply(bind, args || arguments);
79740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
79840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
79940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
80040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	delay: function(delay, bind, args){
80140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return setTimeout(this.pass((args == null ? [] : args), bind), delay);
80240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
80340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
80440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	periodical: function(periodical, bind, args){
80540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return setInterval(this.pass((args == null ? [] : args), bind), periodical);
80640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
80740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
80840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
80940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
81440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
81540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Object
81740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
81840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Object generic methods
81940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
82040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
82140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
82240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Type
82340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
82440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Object, Hash]
82540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
82640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
82740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
82840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
82940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
83040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
83140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasOwnProperty = Object.prototype.hasOwnProperty;
83240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
83340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.extend({
83440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
83540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	subset: function(object, keys){
83640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var results = {};
83740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = keys.length; i < l; i++){
83840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var k = keys[i];
83940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (k in object) results[k] = object[k];
84040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
84140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return results;
84240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
84340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
84440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	map: function(object, fn, bind){
84540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var results = {};
84640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
84740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);
84840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
84940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return results;
85040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
85140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
85240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	filter: function(object, fn, bind){
85340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var results = {};
85440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
85540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var value = object[key];
85640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
85740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
85840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return results;
85940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
86040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
86140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	every: function(object, fn, bind){
86240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
86340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
86440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
86540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
86640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
86740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
86840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	some: function(object, fn, bind){
86940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
87040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;
87140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
87240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return false;
87340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
87440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
87540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	keys: function(object){
87640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var keys = [];
87740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
87840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key)) keys.push(key);
87940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
88040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return keys;
88140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
88240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
88340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	values: function(object){
88440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var values = [];
88540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
88640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key)) values.push(object[key]);
88740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
88840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return values;
88940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
89040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
89140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getLength: function(object){
89240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Object.keys(object).length;
89340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
89440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
89540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	keyOf: function(object, value){
89640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var key in object){
89740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOwnProperty.call(object, key) && object[key] === value) return key;
89840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
89940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
90040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
90140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
90240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	contains: function(object, value){
90340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Object.keyOf(object, value) != null;
90440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
90540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
90640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toQueryString: function(object, base){
90740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var queryString = [];
90840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
90940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Object.each(object, function(value, key){
91040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (base) key = base + '[' + key + ']';
91140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var result;
91240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			switch (typeOf(value)){
91340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				case 'object': result = Object.toQueryString(value, key); break;
91440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				case 'array':
91540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					var qs = {};
91640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					value.each(function(val, i){
91740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						qs[i] = val;
91840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					});
91940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					result = Object.toQueryString(qs, key);
92040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				break;
92140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				default: result = key + '=' + encodeURIComponent(value);
92240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
92340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (value != null) queryString.push(result);
92440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
92540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
92640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return queryString.join('&');
92740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
92840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
92940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
93040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
93240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
93740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
93840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
93940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Browser
94040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
94140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
94240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
94340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
94440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
94540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Array, Function, Number, String]
94640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
94740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Browser, Window, Document]
94840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
94940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
95040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
95140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
95240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
95340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
95440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar document = this.document;
95540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar window = document.window = this;
95640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
95740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar parse = function(ua, platform){
95840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	ua = ua.toLowerCase();
95940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	platform = (platform ? platform.toLowerCase() : '');
96040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
96140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [null, 'unknown', 0];
96240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
96340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (UA[1] == 'trident'){
96440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		UA[1] = 'ie';
96540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (UA[4]) UA[2] = UA[4];
96640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (UA[1] == 'crios') {
96740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		UA[1] = 'chrome';
96840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
96940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
97040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var platform = ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0];
97140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (platform == 'win') platform = 'windows';
97240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
97340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return {
97440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		extend: Function.prototype.extend,
97540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		name: (UA[1] == 'version') ? UA[3] : UA[1],
97640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		version: parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
97740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		platform: platform
97840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
97940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
98040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
98140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Browser = this.Browser = parse(navigator.userAgent, navigator.platform);
98240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
98340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (Browser.ie){
98440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Browser.version = document.documentMode;
98540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
98640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
98740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikBrowser.extend({
98840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Features: {
98940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xpath: !!(document.evaluate),
99040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		air: !!(window.runtime),
99140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		query: !!(document.querySelector),
99240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		json: !!(window.JSON)
99340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
99440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	parseUA: parse
99540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
99640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
99740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
99840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
99940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Request
100040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
100140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikBrowser.Request = (function(){
100240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
100340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var XMLHTTP = function(){
100440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return new XMLHttpRequest();
100540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
100640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
100740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var MSXML2 = function(){
100840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return new ActiveXObject('MSXML2.XMLHTTP');
100940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
101040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
101140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var MSXML = function(){
101240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return new ActiveXObject('Microsoft.XMLHTTP');
101340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
101440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
101540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return Function.attempt(function(){
101640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		XMLHTTP();
101740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return XMLHTTP;
101840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}, function(){
101940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		MSXML2();
102040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return MSXML2;
102140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}, function(){
102240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		MSXML();
102340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return MSXML;
102440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
102540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
102640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
102740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
102840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikBrowser.Features.xhr = !!(Browser.Request);
102940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
103040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
103140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
103240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// String scripts
103340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
103440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikBrowser.exec = function(text){
103540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!text) return text;
103640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (window.execScript){
103740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		window.execScript(text);
103840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else {
103940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var script = document.createElement('script');
104040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		script.setAttribute('type', 'text/javascript');
104140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		script.text = text;
104240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		document.head.appendChild(script);
104340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		document.head.removeChild(script);
104440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
104540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return text;
104640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
104740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
104840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikString.implement('stripScripts', function(exec){
104940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var scripts = '';
105040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
105140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		scripts += code + '\n';
105240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return '';
105340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
105440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (exec === true) Browser.exec(scripts);
105540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (typeOf(exec) == 'function') exec(scripts, text);
105640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return text;
105740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
105840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
105940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Window, Document
106040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
106140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikBrowser.extend({
106240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Document: this.Document,
106340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Window: this.Window,
106440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element: this.Element,
106540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Event: this.Event
106640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
106740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
106840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.Window = this.$constructor = new Type('Window', function(){});
106940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
107040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.$family = Function.from('window').hide();
107140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
107240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikWindow.mirror(function(name, method){
107340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	window[name] = method;
107440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
107540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
107640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.Document = document.$constructor = new Type('Document', function(){});
107740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
107840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdocument.$family = Function.from('document').hide();
107940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
108040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDocument.mirror(function(name, method){
108140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	document[name] = method;
108240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
108340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
108440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdocument.html = document.documentElement;
108540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!document.head) document.head = document.getElementsByTagName('head')[0];
108640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
108740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (document.execCommand) try {
108840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	document.execCommand("BackgroundImageCache", false, true);
108940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} catch (e){}
109040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
109140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
109240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (this.attachEvent && !this.addEventListener){
109340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var unloadEvent = function(){
109440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.detachEvent('onunload', unloadEvent);
109540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		document.head = document.html = document.window = null;
109640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
109740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.attachEvent('onunload', unloadEvent);
109840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
109940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
110040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// IE fails on collections and <select>.options (refers to <select>)
110140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar arrayFrom = Array.from;
110240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiktry {
110340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	arrayFrom(document.html.childNodes);
110440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} catch(e){
110540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Array.from = function(item){
110640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
110740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var i = item.length, array = new Array(i);
110840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			while (i--) array[i] = item[i];
110940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return array;
111040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
111140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return arrayFrom(item);
111240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
111340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
111440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var prototype = Array.prototype,
111540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		slice = prototype.slice;
111640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
111740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var method = prototype[name];
111840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array[name] = function(item){
111940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return method.apply(Array.from(item), slice.call(arguments, 1));
112040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
112140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
112240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
112340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
112440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
112540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
112640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
112740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
112840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
112940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
113040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
113140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
113240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
113340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Event
113440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
113540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains the Event Type, to make the event object cross-browser.
113640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
113740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
113840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
113940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Window, Document, Array, Function, String, Object]
114040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
114140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Event
114240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
114340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
114440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
114540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
114640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function() {
114740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
114840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar _keys = {};
114940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
115040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){
115140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!win) win = window;
115240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	event = event || win.event;
115340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (event.$extended) return event;
115440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.event = event;
115540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.$extended = true;
115640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.shift = event.shiftKey;
115740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.control = event.ctrlKey;
115840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.alt = event.altKey;
115940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.meta = event.metaKey;
116040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var type = this.type = event.type;
116140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var target = event.target || event.srcElement;
116240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (target && target.nodeType == 3) target = target.parentNode;
116340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.target = document.id(target);
116440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
116540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (type.indexOf('key') == 0){
116640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var code = this.code = (event.which || event.keyCode);
116740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.key = _keys[code];
116840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (type == 'keydown' || type == 'keyup'){
116940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (code > 111 && code < 124) this.key = 'f' + (code - 111);
117040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else if (code > 95 && code < 106) this.key = code - 96;
117140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
117240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.key == null) this.key = String.fromCharCode(code).toLowerCase();
117340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
117440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var doc = win.document;
117540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
117640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.page = {
117740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
117840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
117940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
118040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.client = {
118140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
118240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
118340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
118440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (type == 'DOMMouseScroll' || type == 'mousewheel')
118540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
118640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
118740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.rightClick = (event.which == 3 || event.button == 2);
118840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (type == 'mouseover' || type == 'mouseout'){
118940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
119040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			while (related && related.nodeType == 3) related = related.parentNode;
119140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.relatedTarget = document.id(related);
119240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
119340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
119440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.rotation = event.rotation;
119540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.scale = event.scale;
119640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.targetTouches = event.targetTouches;
119740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.changedTouches = event.changedTouches;
119840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var touches = this.touches = event.touches;
119940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (touches && touches[0]){
120040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var touch = touches[0];
120140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.page = {x: touch.pageX, y: touch.pageY};
120240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.client = {x: touch.clientX, y: touch.clientY};
120340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
120440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
120540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
120640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!this.client) this.client = {};
120740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!this.page) this.page = {};
120840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
120940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
121040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDOMEvent.implement({
121140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
121240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	stop: function(){
121340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.preventDefault().stopPropagation();
121440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
121540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
121640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	stopPropagation: function(){
121740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.event.stopPropagation) this.event.stopPropagation();
121840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else this.event.cancelBubble = true;
121940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
122040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
122140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
122240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	preventDefault: function(){
122340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.event.preventDefault) this.event.preventDefault();
122440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else this.event.returnValue = false;
122540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
122640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
122740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
122840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
122940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
123040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDOMEvent.defineKey = function(code, key){
123140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	_keys[code] = key;
123240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
123340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
123440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
123540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);
123640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
123740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDOMEvent.defineKeys({
123840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'38': 'up', '40': 'down', '37': 'left', '39': 'right',
123940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
124040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'46': 'delete', '13': 'enter'
124140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
124240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
124440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
124940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
125040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
125140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
125240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
125340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Class
125440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
125540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains the Class Function for easily creating, extending, and implementing reusable Classes.
125640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
125740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
125840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
125940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Array, String, Function, Number]
126040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
126140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Class
126240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
126340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
126440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
126540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
126640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
126740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
126840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Class = this.Class = new Type('Class', function(params){
126940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (instanceOf(params, Function)) params = {initialize: params};
127040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
127140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var newClass = function(){
127240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		reset(this);
127340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (newClass.$prototyping) return this;
127440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$caller = null;
127540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
127640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$caller = this.caller = null;
127740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return value;
127840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.extend(this).implement(params);
127940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
128040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	newClass.$constructor = Class;
128140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	newClass.prototype.$constructor = newClass;
128240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	newClass.prototype.parent = parent;
128340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
128440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return newClass;
128540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
128640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
128740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar parent = function(){
128840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!this.$caller) throw new Error('The method "parent" cannot be called.');
128940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var name = this.$caller.$name,
129040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parent = this.$caller.$owner.parent,
129140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		previous = (parent) ? parent.prototype[name] : null;
129240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!previous) throw new Error('The method "' + name + '" has no parent.');
129340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return previous.apply(this, arguments);
129440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
129540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
129640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar reset = function(object){
129740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var key in object){
129840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var value = object[key];
129940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (typeOf(value)){
130040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'object':
130140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var F = function(){};
130240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				F.prototype = value;
130340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				object[key] = reset(new F);
130440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			break;
130540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'array': object[key] = value.clone(); break;
130640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
130740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
130840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return object;
130940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
131040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
131140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar wrap = function(self, key, method){
131240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (method.$origin) method = method.$origin;
131340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var wrapper = function(){
131440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
131540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var caller = this.caller, current = this.$caller;
131640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.caller = current; this.$caller = wrapper;
131740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var result = method.apply(this, arguments);
131840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$caller = current; this.caller = caller;
131940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return result;
132040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.extend({$owner: self, $origin: method, $name: key});
132140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return wrapper;
132240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
132340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
132440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar implement = function(key, value, retain){
132540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (Class.Mutators.hasOwnProperty(key)){
132640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		value = Class.Mutators[key].call(this, value);
132740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (value == null) return this;
132840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
132940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
133040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (typeOf(value) == 'function'){
133140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (value.$hidden) return this;
133240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.prototype[key] = (retain) ? value : wrap(this, key, value);
133340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else {
133440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Object.merge(this.prototype, key, value);
133540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
133640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
133740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
133840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
133940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
134040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar getInstance = function(klass){
134140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	klass.$prototyping = true;
134240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var proto = new klass;
134340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	delete klass.$prototyping;
134440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return proto;
134540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
134640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
134740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikClass.implement('implement', implement.overloadSetter());
134840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
134940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikClass.Mutators = {
135040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
135140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: function(parent){
135240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.parent = parent;
135340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.prototype = getInstance(parent);
135440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
135540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
135640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Implements: function(items){
135740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.from(items).each(function(item){
135840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var instance = new item;
135940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var key in instance) implement.call(this, key, instance[key], true);
136040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}, this);
136140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
136240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
136340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
136440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
136540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
136640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
136740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
136840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
136940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
137040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Class.Extras
137140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
137240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.
137340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
137440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
137540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
137640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Class
137740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
137840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Class.Extras, Chain, Events, Options]
137940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
138040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
138140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
138240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
138340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
138440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
138540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.Chain = new Class({
138640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
138740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	$chain: [],
138840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
138940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	chain: function(){
139040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$chain.append(Array.flatten(arguments));
139140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
139240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
139340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
139440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	callChain: function(){
139540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
139640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
139740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
139840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clearChain: function(){
139940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$chain.empty();
140040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
140140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
140240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
140340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
140440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
140540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar removeOn = function(string){
140640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return string.replace(/^on([A-Z])/, function(full, first){
140740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return first.toLowerCase();
140840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
140940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
141040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
141140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.Events = new Class({
141240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
141340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	$events: {},
141440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
141540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvent: function(type, fn, internal){
141640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		type = removeOn(type);
141740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
141840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
141940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
142040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.$events[type] = (this.$events[type] || []).include(fn);
142140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (internal) fn.internal = true;
142240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
142340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
142440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
142540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvents: function(events){
142640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var type in events) this.addEvent(type, events[type]);
142740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
142840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
142940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
143040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	fireEvent: function(type, args, delay){
143140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		type = removeOn(type);
143240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = this.$events[type];
143340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events) return this;
143440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		args = Array.from(args);
143540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		events.each(function(fn){
143640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (delay) fn.delay(delay, this, args);
143740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else fn.apply(this, args);
143840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}, this);
143940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
144040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
144140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
144240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvent: function(type, fn){
144340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		type = removeOn(type);
144440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = this.$events[type];
144540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (events && !fn.internal){
144640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var index =  events.indexOf(fn);
144740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (index != -1) delete events[index];
144840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
144940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
145040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
145140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
145240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvents: function(events){
145340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var type;
145440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(events) == 'object'){
145540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (type in events) this.removeEvent(type, events[type]);
145640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this;
145740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
145840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (events) events = removeOn(events);
145940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (type in this.$events){
146040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (events && events != type) continue;
146140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var fns = this.$events[type];
146240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var i = fns.length; i--;) if (i in fns){
146340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.removeEvent(type, fns[i]);
146440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
146540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
146640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
146740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
146840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
146940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
147040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
147140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikthis.Options = new Class({
147240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
147340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setOptions: function(){
147440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
147540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.addEvent) for (var option in options){
147640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
147740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.addEvent(option, options[option]);
147840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete options[option];
147940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
148040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
148140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
148240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
148340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
148440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
148540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
148640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
148740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
148840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
148940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
149040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Slick.Parser
149140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Standalone CSS3 Selector parser
149240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Slick.Parser
149340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
149440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
149540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
149640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik;(function(){
149740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
149840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar parsed,
149940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	separatorIndex,
150040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	combinatorIndex,
150140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reversed,
150240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	cache = {},
150340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reverseCache = {},
150440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reUnescape = /\\/g;
150540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
150640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar parse = function(expression, isReversed){
150740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (expression == null) return null;
150840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (expression.Slick === true) return expression;
150940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	expression = ('' + expression).replace(/^\s+|\s+$/g, '');
151040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reversed = !!isReversed;
151140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var currentCache = (reversed) ? reverseCache : cache;
151240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (currentCache[expression]) return currentCache[expression];
151340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	parsed = {
151440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Slick: true,
151540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		expressions: [],
151640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		raw: expression,
151740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		reverse: function(){
151840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return parse(this.raw, true);
151940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
152040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
152140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	separatorIndex = -1;
152240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (expression != (expression = expression.replace(regexp, parser)));
152340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	parsed.length = parsed.expressions.length;
152440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
152540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
152640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
152740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar reverseCombinator = function(combinator){
152840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (combinator === '!') return ' ';
152940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (combinator === ' ') return '!';
153040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
153140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else return '!' + combinator;
153240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
153340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
153440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar reverse = function(expression){
153540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var expressions = expression.expressions;
153640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = 0; i < expressions.length; i++){
153740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var exp = expressions[i];
153840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
153940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
154040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var j = 0; j < exp.length; j++){
154140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var cexp = exp[j];
154240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
154340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			cexp.combinator = cexp.reverseCombinator;
154440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete cexp.reverseCombinator;
154540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
154640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
154740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		exp.reverse().push(last);
154840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
154940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return expression;
155040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
155140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
155240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
155340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
155440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return '\\' + match;
155540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
155640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
155740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
155840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar regexp = new RegExp(
155940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
156040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik#!/usr/bin/env ruby
156140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikputs "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
156240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik__END__
156340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	"(?x)^(?:\
156440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	  \\s* ( , ) \\s*               # Separator          \n\
156540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	| \\s* ( <combinator>+ ) \\s*   # Combinator         \n\
156640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	|      ( \\s+ )                 # CombinatorChildren \n\
156740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	|      ( <unicode>+ | \\* )     # Tag                \n\
156840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	| \\#  ( <unicode>+       )     # ID                 \n\
156940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	| \\.  ( <unicode>+       )     # ClassName          \n\
157040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	|                               # Attribute          \n\
157140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	\\[  \
157240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		\\s* (<unicode1>+)  (?:  \
157340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			\\s* ([*^$!~|]?=)  (?:  \
157440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				\\s* (?:\
157540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					([\"']?)(.*?)\\9 \
157640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				)\
157740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			)  \
157840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		)?  \\s*  \
157940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	\\](?!\\]) \n\
158040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	|   :+ ( <unicode>+ )(?:\
158140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	\\( (?:\
158240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
158340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	) \\)\
158440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	)?\
158540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	)"
158640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
158740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	"^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
158840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	.replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
158940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	.replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
159040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	.replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
159140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik);
159240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
159340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction parser(
159440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	rawMatch,
159540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
159640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	separator,
159740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	combinator,
159840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	combinatorChildren,
159940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
160040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	tagName,
160140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	id,
160240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	className,
160340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
160440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attributeKey,
160540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attributeOperator,
160640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attributeQuote,
160740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	attributeValue,
160840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
160940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pseudoMarker,
161040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pseudoClass,
161140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pseudoQuote,
161240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pseudoClassQuotedValue,
161340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pseudoClassValue
161440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik){
161540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (separator || separatorIndex === -1){
161640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parsed.expressions[++separatorIndex] = [];
161740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		combinatorIndex = -1;
161840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (separator) return '';
161940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
162040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
162140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (combinator || combinatorChildren || combinatorIndex === -1){
162240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		combinator = combinator || ' ';
162340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var currentSeparator = parsed.expressions[separatorIndex];
162440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (reversed && currentSeparator[combinatorIndex])
162540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
162640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
162740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
162840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
162940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
163040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
163140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (tagName){
163240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.tag = tagName.replace(reUnescape, '');
163340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
163440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (id){
163540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.id = id.replace(reUnescape, '');
163640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
163740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (className){
163840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		className = className.replace(reUnescape, '');
163940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
164040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!currentParsed.classList) currentParsed.classList = [];
164140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!currentParsed.classes) currentParsed.classes = [];
164240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.classList.push(className);
164340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.classes.push({
164440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value: className,
164540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
164640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
164740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
164840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (pseudoClass){
164940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
165040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
165140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
165240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!currentParsed.pseudos) currentParsed.pseudos = [];
165340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.pseudos.push({
165440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			key: pseudoClass.replace(reUnescape, ''),
165540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value: pseudoClassValue,
165640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			type: pseudoMarker.length == 1 ? 'class' : 'element'
165740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
165840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
165940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (attributeKey){
166040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		attributeKey = attributeKey.replace(reUnescape, '');
166140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		attributeValue = (attributeValue || '').replace(reUnescape, '');
166240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
166340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var test, regexp;
166440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
166540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (attributeOperator){
166640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '^=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue)            ); break;
166740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '$=' : regexp = new RegExp(            escapeRegExp(attributeValue) +'$'       ); break;
166840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
166940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '|=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue) +'(-|$)'   ); break;
167040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case  '=' : test = function(value){
167140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return attributeValue == value;
167240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}; break;
167340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '*=' : test = function(value){
167440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return value && value.indexOf(attributeValue) > -1;
167540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}; break;
167640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case '!=' : test = function(value){
167740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return attributeValue != value;
167840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}; break;
167940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			default   : test = function(value){
168040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return !!value;
168140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			};
168240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
168340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
168440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
168540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return false;
168640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
168740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
168840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!test) test = function(value){
168940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return value && regexp.test(value);
169040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
169140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
169240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!currentParsed.attributes) currentParsed.attributes = [];
169340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentParsed.attributes.push({
169440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			key: attributeKey,
169540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			operator: attributeOperator,
169640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value: attributeValue,
169740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			test: test
169840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
169940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
170040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
170140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
170240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return '';
170340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
170440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
170540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick NS
170640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
170740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Slick = (this.Slick || {});
170840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
170940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.parse = function(expression){
171040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return parse(expression);
171140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
171240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
171340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.escapeRegExp = escapeRegExp;
171440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
171540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!this.Slick) this.Slick = Slick;
171640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
171740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
171840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
171940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
172040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
172140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
172240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Slick.Finder
172340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: The new, superfast css selector engine.
172440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Slick.Finder
172540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Slick.Parser
172640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
172740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
172840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
172940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik;(function(){
173040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
173140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar local = {},
173240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	featuresCache = {},
173340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toString = Object.prototype.toString;
173440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
173540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Feature / Bug detection
173640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
173740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.isNativeCode = function(fn){
173840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (/\{\s*\[native code\]\s*\}/).test('' + fn);
173940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
174040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
174140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.isXML = function(document){
174240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
174340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	(document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
174440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
174540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
174640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.setDocument = function(document){
174740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
174840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
174940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var nodeType = document.nodeType;
175040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (nodeType == 9); // document
175140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (nodeType) document = document.ownerDocument; // node
175240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (document.navigator) document = document.document; // window
175340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else return;
175440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
175540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// check if it's the old document
175640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
175740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this.document === document) return;
175840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.document = document;
175940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
176040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// check if we have done feature detection on this document before
176140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
176240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var root = document.documentElement,
176340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		rootUid = this.getUIDXML(root),
176440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features = featuresCache[rootUid],
176540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		feature;
176640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
176740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (features){
176840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (feature in features){
176940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this[feature] = features[feature];
177040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
177140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return;
177240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
177340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
177440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features = featuresCache[rootUid] = {};
177540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
177640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.root = root;
177740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.isXMLDocument = this.isXML(document);
177840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
177940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.brokenStarGEBTN
178040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.starSelectsClosedQSA
178140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.idGetsName
178240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.brokenMixedCaseQSA
178340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.brokenGEBCN
178440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.brokenCheckedQSA
178540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.brokenEmptyAttributeQSA
178640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.isHTMLDocument
178740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= features.nativeMatchesSelector
178840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	= false;
178940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
179040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var starSelectsClosed, starSelectsComments,
179140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
179240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		brokenFormAttributeGetter;
179340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
179440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var selected, id = 'slick_uniqueid';
179540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var testNode = document.createElement('div');
179640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
179740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
179840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	testRoot.appendChild(testNode);
179940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
180040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// on non-HTML documents innerHTML and getElementsById doesnt work properly
180140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	try {
180240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		testNode.innerHTML = '<a id="'+id+'"></a>';
180340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features.isHTMLDocument = !!document.getElementById(id);
180440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} catch(e){};
180540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
180640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (features.isHTMLDocument){
180740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
180840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		testNode.style.display = 'none';
180940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
181040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// IE returns comment nodes for getElementsByTagName('*') for some documents
181140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		testNode.appendChild(document.createComment(''));
181240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
181340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
181440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
181540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
181640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			testNode.innerHTML = 'foo</foo>';
181740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			selected = testNode.getElementsByTagName('*');
181840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			starSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
181940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(e){};
182040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
182140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
182240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
182340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// IE returns elements with the name instead of just id for getElementsById for some documents
182440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
182540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>';
182640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			features.idGetsName = document.getElementById(id) === testNode.firstChild;
182740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(e){};
182840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
182940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (testNode.getElementsByClassName){
183040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
183140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// Safari 3.2 getElementsByClassName caches results
183240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
183340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
183440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.getElementsByClassName('b').length;
183540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.firstChild.className = 'b';
183640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);
183740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
183840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
183940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
184040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
184140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
184240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);
184340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
184440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
184540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
184640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
184740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
184840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (testNode.querySelectorAll){
184940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
185040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
185140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = 'foo</foo>';
185240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				selected = testNode.querySelectorAll('*');
185340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				features.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
185440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
185540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
185640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
185740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
185840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = '<a class="MiX"></a>';
185940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;
186040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
186140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
186240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// Webkit and Opera dont return selected options on querySelectorAll
186340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
186440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = '<select><option selected="selected">a</option></select>';
186540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);
186640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
186740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
186840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
186940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
187040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				testNode.innerHTML = '<a class=""></a>';
187140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0);
187240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e){};
187340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
187440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
187540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
187640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input
187740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
187840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			testNode.innerHTML = '<form action="s"><input id="action"/></form>';
187940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');
188040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(e){};
188140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
188240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// native matchesSelector function
188340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
188440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features.nativeMatchesSelector = root.matches || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
188540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (features.nativeMatchesSelector) try {
188640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// if matchesSelector trows errors on incorrect sintaxes we can use it
188740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			features.nativeMatchesSelector.call(root, ':slick');
188840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			features.nativeMatchesSelector = null;
188940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(e){};
189040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
189140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
189240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
189340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	try {
189440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		root.slick_expando = 1;
189540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete root.slick_expando;
189640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features.getUID = this.getUIDHTML;
189740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} catch(e) {
189840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		features.getUID = this.getUIDXML;
189940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
190040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
190140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	testRoot.removeChild(testNode);
190240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	testNode = selected = testRoot = null;
190340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
190440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// getAttribute
190540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
190640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){
190740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var method = this.attributeGetters[name];
190840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (method) return method.call(node);
190940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attributeNode = node.getAttributeNode(name);
191040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (attributeNode) ? attributeNode.nodeValue : null;
191140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(node, name){
191240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var method = this.attributeGetters[name];
191340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (method) ? method.call(node) : node.getAttribute(name);
191440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
191540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
191640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// hasAttribute
191740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
191840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
191940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return node.hasAttribute(attribute);
192040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(node, attribute) {
192140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node = node.getAttributeNode(attribute);
192240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !!(node && (node.specified || node.nodeValue));
192340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
192440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
192540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// contains
192640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// FIXME: Add specs: local.contains should be different for xml and html documents?
192740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var nativeRootContains = root && this.isNativeCode(root.contains),
192840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		nativeDocumentContains = document && this.isNativeCode(document.contains);
192940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
193040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.contains = (nativeRootContains && nativeDocumentContains) ? function(context, node){
193140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return context.contains(node);
193240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : (nativeRootContains && !nativeDocumentContains) ? function(context, node){
193340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		// IE8 does not have .contains on document.
193440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return context === node || ((context === document) ? document.documentElement : context).contains(node);
193540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : (root && root.compareDocumentPosition) ? function(context, node){
193640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return context === node || !!(context.compareDocumentPosition(node) & 16);
193740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(context, node){
193840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (node) do {
193940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node === context) return true;
194040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} while ((node = node.parentNode));
194140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return false;
194240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
194340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
194440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// document order sorting
194540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// credits to Sizzle (http://sizzlejs.com/)
194640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
194740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	features.documentSorter = (root.compareDocumentPosition) ? function(a, b){
194840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
194940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
195040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : ('sourceIndex' in root) ? function(a, b){
195140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!a.sourceIndex || !b.sourceIndex) return 0;
195240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return a.sourceIndex - b.sourceIndex;
195340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : (document.createRange) ? function(a, b){
195440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!a.ownerDocument || !b.ownerDocument) return 0;
195540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
195640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		aRange.setStart(a, 0);
195740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		aRange.setEnd(a, 0);
195840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		bRange.setStart(b, 0);
195940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		bRange.setEnd(b, 0);
196040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
196140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : null ;
196240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
196340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	root = null;
196440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
196540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (feature in features){
196640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this[feature] = features[feature];
196740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
196840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
196940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
197040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Main Method
197140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
197240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/,
197340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
197440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	qsaFailExpCache = {};
197540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
197640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.search = function(context, expression, append, first){
197740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
197840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var found = this.found = (first) ? null : (append || []);
197940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
198040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!context) return found;
198140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (context.navigator) context = context.document; // Convert the node from a window to a document
198240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else if (!context.nodeType) return found;
198340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
198440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// setup
198540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
198640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var parsed, i,
198740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		uniques = this.uniques = {},
198840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		hasOthers = !!(append && append.length),
198940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		contextIsDocument = (context.nodeType == 9);
199040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
199140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);
199240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
199340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// avoid duplicating items already in the append array
199440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true;
199540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
199640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// expression checks
199740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
199840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (typeof expression == 'string'){ // expression is a string
199940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
200040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*<simple-selectors-override>*/
200140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var simpleSelector = expression.match(reSimpleSelector);
200240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		simpleSelectors: if (simpleSelector) {
200340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
200440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var symbol = simpleSelector[1],
200540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				name = simpleSelector[2],
200640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				node, nodes;
200740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
200840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!symbol){
200940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
201040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (name == '*' && this.brokenStarGEBTN) break simpleSelectors;
201140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				nodes = context.getElementsByTagName(name);
201240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (first) return nodes[0] || null;
201340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				for (i = 0; node = nodes[i++];){
201440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
201540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
201640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
201740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else if (symbol == '#'){
201840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
201940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
202040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				node = context.getElementById(name);
202140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!node) return found;
202240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors;
202340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (first) return node || null;
202440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
202540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
202640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else if (symbol == '.'){
202740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
202840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors;
202940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (context.getElementsByClassName && !this.brokenGEBCN){
203040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					nodes = context.getElementsByClassName(name);
203140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (first) return nodes[0] || null;
203240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					for (i = 0; node = nodes[i++];){
203340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
203440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					}
203540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				} else {
203640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s|$)');
203740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					nodes = context.getElementsByTagName('*');
203840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					for (i = 0; node = nodes[i++];){
203940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						className = node.className;
204040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						if (!(className && matchClass.test(className))) continue;
204140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						if (first) return node;
204240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
204340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					}
204440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
204540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
204640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
204740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
204840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOthers) this.sort(found);
204940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (first) ? null : found;
205040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
205140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
205240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*</simple-selectors-override>*/
205340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
205440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*<query-selector-override>*/
205540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		querySelector: if (context.querySelectorAll) {
205640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
205740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!this.isHTMLDocument
205840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| qsaFailExpCache[expression]
205940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				//TODO: only skip when expression is actually mixed case
206040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| this.brokenMixedCaseQSA
206140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)
206240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))
206340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| (!contextIsDocument //Abort when !contextIsDocument and...
206440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					//  there are multiple expressions in the selector
206540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					//  since we currently only fix non-document rooted QSA for single expression selectors
206640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					&& expression.indexOf(',') > -1
206740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				)
206840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				|| Slick.disableQSA
206940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			) break querySelector;
207040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
207140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var _expression = expression, _context = context;
207240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!contextIsDocument){
207340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				// non-document rooted QSA
207440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				// credits to Andrew Dupont
207540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var currentId = _context.getAttribute('id'), slickid = 'slickid__';
207640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				_context.setAttribute('id', slickid);
207740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				_expression = '#' + slickid + ' ' + _expression;
207840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				context = _context.parentNode;
207940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
208040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
208140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
208240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (first) return context.querySelector(_expression) || null;
208340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				else nodes = context.querySelectorAll(_expression);
208440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch(e) {
208540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				qsaFailExpCache[expression] = 1;
208640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				break querySelector;
208740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} finally {
208840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!contextIsDocument){
208940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (currentId) _context.setAttribute('id', currentId);
209040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					else _context.removeAttribute('id');
209140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					context = _context;
209240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
209340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
209440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
209540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
209640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node);
209740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else for (i = 0; node = nodes[i++];){
209840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
209940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
210040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
210140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (hasOthers) this.sort(found);
210240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return found;
210340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
210440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
210540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*</query-selector-override>*/
210640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
210740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parsed = this.Slick.parse(expression);
210840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!parsed.length) return found;
210940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (expression == null){ // there is no expression
211040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return found;
211140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (expression.Slick){ // expression is a parsed Slick object
211240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parsed = expression;
211340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else if (this.contains(context.documentElement || context, expression)){ // expression is a node
211440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(found) ? found.push(expression) : found = expression;
211540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return found;
211640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else { // other junk
211740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return found;
211840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
211940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
212040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
212140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
212240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// cache elements for the nth selectors
212340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
212440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.posNTH = {};
212540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.posNTHLast = {};
212640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.posNTHType = {};
212740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.posNTHTypeLast = {};
212840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
212940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
213040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
213140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// if append is null and there is only a single selector with one expression use pushArray, else use pushUID
213240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;
213340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
213440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (found == null) found = [];
213540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
213640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// default engine
213740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
213840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var j, m, n;
213940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var combinator, tag, id, classList, classes, attributes, pseudos;
214040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
214140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
214240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
214340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
214440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		combinator = 'combinator:' + currentBit.combinator;
214540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this[combinator]) continue search;
214640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
214740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		tag        = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();
214840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		id         = currentBit.id;
214940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		classList  = currentBit.classList;
215040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		classes    = currentBit.classes;
215140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		attributes = currentBit.attributes;
215240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		pseudos    = currentBit.pseudos;
215340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		lastBit    = (j === (currentExpression.length - 1));
215440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
215540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.bitUniques = {};
215640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
215740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (lastBit){
215840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.uniques = uniques;
215940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.found = found;
216040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
216140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.uniques = {};
216240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.found = [];
216340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
216440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
216540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (j === 0){
216640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this[combinator](context, tag, id, classes, attributes, pseudos, classList);
216740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (first && lastBit && found.length) break search;
216840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
216940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
217040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
217140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (found.length) break search;
217240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
217340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
217440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
217540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		currentItems = this.found;
217640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
217740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
217840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// should sort if there are nodes in append and if you pass multiple expressions.
217940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
218040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
218140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (first) ? (found[0] || null) : found;
218240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
218340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
218440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Utils
218540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
218640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.uidx = 1;
218740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.uidk = 'slick-uniqueid';
218840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
218940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.getUIDXML = function(node){
219040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var uid = node.getAttribute(this.uidk);
219140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!uid){
219240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		uid = this.uidx++;
219340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node.setAttribute(this.uidk, uid);
219440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
219540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return uid;
219640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
219740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
219840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.getUIDHTML = function(node){
219940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
220040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
220140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
220240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// sort based on the setDocument documentSorter method.
220340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
220440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.sort = function(results){
220540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!this.documentSorter) return results;
220640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	results.sort(this.documentSorter);
220740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return results;
220840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
220940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
221040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
221140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
221240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.cacheNTH = {};
221340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
221440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
221540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
221640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.parseNTHArgument = function(argument){
221740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var parsed = argument.match(this.matchNTH);
221840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!parsed) return false;
221940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var special = parsed[2] || false;
222040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var a = parsed[1] || 1;
222140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (a == '-') a = -1;
222240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var b = +parsed[3] || 0;
222340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	parsed =
222440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(special == 'n')	? {a: a, b: b} :
222540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(special == 'odd')	? {a: 2, b: 1} :
222640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(special == 'even')	? {a: 2, b: 0} : {a: 0, b: a};
222740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
222840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (this.cacheNTH[argument] = parsed);
222940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
223040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
223140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.createNTHPseudo = function(child, sibling, positions, ofType){
223240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return function(node, argument){
223340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var uid = this.getUID(node);
223440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this[positions][uid]){
223540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var parent = node.parentNode;
223640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!parent) return false;
223740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var el = parent[child], count = 1;
223840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (ofType){
223940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var nodeName = node.nodeName;
224040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				do {
224140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (el.nodeName != nodeName) continue;
224240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					this[positions][this.getUID(el)] = count++;
224340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				} while ((el = el[sibling]));
224440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else {
224540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				do {
224640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (el.nodeType != 1) continue;
224740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					this[positions][this.getUID(el)] = count++;
224840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				} while ((el = el[sibling]));
224940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
225040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
225140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		argument = argument || 'n';
225240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
225340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!parsed) return false;
225440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var a = parsed.a, b = parsed.b, pos = this[positions][uid];
225540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (a == 0) return b == pos;
225640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (a > 0){
225740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (pos < b) return false;
225840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
225940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (b < pos) return false;
226040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
226140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return ((pos - b) % a) == 0;
226240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
226340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
226440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
226540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
226640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
226740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.pushArray = function(node, tag, id, classes, attributes, pseudos){
226840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);
226940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
227040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
227140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.pushUID = function(node, tag, id, classes, attributes, pseudos){
227240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var uid = this.getUID(node);
227340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){
227440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.uniques[uid] = true;
227540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.found.push(node);
227640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
227740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
227840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
227940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.matchNode = function(node, selector){
228040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this.isHTMLDocument && this.nativeMatchesSelector){
228140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
228240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
228340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(matchError) {}
228440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
228540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
228640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var parsed = this.Slick.parse(selector);
228740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!parsed) return true;
228840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
228940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// simple (single) selectors
229040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var expressions = parsed.expressions, simpleExpCounter = 0, i;
229140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (i = 0; (currentExpression = expressions[i]); i++){
229240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (currentExpression.length == 1){
229340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var exp = currentExpression[0];
229440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
229540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			simpleExpCounter++;
229640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
229740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
229840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
229940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (simpleExpCounter == parsed.length) return false;
230040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
230140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var nodes = this.search(this.document, parsed), item;
230240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (i = 0; item = nodes[i++];){
230340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (item === node) return true;
230440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
230540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return false;
230640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
230740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
230840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.matchPseudo = function(node, name, argument){
230940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var pseudoName = 'pseudo:' + name;
231040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (this[pseudoName]) return this[pseudoName](node, argument);
231140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var attribute = this.getAttribute(node, name);
231240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (argument) ? argument == attribute : !!attribute;
231340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
231440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
231540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklocal.matchSelector = function(node, tag, id, classes, attributes, pseudos){
231640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (tag){
231740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase();
231840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (tag == '*'){
231940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (nodeName < '@') return false; // Fix for comment nodes and closed nodes
232040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
232140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (nodeName != tag) return false;
232240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
232340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
232440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
232540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (id && node.getAttribute('id') != id) return false;
232640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
232740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var i, part, cls;
232840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (classes) for (i = classes.length; i--;){
232940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		cls = this.getAttribute(node, 'class');
233040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!(cls && classes[i].regexp.test(cls))) return false;
233140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
233240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (attributes) for (i = attributes.length; i--;){
233340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		part = attributes[i];
233440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;
233540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
233640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (pseudos) for (i = pseudos.length; i--;){
233740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		part = pseudos[i];
233840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.matchPseudo(node, part.key, part.value)) return false;
233940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
234040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return true;
234140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
234240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
234340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar combinators = {
234440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
234540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
234640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
234740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var i, item, children;
234840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
234940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.isHTMLDocument){
235040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			getById: if (id){
235140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				item = this.document.getElementById(id);
235240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){
235340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					// all[id] returns all the elements with that name or id inside node
235440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					// if theres just one it will return the element, else it will be a collection
235540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					children = node.all[id];
235640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (!children) return;
235740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (!children[0]) children = [children];
235840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					for (i = 0; item = children[i++];){
235940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						var idNode = item.getAttributeNode('id');
236040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						if (idNode && idNode.nodeValue == id){
236140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik							this.push(item, tag, null, classes, attributes, pseudos);
236240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik							break;
236340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						}
236440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					}
236540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					return;
236640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
236740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!item){
236840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					// if the context is in the dom we return, else we will try GEBTN, breaking the getById label
236940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (this.contains(this.root, node)) return;
237040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					else break getById;
237140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				} else if (this.document !== node && !this.contains(node, item)) return;
237240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.push(item, tag, null, classes, attributes, pseudos);
237340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return;
237440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
237540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){
237640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				children = node.getElementsByClassName(classList.join(' '));
237740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!(children && children.length)) break getByClass;
237840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);
237940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return;
238040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
238140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
238240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		getByTag: {
238340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			children = node.getElementsByTagName(tag);
238440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!(children && children.length)) break getByTag;
238540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!this.brokenStarGEBTN) tag = null;
238640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
238740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
238840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
238940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
239040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'>': function(node, tag, id, classes, attributes, pseudos){ // direct children
239140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if ((node = node.firstChild)) do {
239240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
239340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} while ((node = node.nextSibling));
239440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
239540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
239640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
239740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.nextSibling)) if (node.nodeType == 1){
239840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.push(node, tag, id, classes, attributes, pseudos);
239940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			break;
240040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
240140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
240240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
240340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'^': function(node, tag, id, classes, attributes, pseudos){ // first child
240440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node = node.firstChild;
240540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (node){
240640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
240740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
240840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
240940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
241040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
241140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
241240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.nextSibling)){
241340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.nodeType != 1) continue;
241440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var uid = this.getUID(node);
241540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this.bitUniques[uid]) break;
241640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.bitUniques[uid] = true;
241740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.push(node, tag, id, classes, attributes, pseudos);
241840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
241940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
242040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
242140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling
242240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this['combinator:+'](node, tag, id, classes, attributes, pseudos);
242340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
242440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
242540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
242640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
242740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this['combinator:~'](node, tag, id, classes, attributes, pseudos);
242840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
242940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
243040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
243140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document
243240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
243340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
243440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
243540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
243640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node = node.parentNode;
243740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
243840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
243940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
244040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
244140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.previousSibling)) if (node.nodeType == 1){
244240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.push(node, tag, id, classes, attributes, pseudos);
244340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			break;
244440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
244540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
244640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
244740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'!^': function(node, tag, id, classes, attributes, pseudos){ // last child
244840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node = node.lastChild;
244940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (node){
245040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
245140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
245240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
245340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
245440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
245540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
245640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.previousSibling)){
245740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.nodeType != 1) continue;
245840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var uid = this.getUID(node);
245940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this.bitUniques[uid]) break;
246040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.bitUniques[uid] = true;
246140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.push(node, tag, id, classes, attributes, pseudos);
246240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
246340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
246440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
246540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
246640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
246740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfor (var c in combinators) local['combinator:' + c] = combinators[c];
246840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
246940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar pseudos = {
247040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
247140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<pseudo-selectors>*/
247240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
247340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'empty': function(node){
247440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var child = node.firstChild;
247540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
247640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
247740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
247840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'not': function(node, expression){
247940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !this.matchNode(node, expression);
248040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
248140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
248240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'contains': function(node, text){
248340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (node.innerText || node.textContent || '').indexOf(text) > -1;
248440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
248540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
248640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'first-child': function(node){
248740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
248840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
248940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
249040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
249140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'last-child': function(node){
249240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
249340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
249440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
249540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
249640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'only-child': function(node){
249740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var prev = node;
249840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;
249940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var next = node;
250040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
250140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
250240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
250340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
250440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<nth-pseudo-selectors>*/
250540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
250640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
250740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
250840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
250940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
251040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),
251140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
251240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),
251340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
251440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'index': function(node, index){
251540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this['pseudo:nth-child'](node, '' + (index + 1));
251640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
251740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
251840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'even': function(node){
251940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this['pseudo:nth-child'](node, '2n');
252040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
252140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
252240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'odd': function(node){
252340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this['pseudo:nth-child'](node, '2n+1');
252440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
252540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
252640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</nth-pseudo-selectors>*/
252740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
252840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*<of-type-pseudo-selectors>*/
252940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
253040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'first-of-type': function(node){
253140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var nodeName = node.nodeName;
253240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;
253340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
253440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
253540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
253640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'last-of-type': function(node){
253740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var nodeName = node.nodeName;
253840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;
253940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
254040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
254140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
254240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'only-of-type': function(node){
254340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var prev = node, nodeName = node.nodeName;
254440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;
254540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var next = node;
254640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;
254740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
254840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
254940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
255040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</of-type-pseudo-selectors>*/
255140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
255240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// custom pseudos
255340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
255440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'enabled': function(node){
255540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !node.disabled;
255640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
255740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
255840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'disabled': function(node){
255940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return node.disabled;
256040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
256140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
256240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'checked': function(node){
256340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return node.checked || node.selected;
256440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
256540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
256640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'focus': function(node){
256740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
256840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
256940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
257040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'root': function(node){
257140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (node === this.root);
257240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
257340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
257440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'selected': function(node){
257540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return node.selected;
257640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
257740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
257840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	/*</pseudo-selectors>*/
257940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
258040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
258140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfor (var p in pseudos) local['pseudo:' + p] = pseudos[p];
258240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
258340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// attributes methods
258440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
258540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar attributeGetters = local.attributeGetters = {
258640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
258740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'for': function(){
258840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
258940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
259040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
259140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'href': function(){
259240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');
259340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
259440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
259540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'style': function(){
259640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.style) ? this.style.cssText : this.getAttribute('style');
259740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
259840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
259940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'tabindex': function(){
260040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attributeNode = this.getAttributeNode('tabindex');
260140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
260240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
260340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
260440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'type': function(){
260540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getAttribute('type');
260640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
260740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
260840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'maxlength': function(){
260940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attributeNode = this.getAttributeNode('maxLength');
261040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
261140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
261240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
261340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
261440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
261540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikattributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxlength;
261640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
261740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick
261840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
261940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Slick = local.Slick = (this.Slick || {});
262040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
262140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.version = '1.1.7';
262240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
262340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick finder
262440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
262540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.search = function(context, expression, append){
262640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.search(context, expression, append);
262740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
262840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
262940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.find = function(context, expression){
263040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.search(context, expression, null, true);
263140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
263240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
263340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick containment checker
263440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
263540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.contains = function(container, node){
263640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.setDocument(container);
263740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.contains(container, node);
263840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
263940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
264040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick attribute getter
264140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
264240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.getAttribute = function(node, name){
264340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.setDocument(node);
264440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.getAttribute(node, name);
264540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
264640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
264740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.hasAttribute = function(node, name){
264840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.setDocument(node);
264940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.hasAttribute(node, name);
265040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
265140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
265240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick matcher
265340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
265440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.match = function(node, selector){
265540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!(node && selector)) return false;
265640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!selector || selector === node) return true;
265740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.setDocument(node);
265840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.matchNode(node, selector);
265940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
266040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
266140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick attribute accessor
266240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
266340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.defineAttributeGetter = function(name, fn){
266440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.attributeGetters[name] = fn;
266540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
266640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
266740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
266840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.lookupAttributeGetter = function(name){
266940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.attributeGetters[name];
267040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
267140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
267240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick pseudo accessor
267340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
267440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.definePseudo = function(name, fn){
267540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local['pseudo:' + name] = function(node, argument){
267640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return fn.call(node, argument);
267740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
267840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
267940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
268040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
268140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.lookupPseudo = function(name){
268240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var pseudo = local['pseudo:' + name];
268340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (pseudo) return function(argument){
268440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return pseudo.call(this, argument);
268540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
268640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return null;
268740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
268840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
268940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Slick overrides accessor
269040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
269140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.override = function(regexp, fn){
269240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	local.override(regexp, fn);
269340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
269440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
269540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
269640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.isXML = local.isXML;
269740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
269840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.uidOf = function(node){
269940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return local.getUIDHTML(node);
270040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
270140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
270240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!this.Slick) this.Slick = Slick;
270340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
270440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
270540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
270640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
270740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
270840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
270940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
271040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Element
271140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
271240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements.
271340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
271440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
271540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
271640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Window, Document, Array, String, Function, Object, Number, Slick.Parser, Slick.Finder]
271740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
271840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Element, Elements, $, $$, IFrame, Selectors]
271940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
272040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
272140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
272240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
272340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Element = this.Element = function(tag, props){
272440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var konstructor = Element.Constructors[tag];
272540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (konstructor) return konstructor(props);
272640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (typeof tag != 'string') return document.id(tag).set(props);
272740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
272840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!props) props = {};
272940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
273040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!(/^[\w-]+$/).test(tag)){
273140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parsed = Slick.parse(tag).expressions[0][0];
273240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		tag = (parsed.tag == '*') ? 'div' : parsed.tag;
273340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (parsed.id && props.id == null) props.id = parsed.id;
273440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
273540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attributes = parsed.attributes;
273640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
273740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			attr = attributes[i];
273840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (props[attr.key] != null) continue;
273940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
274040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
274140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else if (!attr.value && !attr.operator) props[attr.key] = true;
274240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
274340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
274440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
274540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
274640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
274740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return document.newElement(tag, props);
274840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
274940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
275040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
275140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (Browser.Element){
275240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.prototype = Browser.Element.prototype;
275340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	// IE8 and IE9 require the wrapping.
275440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.prototype._fireEvent = (function(fireEvent){
275540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return function(type, event){
275640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return fireEvent.call(this, type, event);
275740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
275840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	})(Element.prototype.fireEvent);
275940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
276040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
276140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiknew Type('Element', Element).mirror(function(name){
276240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (Array.prototype[name]) return;
276340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
276440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var obj = {};
276540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	obj[name] = function(){
276640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var results = [], args = arguments, elements = true;
276740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = this.length; i < l; i++){
276840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var element = this[i], result = results[i] = element[name].apply(element, args);
276940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			elements = (elements && typeOf(result) == 'element');
277040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
277140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (elements) ? new Elements(results) : results;
277240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
277340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
277440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Elements.implement(obj);
277540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
277640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
277740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!Browser.Element){
277840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.parent = Object;
277940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
278040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.Prototype = {
278140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		'$constructor': Element,
278240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		'$family': Function.from('element').hide()
278340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
278440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
278540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.mirror(function(name, method){
278640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Element.Prototype[name] = method;
278740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
278840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
278940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
279040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Constructors = {};
279140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
279240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
279340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
279440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar IFrame = new Type('IFrame', function(){
279540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var params = Array.link(arguments, {
279640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		properties: Type.isObject,
279740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		iframe: function(obj){
279840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (obj != null);
279940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
280040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
280140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
280240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var props = params.properties || {}, iframe;
280340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (params.iframe) iframe = document.id(params.iframe);
280440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var onload = props.onload || function(){};
280540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	delete props.onload;
280640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
280740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	iframe = new Element(iframe || 'iframe', props);
280840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
280940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var onLoad = function(){
281040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onload.call(iframe.contentWindow);
281140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
281240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
281340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (window.frames[props.id]) onLoad();
281440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	else iframe.addListener('load', onLoad);
281540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return iframe;
281640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
281740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
281840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Elements = this.Elements = function(nodes){
281940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (nodes && nodes.length){
282040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var uniques = {}, node;
282140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; node = nodes[i++];){
282240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var uid = Slick.uidOf(node);
282340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!uniques[uid]){
282440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				uniques[uid] = true;
282540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.push(node);
282640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
282740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
282840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
282940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
283040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
283140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElements.prototype = {length: 0};
283240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElements.parent = Array;
283340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
283440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiknew Type('Elements', Elements).implement({
283540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
283640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	filter: function(filter, bind){
283740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!filter) return this;
283840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
283940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return item.match(filter);
284040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} : filter, bind));
284140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect(),
284240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
284340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	push: function(){
284440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var length = this.length;
284540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = arguments.length; i < l; i++){
284640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var item = document.id(arguments[i]);
284740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (item) this[length++] = item;
284840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
284940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.length = length);
285040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect(),
285140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
285240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	unshift: function(){
285340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var items = [];
285440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = arguments.length; i < l; i++){
285540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var item = document.id(arguments[i]);
285640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (item) items.push(item);
285740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
285840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Array.prototype.unshift.apply(this, items);
285940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect(),
286040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
286140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	concat: function(){
286240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var newElements = new Elements(this);
286340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = arguments.length; i < l; i++){
286440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var item = arguments[i];
286540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (Type.isEnumerable(item)) newElements.append(item);
286640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else newElements.push(item);
286740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
286840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return newElements;
286940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect(),
287040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
287140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	append: function(collection){
287240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
287340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
287440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect(),
287540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
287640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	empty: function(){
287740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while (this.length) delete this[--this.length];
287840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
287940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.protect()
288040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
288140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
288240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
288340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
288440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
288540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
288640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
288740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// FF, IE
288840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
288940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
289040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiksplice.call(object, 1, 1);
289140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (object[1] == 1) Elements.implement('splice', function(){
289240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var length = this.length;
289340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var result = splice.apply(this, arguments);
289440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (length >= this.length) delete this[length--];
289540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return result;
289640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}.protect());
289740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
289840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.forEachMethod(function(method, name){
289940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Elements.implement(name, method);
290040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
290140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
290240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.mirror(Elements);
290340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
290440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE8>*/
290540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar createElementAcceptsHTML;
290640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiktry {
290740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x');
290840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} catch (e){}
290940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
291040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar escapeQuotes = function(html){
291140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
291240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
291340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE8>*/
291440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
291540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDocument.implement({
291640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
291740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	newElement: function(tag, props){
291840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (props && props.checked != null) props.defaultChecked = props.checked;
291940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
292040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (createElementAcceptsHTML && props){
292140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tag = '<' + tag;
292240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
292340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
292440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tag += '>';
292540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete props.name;
292640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete props.type;
292740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
292840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*</ltIE8>*/
292940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.id(this.createElement(tag)).set(props);
293040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
293140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
293240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
293340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
293440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
293540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
293640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
293740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
293840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.uidOf(window);
293940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSlick.uidOf(document);
294040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
294140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikDocument.implement({
294240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
294340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	newTextNode: function(text){
294440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.createTextNode(text);
294540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
294640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
294740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getDocument: function(){
294840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
294940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
295040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
295140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getWindow: function(){
295240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.window;
295340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
295440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
295540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	id: (function(){
295640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
295740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var types = {
295840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
295940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			string: function(id, nocash, doc){
296040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
296140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return (id) ? types.element(id, nocash) : null;
296240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			},
296340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
296440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			element: function(el, nocash){
296540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				Slick.uidOf(el);
296640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){
296740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					var fireEvent = el.fireEvent;
296840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					// wrapping needed in IE7, or else crash
296940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					el._fireEvent = function(type, event){
297040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						return fireEvent(type, event);
297140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					};
297240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					Object.append(el, Element.Prototype);
297340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
297440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return el;
297540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			},
297640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
297740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			object: function(obj, nocash, doc){
297840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (obj.toElement) return types.element(obj.toElement(doc), nocash);
297940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return null;
298040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
298140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
298240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
298340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
298440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		types.textnode = types.whitespace = types.window = types.document = function(zero){
298540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return zero;
298640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
298740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
298840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return function(el, nocash, doc){
298940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (el && el.$family && el.uniqueNumber) return el;
299040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var type = typeOf(el);
299140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (types[type]) ? types[type](el, nocash, doc || document) : null;
299240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
299340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
299440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	})()
299540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
299640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
299740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
299840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (window.$ == null) Window.implement('$', function(el, nc){
299940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return document.id(el, nc, this.document);
300040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
300140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
300240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikWindow.implement({
300340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
300440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getDocument: function(){
300540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.document;
300640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
300740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
300840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getWindow: function(){
300940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
301040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
301140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
301240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
301340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
301440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Document, Element].invoke('implement', {
301540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
301640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getElements: function(expression){
301740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Slick.search(this, expression, new Elements);
301840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
301940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
302040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getElement: function(expression){
302140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return document.id(Slick.find(this, expression));
302240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
302340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
302440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
302540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
302640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar contains = {contains: function(element){
302740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return Slick.contains(this, element);
302840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}};
302940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
303040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!document.contains) Document.implement(contains);
303140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!document.createElement('div').contains) Element.implement(contains);
303240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
303340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
303440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
303540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// tree walking
303640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
303740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar injectCombinator = function(expression, combinator){
303840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!expression) return combinator;
303940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
304040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	expression = Object.clone(Slick.parse(expression));
304140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
304240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var expressions = expression.expressions;
304340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = expressions.length; i--;)
304440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		expressions[i][0].combinator = combinator;
304540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
304640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return expression;
304740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
304840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
304940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.forEach({
305040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getNext: '~',
305140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getPrevious: '!~',
305240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getParent: '!'
305340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}, function(combinator, method){
305440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.implement(method, function(expression){
305540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getElement(injectCombinator(expression, combinator));
305640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
305740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
305840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
305940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.forEach({
306040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getAllNext: '~',
306140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getAllPrevious: '!~',
306240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getSiblings: '~~',
306340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getChildren: '>',
306440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getParents: '!'
306540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}, function(combinator, method){
306640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.implement(method, function(expression){
306740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getElements(injectCombinator(expression, combinator));
306840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
306940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
307040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
307140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
307240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
307340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getFirst: function(expression){
307440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
307540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
307640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
307740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getLast: function(expression){
307840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
307940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
308040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
308140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getWindow: function(){
308240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.ownerDocument.window;
308340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
308440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
308540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getDocument: function(){
308640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.ownerDocument;
308740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
308840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
308940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getElementById: function(id){
309040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
309140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
309240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
309340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	match: function(expression){
309440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !expression || Slick.match(this, expression);
309540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
309640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
309740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
309840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
309940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
310040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
310140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (window.$$ == null) Window.implement('$$', function(selector){
310240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (arguments.length == 1){
310340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
310440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else if (Type.isEnumerable(selector)) return new Elements(selector);
310540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
310640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return new Elements(arguments);
310740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
310840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
310940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Inserters
311040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
311140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar inserters = {
311240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
311340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	before: function(context, element){
311440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parent = element.parentNode;
311540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (parent) parent.insertBefore(context, element);
311640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
311740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
311840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	after: function(context, element){
311940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parent = element.parentNode;
312040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (parent) parent.insertBefore(context, element.nextSibling);
312140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
312240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
312340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	bottom: function(context, element){
312440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		element.appendChild(context);
312540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
312640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
312740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	top: function(context, element){
312840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		element.insertBefore(context, element.firstChild);
312940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
313040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
313240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikinserters.inside = inserters.bottom;
313440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// getProperty / setProperty
313840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
313940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar propertyGetters = {}, propertySetters = {};
314040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
314140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// properties
314240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
314340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar properties = {};
314440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.forEach([
314540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',
314640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'frameBorder', 'rowSpan', 'tabIndex', 'useMap'
314740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik], function(property){
314840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	properties[property.toLowerCase()] = property;
314940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
315040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
315140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikproperties.html = 'innerHTML';
315240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikproperties.text = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';
315340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
315440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.forEach(properties, function(real, key){
315540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	propertySetters[key] = function(node, value){
315640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node[real] = value;
315740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
315840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	propertyGetters[key] = function(node){
315940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return node[real];
316040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
316140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
316240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
316340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Booleans
316440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
316540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar bools = [
316640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
316740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
316840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
316940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'loop'
317040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik];
317140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
317240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar booleans = {};
317340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikArray.forEach(bools, function(bool){
317440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var lower = bool.toLowerCase();
317540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	booleans[lower] = bool;
317640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	propertySetters[lower] = function(node, value){
317740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node[bool] = !!value;
317840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
317940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	propertyGetters[lower] = function(node){
318040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !!node[bool];
318140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
318240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
318340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
318440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Special cases
318540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
318640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikObject.append(propertySetters, {
318740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
318840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'class': function(node, value){
318940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		('className' in node) ? node.className = (value || '') : node.setAttribute('class', value);
319040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
319140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
319240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'for': function(node, value){
319340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
319440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
319540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
319640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'style': function(node, value){
319740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(node.style) ? node.style.cssText = value : node.setAttribute('style', value);
319840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
319940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
320040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	'value': function(node, value){
320140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		node.value = (value != null) ? value : '';
320240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
320340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
320440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
320540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
320640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikpropertyGetters['class'] = function(node){
320740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return ('className' in node) ? node.className || null : node.getAttribute('class');
320840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
320940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
321040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/* <webkit> */
321140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar el = document.createElement('button');
321240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// IE sets type as readonly and throws
321340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiktry { el.type = 'button'; } catch(e){}
321440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (el.type != 'button') propertySetters.type = function(node, value){
321540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	node.setAttribute('type', value);
321640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
321740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel = null;
321840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/* </webkit> */
321940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
322040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<IE>*/
322140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar input = document.createElement('input');
322240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikinput.value = 't';
322340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikinput.type = 'submit';
322440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (input.value != 't') propertySetters.type = function(node, type){
322540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var value = node.value;
322640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	node.type = type;
322740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	node.value = value;
322840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
322940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikinput = null;
323040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</IE>*/
323140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
323240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/* getProperty, setProperty */
323340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
323440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/* <ltIE9> */
323540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar pollutesGetAttribute = (function(div){
323640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	div.random = 'attribute';
323740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (div.getAttribute('random') == 'attribute');
323840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})(document.createElement('div'));
323940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
324040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasCloneBug = (function(test){
324140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	test.innerHTML = '<object><param name="should_fix" value="the unknown"></object>';
324240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return test.cloneNode(true).firstChild.childNodes.length != 1;
324340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})(document.createElement('div'));
324440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/* </ltIE9> */
324540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
324640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasClassList = !!document.createElement('div').classList;
324740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
324840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar classes = function(className){
324940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var classNames = (className || '').clean().split(" "), uniques = {};
325040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return classNames.filter(function(className){
325140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (className !== "" && !uniques[className]) return uniques[className] = className;
325240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
325340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
325440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
325540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar addToClassList = function(name){
325640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.classList.add(name);
325740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
325840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
325940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar removeFromClassList = function(name){
326040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.classList.remove(name);
326140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
326240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
326340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
326440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
326540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setProperty: function(name, value){
326640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var setter = propertySetters[name.toLowerCase()];
326740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (setter){
326840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			setter(this, value);
326940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
327040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			/* <ltIE9> */
327140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var attributeWhiteList;
327240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (pollutesGetAttribute) attributeWhiteList = this.retrieve('$attributeWhiteList', {});
327340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			/* </ltIE9> */
327440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
327540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (value == null){
327640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.removeAttribute(name);
327740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				/* <ltIE9> */
327840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (pollutesGetAttribute) delete attributeWhiteList[name];
327940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				/* </ltIE9> */
328040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else {
328140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.setAttribute(name, '' + value);
328240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				/* <ltIE9> */
328340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (pollutesGetAttribute) attributeWhiteList[name] = true;
328440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				/* </ltIE9> */
328540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
328640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
328740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
328840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
328940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
329040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setProperties: function(attributes){
329140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
329240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
329340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
329440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
329540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getProperty: function(name){
329640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var getter = propertyGetters[name.toLowerCase()];
329740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (getter) return getter(this);
329840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/* <ltIE9> */
329940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (pollutesGetAttribute){
330040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {});
330140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!attr) return null;
330240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (attr.expando && !attributeWhiteList[name]){
330340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var outer = this.outerHTML;
330440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				// segment by the opening tag and find mention of attribute name
330540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(name) < 0) return null;
330640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				attributeWhiteList[name] = true;
330740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
330840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
330940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/* </ltIE9> */
331040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var result = Slick.getAttribute(this, name);
331140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (!result && !Slick.hasAttribute(this, name)) ? null : result;
331240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
331340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
331440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getProperties: function(){
331540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var args = Array.from(arguments);
331640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return args.map(this.getProperty, this).associate(args);
331740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
331840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
331940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeProperty: function(name){
332040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.setProperty(name, null);
332140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
332240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
332340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeProperties: function(){
332440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.each(arguments, this.removeProperty, this);
332540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
332640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
332740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
332840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(prop, value){
332940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var property = Element.Properties[prop];
333040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
333140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.overloadSetter(),
333240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
333340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(prop){
333440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var property = Element.Properties[prop];
333540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
333640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}.overloadGetter(),
333740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
333840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	erase: function(prop){
333940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var property = Element.Properties[prop];
334040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
334140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
334240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
334340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
334440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hasClass: hasClassList ? function(className){
334540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.classList.contains(className);
334640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(className){
334740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.className.clean().contains(className, ' ');
334840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
334940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
335040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addClass: hasClassList ? function(className){
335140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		classes(className).forEach(addToClassList, this);
335240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
335340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(className){
335440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.className = classes(className + ' ' + this.className).join(' ');
335540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
335640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
335740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
335840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeClass: hasClassList ? function(className){
335940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		classes(className).forEach(removeFromClassList, this);
336040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
336140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(className){
336240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var classNames = classes(this.className);
336340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		classes(className).forEach(classNames.erase, classNames);
336440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.className = classNames.join(' ');
336540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
336640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
336740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
336840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toggleClass: function(className, force){
336940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (force == null) force = !this.hasClass(className);
337040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (force) ? this.addClass(className) : this.removeClass(className);
337140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
337240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
337340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	adopt: function(){
337440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
337540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (length > 1) parent = fragment = document.createDocumentFragment();
337640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
337740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < length; i++){
337840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var element = document.id(elements[i], true);
337940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (element) parent.appendChild(element);
338040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
338140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
338240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (fragment) this.appendChild(fragment);
338340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
338440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
338540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
338640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
338740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	appendText: function(text, where){
338840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.grab(this.getDocument().newTextNode(text), where);
338940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
339040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
339140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	grab: function(el, where){
339240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		inserters[where || 'bottom'](document.id(el, true), this);
339340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
339440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
339540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
339640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	inject: function(el, where){
339740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		inserters[where || 'bottom'](this, document.id(el, true));
339840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
339940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
340040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
340140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	replaces: function(el){
340240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		el = document.id(el, true);
340340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		el.parentNode.replaceChild(this, el);
340440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
340540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
340640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
340740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	wraps: function(el, where){
340840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		el = document.id(el, true);
340940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.replaces(el).grab(el, where);
341040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
341140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
341240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getSelected: function(){
341340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.selectedIndex; // Safari 3.2.1
341440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return new Elements(Array.from(this.options).filter(function(option){
341540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return option.selected;
341640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}));
341740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
341840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
341940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	toQueryString: function(){
342040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var queryString = [];
342140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.getElements('input, select, textarea').each(function(el){
342240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var type = el.type;
342340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
342440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
342540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
342640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				// IE
342740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return document.id(opt).get('value');
342840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
342940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
343040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			Array.from(value).each(function(val){
343140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
343240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
343340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
343440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return queryString.join('&');
343540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
343640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
343740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
343840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
343940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
344040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// appendHTML
344140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
344240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar appendInserters = {
344340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	before: 'beforeBegin',
344440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	after: 'afterEnd',
344540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	bottom: 'beforeEnd',
344640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	top: 'afterBegin',
344740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	inside: 'beforeEnd'
344840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
344940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
345040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement('appendHTML', ('insertAdjacentHTML' in document.createElement('div')) ? function(html, where){
345140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.insertAdjacentHTML(appendInserters[where || 'bottom'], html);
345240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
345340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : function(html, where){
345440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var temp = new Element('div', {html: html}),
345540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		children = temp.childNodes,
345640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		fragment = temp.firstChild;
345740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
345840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!fragment) return this;
345940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (children.length > 1){
346040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		fragment = document.createDocumentFragment();
346140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0, l = children.length; i < l; i++){
346240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			fragment.appendChild(children[i]);
346340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
346440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
346540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
346640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	inserters[where || 'bottom'](fragment, this);
346740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return this;
346840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
346940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
347040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar collected = {}, storage = {};
347140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
347240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar get = function(uid){
347340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (storage[uid] || (storage[uid] = {}));
347440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
347540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
347640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar clean = function(item){
347740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var uid = item.uniqueNumber;
347840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item.removeEvents) item.removeEvents();
347940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (item.clearAttributes) item.clearAttributes();
348040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (uid != null){
348140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete collected[uid];
348240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete storage[uid];
348340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
348440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return item;
348540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
348640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
348740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar formProps = {input: 'checked', option: 'selected', textarea: 'value'};
348840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
348940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
349040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
349140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	destroy: function(){
349240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var children = clean(this).getElementsByTagName('*');
349340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.each(children, clean);
349440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Element.dispose(this);
349540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
349640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
349740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
349840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	empty: function(){
349940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.from(this.childNodes).each(Element.dispose);
350040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
350140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
350240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
350340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	dispose: function(){
350440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.parentNode) ? this.parentNode.removeChild(this) : this;
350540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
350640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
350740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clone: function(contents, keepid){
350840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		contents = contents !== false;
350940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
351040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
351140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (contents){
351240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			ce.append(Array.from(clone.getElementsByTagName('*')));
351340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			te.append(Array.from(this.getElementsByTagName('*')));
351440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
351540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
351640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (i = ce.length; i--;){
351740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var node = ce[i], element = te[i];
351840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!keepid) node.removeAttribute('id');
351940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			/*<ltIE9>*/
352040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (node.clearAttributes){
352140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				node.clearAttributes();
352240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				node.mergeAttributes(element);
352340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				node.removeAttribute('uniqueNumber');
352440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (node.options){
352540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					var no = node.options, eo = element.options;
352640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					for (var j = no.length; j--;) no[j].selected = eo[j].selected;
352740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
352840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
352940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			/*</ltIE9>*/
353040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var prop = formProps[element.tagName.toLowerCase()];
353140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (prop && element[prop]) node[prop] = element[prop];
353240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
353340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
353440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*<ltIE9>*/
353540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (hasCloneBug){
353640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');
353740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
353840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
353940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*</ltIE9>*/
354040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return document.id(clone);
354140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
354240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
354340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
354440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
354540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Element, Window, Document].invoke('implement', {
354640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
354740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addListener: function(type, fn){
354840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (window.attachEvent && !window.addEventListener){
354940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			collected[Slick.uidOf(this)] = this;
355040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
355140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
355240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else this.attachEvent('on' + type, fn);
355340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
355440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
355540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
355640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeListener: function(type, fn){
355740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
355840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else this.detachEvent('on' + type, fn);
355940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
356040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
356140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
356240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	retrieve: function(property, dflt){
356340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var storage = get(Slick.uidOf(this)), prop = storage[property];
356440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (dflt != null && prop == null) prop = storage[property] = dflt;
356540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return prop != null ? prop : null;
356640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
356740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
356840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	store: function(property, value){
356940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var storage = get(Slick.uidOf(this));
357040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		storage[property] = value;
357140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
357240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
357340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
357440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	eliminate: function(property){
357540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var storage = get(Slick.uidOf(this));
357640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete storage[property];
357740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
357840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
357940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
358040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
358140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
358240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
358340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (window.attachEvent && !window.addEventListener){
358440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var gc = function(){
358540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Object.each(collected, clean);
358640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (window.CollectGarbage) CollectGarbage();
358740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		window.removeListener('unload', gc);
358840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
358940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	window.addListener('unload', gc);
359040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
359140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
359240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
359340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties = {};
359440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
359540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
359640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
359740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.style = {
359840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
359940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(style){
360040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.style.cssText = style;
360140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
360240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
360340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
360440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.style.cssText;
360540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
360640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
360740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	erase: function(){
360840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.style.cssText = '';
360940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
361040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
361140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
361240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
361340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.tag = {
361440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
361540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
361640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.tagName.toLowerCase();
361740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
361840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
361940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
362040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
362140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.html = {
362240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
362340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(html){
362440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (html == null) html = '';
362540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else if (typeOf(html) == 'array') html = html.join('');
362640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.innerHTML = html;
362740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
362840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
362940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	erase: function(){
363040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.innerHTML = '';
363140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
363240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
363340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
363440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
363540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar supportsHTML5Elements = true, supportsTableInnerHTML = true, supportsTRInnerHTML = true;
363640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
363740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
363840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// technique by jdbarlett - http://jdbartlett.com/innershiv/
363940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar div = document.createElement('div');
364040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdiv.innerHTML = '<nav></nav>';
364140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraiksupportsHTML5Elements = (div.childNodes.length == 1);
364240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!supportsHTML5Elements){
364340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '),
364440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		fragment = document.createDocumentFragment(), l = tags.length;
364540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (l--) fragment.createElement(tags[l]);
364640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
364740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdiv = null;
364840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
364940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
365040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<IE>*/
365140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraiksupportsTableInnerHTML = Function.attempt(function(){
365240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var table = document.createElement('table');
365340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	table.innerHTML = '<tr><td></td></tr>';
365440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return true;
365540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
365640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
365740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltFF4>*/
365840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar tr = document.createElement('tr'), html = '<td></td>';
365940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiktr.innerHTML = html;
366040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraiksupportsTRInnerHTML = (tr.innerHTML == html);
366140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiktr = null;
366240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltFF4>*/
366340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
366440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){
366540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
366640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.Properties.html.set = (function(set){
366740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
366840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var translations = {
366940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			table: [1, '<table>', '</table>'],
367040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			select: [1, '<select>', '</select>'],
367140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tbody: [2, '<table><tbody>', '</tbody></table>'],
367240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
367340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
367440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
367540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		translations.thead = translations.tfoot = translations.tbody;
367640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
367740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return function(html){
367840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var wrap = translations[this.get('tag')];
367940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];
368040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!wrap) return set.call(this, html);
368140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
368240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var level = wrap[0], wrapper = document.createElement('div'), target = wrapper;
368340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!supportsHTML5Elements) fragment.appendChild(wrapper);
368440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');
368540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			while (level--) target = target.firstChild;
368640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.empty().adopt(target.childNodes);
368740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!supportsHTML5Elements) fragment.removeChild(wrapper);
368840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			wrapper = null;
368940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
369040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
369140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	})(Element.Properties.html.set);
369240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
369340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</IE>*/
369440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
369540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
369640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar testForm = document.createElement('form');
369740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraiktestForm.innerHTML = '<select><option>s</option></select>';
369840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
369940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (testForm.firstChild.value != 's') Element.Properties.value = {
370040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
370140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(value){
370240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var tag = this.get('tag');
370340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (tag != 'select') return this.setProperty('value', value);
370440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var options = this.getElements('option');
370540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		value = String(value);
370640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var i = 0; i < options.length; i++){
370740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var option = options[i],
370840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				attr = option.getAttributeNode('value'),
370940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				optionValue = (attr && attr.specified) ? option.value : option.get('text');
371040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (optionValue === value) return option.selected = true;
371140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
371240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
371340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
371440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
371540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var option = this, tag = option.get('tag');
371640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
371740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (tag != 'select' && tag != 'option') return this.getProperty('value');
371840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
371940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (tag == 'select' && !(option = option.getSelected()[0])) return '';
372040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
372140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attr = option.getAttributeNode('value');
372240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (attr && attr.specified) ? option.value : option.get('text');
372340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
372440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
372540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
372640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraiktestForm = null;
372740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
372840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
372940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<IE>*/
373040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (document.createElement('div').getAttributeNode('id')) Element.Properties.id = {
373140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(id){
373240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.id = this.getAttributeNode('id').value = id;
373340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
373440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
373540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.id || null;
373640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
373740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	erase: function(){
373840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.id = this.getAttributeNode('id').value = '';
373940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
374040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
374140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</IE>*/
374240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
374340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
374440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
374540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
374640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
374740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
374840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
374940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Element.Style
375040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
375140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains methods for interacting with the styles of Elements in a fashionable way.
375240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
375340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
375440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
375540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Element
375640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
375740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Element.Style
375840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
375940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
376040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
376140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
376240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
376340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
376440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar html = document.html, el;
376540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
376640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//<ltIE9>
376740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Check for oldIE, which does not remove styles when they're set to null
376840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel = document.createElement('div');
376940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel.style.color = 'red';
377040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel.style.color = null;
377140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar doesNotRemoveStyles = el.style.color == 'red';
377240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
377340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// check for oldIE, which returns border* shorthand styles in the wrong order (color-width-style instead of width-style-color)
377440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar border = '1px solid #123abc';
377540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel.style.border = border;
377640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar returnsBordersInWrongOrder = el.style.border != border;
377740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikel = null;
377840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//</ltIE9>
377940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
378040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasGetComputedStyle = !!window.getComputedStyle;
378140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
378240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.styles = {set: function(styles){
378340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.setStyles(styles);
378440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}};
378540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
378640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar hasOpacity = (html.style.opacity != null),
378740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hasFilter = (html.style.filter != null),
378840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reAlpha = /alpha\(opacity=([\d.]+)\)/i;
378940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
379040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar setVisibility = function(element, opacity){
379140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	element.store('$opacity', opacity);
379240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	element.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden';
379340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
379440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
379540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//<ltIE9>
379640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar setFilter = function(element, regexp, value){
379740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var style = element.style,
379840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		filter = style.filter || element.getComputedStyle('filter') || '';
379940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	style.filter = (regexp.test(filter) ? filter.replace(regexp, value) : filter + ' ' + value).trim();
380040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!style.filter) style.removeAttribute('filter');
380140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
380240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//</ltIE9>
380340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
380440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar setOpacity = (hasOpacity ? function(element, opacity){
380540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	element.style.opacity = opacity;
380640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : (hasFilter ? function(element, opacity){
380740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
380840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (opacity == null || opacity == 1){
380940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		setFilter(element, reAlpha, '');
381040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (opacity == 1 && getOpacity(element) != 1) setFilter(element, reAlpha, 'alpha(opacity=100)');
381140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} else {
381240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		setFilter(element, reAlpha, 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')');
381340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
381440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : setVisibility));
381540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
381640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar getOpacity = (hasOpacity ? function(element){
381740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var opacity = element.style.opacity || element.getComputedStyle('opacity');
381840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (opacity == '') ? 1 : opacity.toFloat();
381940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : (hasFilter ? function(element){
382040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var filter = (element.style.filter || element.getComputedStyle('filter')),
382140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		opacity;
382240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (filter) opacity = filter.match(reAlpha);
382340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
382440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : function(element){
382540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var opacity = element.retrieve('$opacity');
382640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);
382740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return opacity;
382840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}));
382940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
383040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat',
383140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	namedPositions = {left: '0%', top: '0%', center: '50%', right: '100%', bottom: '100%'},
383240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hasBackgroundPositionXY = (html.style.backgroundPositionX != null);
383340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
383440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//<ltIE9>
383540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar removeStyle = function(style, property){
383640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (property == 'backgroundPosition'){
383740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		style.removeAttribute(property + 'X');
383840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		property += 'Y';
383940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
384040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	style.removeAttribute(property);
384140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
384240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//</ltIE9>
384340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
384440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
384540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
384640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getComputedStyle: function(property){
384740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!hasGetComputedStyle && this.currentStyle) return this.currentStyle[property.camelCase()];
384840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var defaultView = Element.getDocument(this).defaultView,
384940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
385040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : '';
385140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
385240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
385340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setStyle: function(property, value){
385440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (property == 'opacity'){
385540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (value != null) value = parseFloat(value);
385640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			setOpacity(this, value);
385740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this;
385840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
385940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		property = (property == 'float' ? floatName : property).camelCase();
386040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(value) != 'string'){
386140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var map = (Element.Styles[property] || '@').split(' ');
386240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value = Array.from(value).map(function(val, i){
386340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!map[i]) return '';
386440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
386540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}).join(' ');
386640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else if (value == String(Number(value))){
386740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value = Math.round(value);
386840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
386940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.style[property] = value;
387040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		//<ltIE9>
387140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if ((value == '' || value == null) && doesNotRemoveStyles && this.style.removeAttribute){
387240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			removeStyle(this.style, property);
387340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
387440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		//</ltIE9>
387540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
387640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
387740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
387840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getStyle: function(property){
387940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (property == 'opacity') return getOpacity(this);
388040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		property = (property == 'float' ? floatName : property).camelCase();
388140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var result = this.style[property];
388240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!result || property == 'zIndex'){
388340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (Element.ShortStyles.hasOwnProperty(property)){
388440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				result = [];
388540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				for (var s in Element.ShortStyles[property]) result.push(this.getStyle(s));
388640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return result.join(' ');
388740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
388840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			result = this.getComputedStyle(property);
388940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
389040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (hasBackgroundPositionXY && /^backgroundPosition[XY]?$/.test(property)){
389140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return result.replace(/(top|right|bottom|left)/g, function(position){
389240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return namedPositions[position];
389340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}) || '0px';
389440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
389540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!result && property == 'backgroundPosition') return '0px 0px';
389640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (result){
389740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			result = String(result);
389840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var color = result.match(/rgba?\([\d\s,]+\)/);
389940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (color) result = result.replace(color[0], color[0].rgbToHex());
390040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
390140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!hasGetComputedStyle && !this.style[property]){
390240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if ((/^(height|width)$/).test(property) && !(/px$/.test(result))){
390340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
390440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				values.each(function(value){
390540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
390640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}, this);
390740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return this['offset' + property.capitalize()] - size + 'px';
390840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
390940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if ((/^border(.+)Width|margin|padding/).test(property) && isNaN(parseFloat(result))){
391040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return '0px';
391140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
391240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
391340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		//<ltIE9>
391440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (returnsBordersInWrongOrder && /^border(Top|Right|Bottom|Left)?$/.test(property) && /^#/.test(result)){
391540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return result.replace(/^(.+)\s(.+)\s(.+)$/, '$2 $3 $1');
391640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
391740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		//</ltIE9>
391840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return result;
391940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
392040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
392140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setStyles: function(styles){
392240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var style in styles) this.setStyle(style, styles[style]);
392340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
392440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
392540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
392640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getStyles: function(){
392740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var result = {};
392840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.flatten(arguments).each(function(key){
392940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			result[key] = this.getStyle(key);
393040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}, this);
393140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return result;
393240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
393340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
393440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
393540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
393640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Styles = {
393740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	left: '@px', top: '@px', bottom: '@px', right: '@px',
393840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
393940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	backgroundColor: 'rgb(@, @, @)', backgroundSize: '@px', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
394040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
394140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
394240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
394340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
394440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
394540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
394640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
394740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
394840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
394940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
395040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
395140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
395240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
395340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var Short = Element.ShortStyles;
395440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var All = Element.Styles;
395540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	['margin', 'padding'].each(function(style){
395640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var sd = style + direction;
395740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Short[style][sd] = All[sd] = '@px';
395840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
395940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var bd = 'border' + direction;
396040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
396140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
396240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Short[bd] = {};
396340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
396440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
396540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
396640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
396740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
396840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (hasBackgroundPositionXY) Element.ShortStyles.backgroundPosition = {backgroundPositionX: '@', backgroundPositionY: '@'};
396940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
397040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
397140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
397240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
397340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
397440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
397540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Element.Event
397640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
397740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events, if necessary.
397840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
397940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
398040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
398140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Element, Event]
398240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
398340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Element.Event
398440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
398540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
398640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
398740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
398840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
398940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
399040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.events = {set: function(events){
399140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	this.addEvents(events);
399240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}};
399340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
399440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Element, Window, Document].invoke('implement', {
399540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
399640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvent: function(type, fn){
399740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = this.retrieve('events', {});
399840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events[type]) events[type] = {keys: [], values: []};
399940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (events[type].keys.contains(fn)) return this;
400040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		events[type].keys.push(fn);
400140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var realType = type,
400240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			custom = Element.Events[type],
400340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			condition = fn,
400440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			self = this;
400540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (custom){
400640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (custom.onAdd) custom.onAdd.call(this, fn, type);
400740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (custom.condition){
400840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				condition = function(event){
400940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (custom.condition.call(this, event, type)) return fn.call(this, event);
401040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					return true;
401140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				};
401240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
401340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (custom.base) realType = Function.from(custom.base).call(this, type);
401440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
401540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var defn = function(){
401640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return fn.call(self);
401740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
401840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var nativeEvent = Element.NativeEvents[realType];
401940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (nativeEvent){
402040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (nativeEvent == 2){
402140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				defn = function(event){
402240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					event = new DOMEvent(event, self.getWindow());
402340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (condition.call(self, event) === false) event.stop();
402440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				};
402540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
402640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.addListener(realType, defn, arguments[2]);
402740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
402840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		events[type].values.push(defn);
402940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
403040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
403140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
403240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvent: function(type, fn){
403340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = this.retrieve('events');
403440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events || !events[type]) return this;
403540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var list = events[type];
403640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var index = list.keys.indexOf(fn);
403740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (index == -1) return this;
403840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var value = list.values[index];
403940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete list.keys[index];
404040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		delete list.values[index];
404140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var custom = Element.Events[type];
404240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (custom){
404340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (custom.onRemove) custom.onRemove.call(this, fn, type);
404440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (custom.base) type = Function.from(custom.base).call(this, type);
404540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
404640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;
404740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
404840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
404940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvents: function(events){
405040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var event in events) this.addEvent(event, events[event]);
405140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
405240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
405340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
405440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvents: function(events){
405540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var type;
405640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(events) == 'object'){
405740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (type in events) this.removeEvent(type, events[type]);
405840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this;
405940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
406040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var attached = this.retrieve('events');
406140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!attached) return this;
406240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events){
406340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (type in attached) this.removeEvents(type);
406440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.eliminate('events');
406540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else if (attached[events]){
406640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			attached[events].keys.each(function(fn){
406740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.removeEvent(events, fn);
406840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}, this);
406940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete attached[events];
407040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
407140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
407240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
407340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
407440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	fireEvent: function(type, args, delay){
407540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = this.retrieve('events');
407640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events || !events[type]) return this;
407740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		args = Array.from(args);
407840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
407940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		events[type].keys.each(function(fn){
408040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (delay) fn.delay(delay, this, args);
408140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else fn.apply(this, args);
408240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}, this);
408340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
408440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
408540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
408640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	cloneEvents: function(from, type){
408740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		from = document.id(from);
408840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var events = from.retrieve('events');
408940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!events) return this;
409040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!type){
409140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			for (var eventType in events) this.cloneEvents(from, eventType);
409240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else if (events[type]){
409340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			events[type].keys.each(function(fn){
409440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.addEvent(type, fn);
409540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}, this);
409640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
409740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
409840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
409940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
410040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
410140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
410240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.NativeEvents = {
410340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
410440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
410540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
410640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	keydown: 2, keypress: 2, keyup: 2, //keyboard
410740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	orientationchange: 2, // mobile
410840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
410940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
411040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements
411140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
411240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	hashchange: 1, popstate: 2, // history
411340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	error: 1, abort: 1, scroll: 1 //misc
411440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
411540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
411640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Events = {
411740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mousewheel: {
411840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll'
411940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
412040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
412140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
412240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar check = function(event){
412340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var related = event.relatedTarget;
412440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (related == null) return true;
412540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!related) return false;
412640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));
412740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
412840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
412940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif ('onmouseenter' in document.documentElement){
413040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;
413140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.MouseenterCheck = check;
413240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} else {
413340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.Events.mouseenter = {
413440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'mouseover',
413540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		condition: check
413640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
413740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
413840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.Events.mouseleave = {
413940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'mouseout',
414040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		condition: check
414140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
414240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
414340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
414440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
414540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!window.addEventListener){
414640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.NativeEvents.propertychange = 2;
414740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Element.Events.change = {
414840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: function(){
414940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var type = this.type;
415040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change';
415140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
415240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		condition: function(event){
415340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return event.type != 'propertychange' || event.event.propertyName == 'checked';
415440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
415540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
415640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
415740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
415840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
415940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
416240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
416540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
416640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Element.Delegation
416840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
416940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Extends the Element native object to include the delegate method for more efficient event management.
417040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
417140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
417240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
417340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Element.Event]
417440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
417540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Element.Delegation]
417640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
417740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
417840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
417940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
418040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
418140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
418240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar eventListenerSupport = !!window.addEventListener;
418340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
418440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.NativeEvents.focusin = Element.NativeEvents.focusout = 2;
418540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
418640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar bubbleUp = function(self, match, fn, event, target){
418740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	while (target && target != self){
418840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (match(target, event)) return fn.call(target, event, target);
418940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		target = document.id(target.parentNode);
419040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
419140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
419240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
419340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar map = {
419440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mouseenter: {
419540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'mouseover',
419640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		condition: Element.MouseenterCheck
419740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
419840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	mouseleave: {
419940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'mouseout',
420040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		condition: Element.MouseenterCheck
420140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
420240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	focus: {
420340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'focus' + (eventListenerSupport ? '' : 'in'),
420440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		capture: true
420540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
420640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	blur: {
420740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: eventListenerSupport ? 'blur' : 'focusout',
420840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		capture: true
420940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
421040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
421140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
421240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE9>*/
421340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar _key = '$delegation:';
421440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar formObserver = function(type){
421540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
421640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return {
421740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
421840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'focusin',
421940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
422040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		remove: function(self, uid){
422140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var list = self.retrieve(_key + type + 'listeners', {})[uid];
422240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (list && list.forms) for (var i = list.forms.length; i--;){
422340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				list.forms[i].removeEvent(type, list.fns[i]);
422440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
422540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
422640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
422740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		listen: function(self, match, fn, event, target, uid){
422840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var form = (target.get('tag') == 'form') ? target : event.target.getParent('form');
422940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!form) return;
423040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
423140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var listeners = self.retrieve(_key + type + 'listeners', {}),
423240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				listener = listeners[uid] || {forms: [], fns: []},
423340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				forms = listener.forms, fns = listener.fns;
423440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
423540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (forms.indexOf(form) != -1) return;
423640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			forms.push(form);
423740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
423840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var _fn = function(event){
423940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				bubbleUp(self, match, fn, event, target);
424040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			};
424140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			form.addEvent(type, _fn);
424240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			fns.push(_fn);
424340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
424440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			listeners[uid] = listener;
424540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			self.store(_key + type + 'listeners', listeners);
424640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
424740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
424840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
424940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
425040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar inputObserver = function(type){
425140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return {
425240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		base: 'focusin',
425340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		listen: function(self, match, fn, event, target){
425440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var events = {blur: function(){
425540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.removeEvents(events);
425640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}};
425740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			events[type] = function(event){
425840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				bubbleUp(self, match, fn, event, target);
425940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			};
426040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			event.target.addEvents(events);
426140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
426240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
426340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
426440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
426540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (!eventListenerSupport) Object.append(map, {
426640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	submit: formObserver('submit'),
426740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	reset: formObserver('reset'),
426840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	change: inputObserver('change'),
426940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	select: inputObserver('select')
427040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
427140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE9>*/
427240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
427340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar proto = Element.prototype,
427440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvent = proto.addEvent,
427540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvent = proto.removeEvent;
427640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
427740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar relay = function(old, method){
427840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return function(type, fn, useCapture){
427940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (type.indexOf(':relay') == -1) return old.call(this, type, fn, useCapture);
428040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parsed = Slick.parse(type).expressions[0][0];
428140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (parsed.pseudos[0].key != 'relay') return old.call(this, type, fn, useCapture);
428240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var newType = parsed.tag;
428340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parsed.pseudos.slice(1).each(function(pseudo){
428440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			newType += ':' + pseudo.key + (pseudo.value ? '(' + pseudo.value + ')' : '');
428540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
428640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		old.call(this, type, fn);
428740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return method.call(this, newType, parsed.pseudos[0].value, fn);
428840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
428940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
429040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
429140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar delegation = {
429240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
429340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvent: function(type, match, fn){
429440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var storage = this.retrieve('$delegates', {}), stored = storage[type];
429540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (stored) for (var _uid in stored){
429640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (stored[_uid].fn == fn && stored[_uid].match == match) return this;
429740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
429840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
429940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var _type = type, _match = match, _fn = fn, _map = map[type] || {};
430040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		type = _map.base || _type;
430140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
430240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		match = function(target){
430340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return Slick.match(target, _match);
430440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
430540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
430640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var elementEvent = Element.Events[_type];
430740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (_map.condition || elementEvent && elementEvent.condition){
430840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var __match = match, condition = _map.condition || elementEvent.condition;
430940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			match = function(target, event){
431040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return __match(target, event) && condition.call(target, event, type);
431140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			};
431240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
431340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
431440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var self = this, uid = String.uniqueID();
431540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var delegator = _map.listen ? function(event, target){
431640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!target && event && event.target) target = event.target;
431740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (target) _map.listen(self, match, fn, event, target, uid);
431840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} : function(event, target){
431940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (!target && event && event.target) target = event.target;
432040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (target) bubbleUp(self, match, fn, event, target);
432140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
432240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
432340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!stored) stored = {};
432440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		stored[uid] = {
432540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			match: _match,
432640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			fn: _fn,
432740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delegator: delegator
432840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
432940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		storage[_type] = stored;
433040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return addEvent.call(this, type, delegator, _map.capture);
433140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
433240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
433340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvent: function(type, match, fn, _uid){
433440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var storage = this.retrieve('$delegates', {}), stored = storage[type];
433540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!stored) return this;
433640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
433740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (_uid){
433840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var _type = type, delegator = stored[_uid].delegator, _map = map[type] || {};
433940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			type = _map.base || _type;
434040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (_map.remove) _map.remove(this, _uid);
434140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete stored[_uid];
434240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			storage[_type] = stored;
434340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return removeEvent.call(this, type, delegator, _map.capture);
434440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
434540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
434640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var __uid, s;
434740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (fn) for (__uid in stored){
434840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			s = stored[__uid];
434940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid);
435040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else for (__uid in stored){
435140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			s = stored[__uid];
435240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid);
435340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
435440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
435540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
435640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
435740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
435840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
435940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Element, Window, Document].invoke('implement', {
436040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	addEvent: relay(addEvent, delegation.addEvent),
436140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	removeEvent: relay(removeEvent, delegation.removeEvent)
436240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
436340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
436440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
436540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
436640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
436740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
436840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
436940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
437040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Element.Dimensions
437140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
437240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains methods to work with size, scroll, or positioning of Elements and the window object.
437340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
437440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
437540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
437640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikcredits:
437740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
437840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).
437940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
438040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Element, Element.Style]
438140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
438240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Element.Dimensions]
438340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
438440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
438540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
438640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
438740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
438840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
438940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar element = document.createElement('div'),
439040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	child = document.createElement('div');
439140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikelement.style.height = '0';
439240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikelement.appendChild(child);
439340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar brokenOffsetParent = (child.offsetParent === element);
439440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikelement = child = null;
439540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
439640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar isOffset = function(el){
439740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return styleString(el, 'position') != 'static' || isBody(el);
439840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
439940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
440040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar isOffsetStatic = function(el){
440140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
440240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
440340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
440440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
440540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
440640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	scrollTo: function(x, y){
440740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)){
440840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.getWindow().scrollTo(x, y);
440940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
441040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.scrollLeft = x;
441140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.scrollTop = y;
441240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
441340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
441440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
441540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
441640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getSize: function(){
441740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)) return this.getWindow().getSize();
441840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: this.offsetWidth, y: this.offsetHeight};
441940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
442040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
442140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollSize: function(){
442240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)) return this.getWindow().getScrollSize();
442340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: this.scrollWidth, y: this.scrollHeight};
442440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
442540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
442640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScroll: function(){
442740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)) return this.getWindow().getScroll();
442840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: this.scrollLeft, y: this.scrollTop};
442940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
443040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
443140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrolls: function(){
443240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var element = this.parentNode, position = {x: 0, y: 0};
443340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while (element && !isBody(element)){
443440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			position.x += element.scrollLeft;
443540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			position.y += element.scrollTop;
443640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			element = element.parentNode;
443740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
443840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return position;
443940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
444040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
444140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getOffsetParent: brokenOffsetParent ? function(){
444240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var element = this;
444340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
444440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
444540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset;
444640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while ((element = element.parentNode)){
444740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (isOffsetCheck(element)) return element;
444840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
444940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
445040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} : function(){
445140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var element = this;
445240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
445340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
445440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
445540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return element.offsetParent;
445640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch(e) {}
445740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return null;
445840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
445940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
446040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getOffsets: function(){
446140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var hasGetBoundingClientRect = this.getBoundingClientRect;
446240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
446340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (hasGetBoundingClientRect){
446440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var bound = this.getBoundingClientRect(),
446540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				html = document.id(this.getDocument().documentElement),
446640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				htmlScroll = html.getScroll(),
446740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				elemScrolls = this.getScrolls(),
446840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				isFixed = (styleString(this, 'position') == 'fixed');
446940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
447040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return {
447140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
447240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				y: bound.top.toInt()  + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
447340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			};
447440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
447540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
447640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var element = this, position = {x: 0, y: 0};
447740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)) return position;
447840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
447940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		while (element && !isBody(element)){
448040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			position.x += element.offsetLeft;
448140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			position.y += element.offsetTop;
448240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
448340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			element = element.offsetParent;
448440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
448540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
448640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return position;
448740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
448840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
448940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getPosition: function(relative){
449040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var offset = this.getOffsets(),
449140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			scroll = this.getScrolls();
449240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var position = {
449340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			x: offset.x - scroll.x,
449440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			y: offset.y - scroll.y
449540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
449640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
449740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (relative && (relative = document.id(relative))){
449840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var relativePosition = relative.getPosition();
449940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};
450040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
450140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return position;
450240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
450340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
450440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getCoordinates: function(element){
450540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (isBody(this)) return this.getWindow().getCoordinates();
450640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var position = this.getPosition(element),
450740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			size = this.getSize();
450840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var obj = {
450940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			left: position.x,
451040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			top: position.y,
451140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			width: size.x,
451240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			height: size.y
451340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
451440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		obj.right = obj.left + obj.width;
451540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		obj.bottom = obj.top + obj.height;
451640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return obj;
451740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
451840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
451940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	computePosition: function(obj){
452040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {
452140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			left: obj.x - styleNumber(this, 'margin-left'),
452240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			top: obj.y - styleNumber(this, 'margin-top')
452340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
452440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
452540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
452640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setPosition: function(obj){
452740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.setStyles(this.computePosition(obj));
452840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
452940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
453040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
453140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
453240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
453340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Document, Window].invoke('implement', {
453440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
453540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getSize: function(){
453640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var doc = getCompatElement(this);
453740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: doc.clientWidth, y: doc.clientHeight};
453840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
453940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
454040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScroll: function(){
454140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var win = this.getWindow(), doc = getCompatElement(this);
454240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
454340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
454440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
454540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollSize: function(){
454640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var doc = getCompatElement(this),
454740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			min = this.getSize(),
454840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			body = this.getDocument().body;
454940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
455040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
455140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
455240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
455340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getPosition: function(){
455440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {x: 0, y: 0};
455540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
455640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
455740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getCoordinates: function(){
455840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var size = this.getSize();
455940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
456040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
456140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
456240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
456340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
456440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// private methods
456540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
456640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar styleString = Element.getComputedStyle;
456740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
456840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction styleNumber(element, style){
456940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return styleString(element, style).toInt() || 0;
457040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
457140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
457240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction borderBox(element){
457340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return styleString(element, '-moz-box-sizing') == 'border-box';
457440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
457540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
457640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction topBorder(element){
457740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return styleNumber(element, 'border-top-width');
457840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
457940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
458040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction leftBorder(element){
458140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return styleNumber(element, 'border-left-width');
458240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
458340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
458440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction isBody(element){
458540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (/^(?:body|html)$/i).test(element.tagName);
458640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
458740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
458840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikfunction getCompatElement(element){
458940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var doc = element.getDocument();
459040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
459140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
459240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
459340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
459440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
459540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//aliases
459640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.alias({position: 'setPosition'}); //compatability
459740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
459840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik[Window, Document, Element].invoke('implement', {
459940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
460040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getHeight: function(){
460140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getSize().y;
460240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
460340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
460440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getWidth: function(){
460540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getSize().x;
460640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
460740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
460840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollTop: function(){
460940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getScroll().y;
461040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
461140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
461240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollLeft: function(){
461340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getScroll().x;
461440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
461540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
461640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollHeight: function(){
461740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getScrollSize().y;
461840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
461940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
462040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getScrollWidth: function(){
462140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getScrollSize().x;
462240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
462340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
462440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getTop: function(){
462540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getPosition().y;
462640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
462740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
462840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getLeft: function(){
462940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.getPosition().x;
463040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
463140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
463240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
463340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
463440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
463540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
463640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
463740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
463840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Fx
463940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
464040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains the basic animation logic to be extended by all other Fx Classes.
464140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
464240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
464340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
464440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Chain, Events, Options]
464540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
464640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Fx
464740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
464840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
464940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
465040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
465140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
465240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
465340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Fx = this.Fx = new Class({
465440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
465540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Implements: [Chain, Events, Options],
465640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
465740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	options: {
465840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*
465940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onStart: nil,
466040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onCancel: nil,
466140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onComplete: nil,
466240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		*/
466340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		fps: 60,
466440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		unit: false,
466540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		duration: 500,
466640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		frames: null,
466740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		frameSkip: true,
466840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		link: 'ignore'
466940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
467040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
467140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(options){
467240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.subject = this.subject || this;
467340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.setOptions(options);
467440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
467540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
467640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getTransition: function(){
467740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return function(p){
467840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return -(Math.cos(Math.PI * p) - 1) / 2;
467940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
468040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
468140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
468240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	step: function(now){
468340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.frameSkip){
468440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;
468540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.time = now;
468640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.frame += frames;
468740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
468840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.frame++;
468940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
469040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
469140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.frame < this.frames){
469240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var delta = this.transition(this.frame / this.frames);
469340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.set(this.compute(this.from, this.to, delta));
469440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else {
469540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.frame = this.frames;
469640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.set(this.compute(this.from, this.to, 1));
469740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.stop();
469840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
469940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
470040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
470140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(now){
470240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return now;
470340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
470440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
470540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	compute: function(from, to, delta){
470640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Fx.compute(from, to, delta);
470740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
470840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
470940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	check: function(){
471040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.isRunning()) return true;
471140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (this.options.link){
471240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'cancel': this.cancel(); return true;
471340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
471440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
471540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return false;
471640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
471740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
471840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	start: function(from, to){
471940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.check(from, to)) return this;
472040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.from = from;
472140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.to = to;
472240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.frame = (this.options.frameSkip) ? 0 : -1;
472340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.time = null;
472440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.transition = this.getTransition();
472540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration;
472640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.duration = Fx.Durations[duration] || duration.toInt();
472740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.frameInterval = 1000 / fps;
472840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.frames = frames || Math.round(this.duration / this.frameInterval);
472940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('start', this.subject);
473040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		pushInstance.call(this, fps);
473140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
473240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
473340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
473440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	stop: function(){
473540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.isRunning()){
473640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.time = null;
473740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			pullInstance.call(this, this.options.fps);
473840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (this.frames == this.frame){
473940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.fireEvent('complete', this.subject);
474040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
474140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} else {
474240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.fireEvent('stop', this.subject);
474340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
474440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
474540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
474640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
474740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
474840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	cancel: function(){
474940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.isRunning()){
475040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.time = null;
475140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			pullInstance.call(this, this.options.fps);
475240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.frame = this.frames;
475340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.fireEvent('cancel', this.subject).clearChain();
475440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
475540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
475640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
475740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
475840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	pause: function(){
475940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.isRunning()){
476040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.time = null;
476140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			pullInstance.call(this, this.options.fps);
476240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
476340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
476440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
476540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
476640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	resume: function(){
476740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.isPaused()) pushInstance.call(this, this.options.fps);
476840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
476940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
477040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
477140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	isRunning: function(){
477240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var list = instances[this.options.fps];
477340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return list && list.contains(this);
477440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
477540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
477640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	isPaused: function(){
477740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (this.frame < this.frames) && !this.isRunning();
477840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
477940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
478040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
478140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
478240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.compute = function(from, to, delta){
478340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (to - from) * delta + from;
478440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
478540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
478640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
478740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
478840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// global timers
478940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
479040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar instances = {}, timers = {};
479140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
479240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar loop = function(){
479340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var now = Date.now();
479440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = this.length; i--;){
479540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var instance = this[i];
479640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (instance) instance.step(now);
479740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
479840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
479940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
480040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar pushInstance = function(fps){
480140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var list = instances[fps] || (instances[fps] = []);
480240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	list.push(this);
480340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
480440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
480540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
480640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar pullInstance = function(fps){
480740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var list = instances[fps];
480840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (list){
480940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		list.erase(this);
481040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!list.length && timers[fps]){
481140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete instances[fps];
481240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			timers[fps] = clearInterval(timers[fps]);
481340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
481440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
481540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
481640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
481740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
481840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
481940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
482040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
482140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
482240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
482340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Fx.CSS
482440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
482540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.
482640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
482740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
482840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
482940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Fx, Element.Style]
483040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
483140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Fx.CSS
483240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
483340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
483440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
483540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
483640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.CSS = new Class({
483740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
483840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: Fx,
483940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
484040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//prepares the base from/to object
484140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
484240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	prepare: function(element, property, values){
484340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		values = Array.from(values);
484440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var from = values[0], to = values[1];
484540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (to == null){
484640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			to = from;
484740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			from = element.getStyle(property);
484840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var unit = this.options.unit;
484940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			// adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299
485040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (unit && from && typeof from == 'string' && from.slice(-unit.length) != unit && parseFloat(from) != 0){
485140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				element.setStyle(property, to + unit);
485240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var value = element.getComputedStyle(property);
485340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				// IE and Opera support pixelLeft or pixelWidth
485440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!(/px$/.test(value))){
485540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					value = element.style[('pixel-' + property).camelCase()];
485640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (value == null){
485740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						// adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
485840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						var left = element.style.left;
485940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						element.style.left = to + unit;
486040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						value = element.style.pixelLeft;
486140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik						element.style.left = left;
486240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					}
486340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
486440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				from = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0);
486540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				element.setStyle(property, from + unit);
486640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
486740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
486840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return {from: this.parse(from), to: this.parse(to)};
486940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
487040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
487140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//parses a value into an array
487240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
487340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	parse: function(value){
487440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		value = Function.from(value)();
487540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
487640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return value.map(function(val){
487740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			val = String(val);
487840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var found = false;
487940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			Object.each(Fx.CSS.Parsers, function(parser, key){
488040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (found) return;
488140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var parsed = parser.parse(val);
488240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (parsed || parsed === 0) found = {value: parsed, parser: parser};
488340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
488440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			found = found || {value: val, parser: Fx.CSS.Parsers.String};
488540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return found;
488640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
488740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
488840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
488940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//computes by a from and to prepared objects, using their parsers.
489040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
489140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	compute: function(from, to, delta){
489240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var computed = [];
489340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		(Math.min(from.length, to.length)).times(function(i){
489440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
489540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
489640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		computed.$family = Function.from('fx:css:value');
489740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return computed;
489840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
489940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
490040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//serves the value as settable
490140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
490240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	serve: function(value, unit){
490340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeOf(value) != 'fx:css:value') value = this.parse(value);
490440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var returned = [];
490540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		value.each(function(bit){
490640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			returned = returned.concat(bit.parser.serve(bit.value, unit));
490740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
490840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return returned;
490940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
491040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
491140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//renders the change to an element
491240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
491340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	render: function(element, property, value, unit){
491440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		element.setStyle(property, this.serve(value, unit));
491540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
491640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
491740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	//searches inside the page css to find the values for a selector
491840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
491940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	search: function(selector){
492040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
492140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
492240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
492340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var searchStyles = function(rules){
492440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			Array.each(rules, function(rule, i){
492540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (rule.media){
492640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					searchStyles(rule.rules || rule.cssRules);
492740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					return;
492840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}
492940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!rule.style) return;
493040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
493140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					return m.toLowerCase();
493240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				}) : null;
493340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (!selectorText || !selectorTest.test(selectorText)) return;
493440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				Object.each(Element.Styles, function(value, style){
493540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					if (!rule.style[style] || Element.ShortStyles[style]) return;
493640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					value = String(rule.style[style]);
493740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
493840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				});
493940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
494040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
494140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
494240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Array.each(document.styleSheets, function(sheet, j){
494340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var href = sheet.href;
494440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (href && href.indexOf('://') > -1 && href.indexOf(document.domain) == -1) return;
494540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var rules = sheet.rules || sheet.cssRules;
494640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			searchStyles(rules);
494740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
494840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Fx.CSS.Cache[selector] = to;
494940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
495040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
495140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
495240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
495340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.CSS.Cache = {};
495440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
495540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.CSS.Parsers = {
495640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
495740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Color: {
495840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parse: function(value){
495940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
496040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
496140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
496240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		compute: function(from, to, delta){
496340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return from.map(function(value, i){
496440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				return Math.round(Fx.compute(from[i], to[i], delta));
496540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
496640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
496740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		serve: function(value){
496840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return value.map(Number);
496940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
497040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
497140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
497240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Number: {
497340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parse: parseFloat,
497440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		compute: Fx.compute,
497540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		serve: function(value, unit){
497640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (unit) ? value + unit : value;
497740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
497840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
497940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
498040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	String: {
498140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		parse: Function.from(false),
498240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		compute: function(zero, one){
498340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return one;
498440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
498540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		serve: function(zero){
498640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return zero;
498740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
498840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
498940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
499140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
499640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
499740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
499840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Fx.Tween
499940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
500040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Formerly Fx.Style, effect to transition any CSS property for an element.
500140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
500240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
500340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
500440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Fx.CSS
500540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
500640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [Fx.Tween, Element.fade, Element.highlight]
500740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
500840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
500940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
501040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
501140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Tween = new Class({
501240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
501340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: Fx.CSS,
501440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
501540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(element, options){
501640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.element = this.subject = document.id(element);
501740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.parent(options);
501840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
501940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
502040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(property, now){
502140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (arguments.length == 1){
502240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			now = property;
502340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			property = this.property || this.options.property;
502440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
502540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.render(this.element, property, now, this.options.unit);
502640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
502740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
502840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
502940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	start: function(property, from, to){
503040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.check(property, from, to)) return this;
503140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var args = Array.flatten(arguments);
503240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.property = this.options.property || args.shift();
503340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var parsed = this.prepare(this.element, this.property, args);
503440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.parent(parsed.from, parsed.to);
503540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
503640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
503740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
503840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
503940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.tween = {
504040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
504140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(options){
504240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.get('tween').cancel().setOptions(options);
504340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
504440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
504540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
504640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
504740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var tween = this.retrieve('tween');
504840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!tween){
504940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tween = new Fx.Tween(this, {link: 'cancel'});
505040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.store('tween', tween);
505140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
505240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return tween;
505340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
505440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
505540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
505640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
505740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
505840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
505940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	tween: function(property, from, to){
506040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.get('tween').start(property, from, to);
506140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
506240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
506340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
506440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	fade: function(how){
506540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var fade = this.get('tween'), method, args = ['opacity'].append(arguments), toggle;
506640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (args[1] == null) args[1] = 'toggle';
506740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (args[1]){
506840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'in': method = 'start'; args[1] = 1; break;
506940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'out': method = 'start'; args[1] = 0; break;
507040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'show': method = 'set'; args[1] = 1; break;
507140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'hide': method = 'set'; args[1] = 0; break;
507240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'toggle':
507340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);
507440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				method = 'start';
507540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				args[1] = flag ? 0 : 1;
507640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.store('fade:flag', !flag);
507740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				toggle = true;
507840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			break;
507940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			default: method = 'start';
508040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
508140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!toggle) this.eliminate('fade:flag');
508240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		fade[method].apply(fade, args);
508340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var to = args[args.length - 1];
508440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
508540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else fade.chain(function(){
508640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.element.setStyle('visibility', 'hidden');
508740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.callChain();
508840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
508940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
509040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
509140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
509240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	highlight: function(start, end){
509340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!end){
509440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			end = this.retrieve('highlight:original', this.getStyle('background-color'));
509540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			end = (end == 'transparent') ? '#fff' : end;
509640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
509740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var tween = this.get('tween');
509840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		tween.start('background-color', start || '#ffff88', end).chain(function(){
509940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.setStyle('background-color', this.retrieve('highlight:original'));
510040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			tween.callChain();
510140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}.bind(this));
510240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
510340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
510440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
510540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
510640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
510740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
510840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
510940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
511040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
511140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Fx.Morph
511240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
511340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules.
511440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
511540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
511640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
511740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Fx.CSS
511840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
511940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Fx.Morph
512040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
512140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
512240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
512340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
512440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Morph = new Class({
512540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
512640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: Fx.CSS,
512740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
512840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(element, options){
512940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.element = this.subject = document.id(element);
513040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.parent(options);
513140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
513240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
513340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(now){
513440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof now == 'string') now = this.search(now);
513540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var p in now) this.render(this.element, p, now[p], this.options.unit);
513640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
513740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
513840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
513940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	compute: function(from, to, delta){
514040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var now = {};
514140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var p in from) now[p] = this.parent(from[p], to[p], delta);
514240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return now;
514340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
514440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
514540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	start: function(properties){
514640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.check(properties)) return this;
514740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof properties == 'string') properties = this.search(properties);
514840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var from = {}, to = {};
514940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var p in properties){
515040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var parsed = this.prepare(this.element, p, properties[p]);
515140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			from[p] = parsed.from;
515240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			to[p] = parsed.to;
515340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
515440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.parent(from, to);
515540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
515640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
515740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
515840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
515940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.morph = {
516040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
516140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(options){
516240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.get('morph').cancel().setOptions(options);
516340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
516440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
516540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
516640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
516740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var morph = this.retrieve('morph');
516840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!morph){
516940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			morph = new Fx.Morph(this, {link: 'cancel'});
517040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.store('morph', morph);
517140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
517240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return morph;
517340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
517440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
517540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
517640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
517740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
517840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
517940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	morph: function(props){
518040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.get('morph').start(props);
518140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
518240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
518340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
518440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
518540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
518640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
518740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
518840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
518940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
519040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Fx.Transitions
519140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
519240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains a set of advanced transitions to be used with any of the Fx Classes.
519340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
519440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
519540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
519640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikcredits:
519740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
519840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
519940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: Fx
520040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
520140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Fx.Transitions
520240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
520340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
520440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
520540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
520640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.implement({
520740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
520840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getTransition: function(){
520940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var trans = this.options.transition || Fx.Transitions.Sine.easeInOut;
521040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (typeof trans == 'string'){
521140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var data = trans.split(':');
521240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			trans = Fx.Transitions;
521340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			trans = trans[data[0]] || trans[data[0].capitalize()];
521440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
521540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
521640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return trans;
521740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
521840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
521940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
522040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
522140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Transition = function(transition, params){
522240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	params = Array.from(params);
522340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var easeIn = function(pos){
522440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return transition(pos, params);
522540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
522640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return Object.append(easeIn, {
522740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		easeIn: easeIn,
522840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		easeOut: function(pos){
522940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return 1 - transition(1 - pos, params);
523040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
523140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		easeInOut: function(pos){
523240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;
523340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
523440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
523540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
523640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
523740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Transitions = {
523840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
523940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	linear: function(zero){
524040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return zero;
524140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
524240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
524340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
524440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
524540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
524640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
524740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Transitions.extend = function(transitions){
524840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
524940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
525040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
525140f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikFx.Transitions.extend({
525240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
525340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Pow: function(p, x){
525440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.pow(p, x && x[0] || 6);
525540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
525640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
525740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Expo: function(p){
525840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.pow(2, 8 * (p - 1));
525940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
526040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
526140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Circ: function(p){
526240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return 1 - Math.sin(Math.acos(p));
526340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
526440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
526540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Sine: function(p){
526640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return 1 - Math.cos(p * Math.PI / 2);
526740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
526840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
526940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Back: function(p, x){
527040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		x = x && x[0] || 1.618;
527140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.pow(p, 2) * ((x + 1) * p - x);
527240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
527340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
527440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Bounce: function(p){
527540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var value;
527640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		for (var a = 0, b = 1; 1; a += b, b /= 2){
527740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (p >= (7 - 4 * a) / 11){
527840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
527940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				break;
528040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
528140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
528240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return value;
528340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
528440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
528540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Elastic: function(p, x){
528640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
528740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
528840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
528940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
529040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
529140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
529240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Fx.Transitions[transition] = new Fx.Transition(function(p){
529340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Math.pow(p, i + 2);
529440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	});
529540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
529640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
529740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
529840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
529940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
530040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
530140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Request
530240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
530340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Powerful all purpose Request Class. Uses XMLHTTPRequest.
530440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
530540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
530640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
530740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Object, Element, Chain, Events, Options, Browser]
530840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
530940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Request
531040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
531140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
531240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
531340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
531440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
531540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
531640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar empty = function(){},
531740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	progressSupport = ('onprogress' in new Browser.Request);
531840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
531940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Request = this.Request = new Class({
532040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
532140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Implements: [Chain, Events, Options],
532240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
532340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	options: {/*
532440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onRequest: function(){},
532540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onLoadstart: function(event, xhr){},
532640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onProgress: function(event, xhr){},
532740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onComplete: function(){},
532840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onCancel: function(){},
532940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onSuccess: function(responseText, responseXML){},
533040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onFailure: function(xhr){},
533140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onException: function(headerName, value){},
533240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		onTimeout: function(){},
533340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		user: '',
533440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		password: '',*/
533540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		url: '',
533640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		data: '',
533740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		headers: {
533840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			'X-Requested-With': 'XMLHttpRequest',
533940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
534040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		},
534140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		async: true,
534240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		format: false,
534340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		method: 'post',
534440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		link: 'ignore',
534540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		isSuccess: null,
534640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		emulation: true,
534740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		urlEncoded: true,
534840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		encoding: 'utf-8',
534940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		evalScripts: false,
535040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		evalResponse: false,
535140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		timeout: 0,
535240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		noCache: false
535340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
535440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
535540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(options){
535640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.xhr = new Browser.Request();
535740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.setOptions(options);
535840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.headers = this.options.headers;
535940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
536040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
536140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	onStateChange: function(){
536240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var xhr = this.xhr;
536340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (xhr.readyState != 4 || !this.running) return;
536440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.running = false;
536540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.status = 0;
536640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Function.attempt(function(){
536740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var status = xhr.status;
536840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.status = (status == 1223) ? 204 : status;
536940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}.bind(this));
537040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.onreadystatechange = empty;
537140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
537240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		clearTimeout(this.timer);
537340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
537440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
537540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.isSuccess.call(this, this.status))
537640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.success(this.response.text, this.response.xml);
537740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else
537840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.failure();
537940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
538040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
538140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	isSuccess: function(){
538240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var status = this.status;
538340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (status >= 200 && status < 300);
538440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
538540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
538640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	isRunning: function(){
538740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return !!this.running;
538840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
538940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
539040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	processScripts: function(text){
539140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
539240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return text.stripScripts(this.options.evalScripts);
539340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
539440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
539540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	success: function(text, xml){
539640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.onSuccess(this.processScripts(text), xml);
539740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
539840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
539940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	onSuccess: function(){
540040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
540140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
540240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
540340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	failure: function(){
540440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.onFailure();
540540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
540640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
540740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	onFailure: function(){
540840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('complete').fireEvent('failure', this.xhr);
540940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
541040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
541140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	loadstart: function(event){
541240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('loadstart', [event, this.xhr]);
541340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
541440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
541540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	progress: function(event){
541640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('progress', [event, this.xhr]);
541740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
541840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
541940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	timeout: function(){
542040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('timeout', this.xhr);
542140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
542240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
542340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	setHeader: function(name, value){
542440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.headers[name] = value;
542540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
542640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
542740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
542840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	getHeader: function(name){
542940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return Function.attempt(function(){
543040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return this.xhr.getResponseHeader(name);
543140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}.bind(this));
543240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
543340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
543440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	check: function(){
543540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.running) return true;
543640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (this.options.link){
543740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'cancel': this.cancel(); return true;
543840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
543940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
544040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return false;
544140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
544240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
544340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	send: function(options){
544440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.check(options)) return this;
544540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
544640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
544740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.running = true;
544840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
544940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var type = typeOf(options);
545040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (type == 'string' || type == 'element') options = {data: options};
545140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
545240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var old = this.options;
545340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		options = Object.append({data: old.data, url: old.url, method: old.method}, options);
545440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var data = options.data, url = String(options.url), method = options.method.toLowerCase();
545540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
545640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		switch (typeOf(data)){
545740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'element': data = document.id(data).toQueryString(); break;
545840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			case 'object': case 'hash': data = Object.toQueryString(data);
545940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
546040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
546140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.format){
546240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var format = 'format=' + this.options.format;
546340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			data = (data) ? format + '&' + data : format;
546440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
546540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
546640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.emulation && !['get', 'post'].contains(method)){
546740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var _method = '_method=' + method;
546840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			data = (data) ? _method + '&' + data : _method;
546940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			method = 'post';
547040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
547140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
547240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.urlEncoded && ['post', 'put'].contains(method)){
547340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
547440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
547540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
547640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
547740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!url) url = document.location.pathname;
547840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
547940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var trimPosition = url.lastIndexOf('/');
548040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
548140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
548240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.noCache)
548340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			url += (url.indexOf('?') > -1 ? '&' : '?') + String.uniqueID();
548440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
548540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (data && (method == 'get' || method == 'delete')){
548640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			url += (url.indexOf('?') > -1 ? '&' : '?') + data;
548740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			data = null;
548840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
548940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
549040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var xhr = this.xhr;
549140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (progressSupport){
549240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			xhr.onloadstart = this.loadstart.bind(this);
549340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			xhr.onprogress = this.progress.bind(this);
549440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
549540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
549640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
549740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
549840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
549940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.onreadystatechange = this.onStateChange.bind(this);
550040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
550140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Object.each(this.headers, function(value, key){
550240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			try {
550340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				xhr.setRequestHeader(key, value);
550440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			} catch (e){
550540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				this.fireEvent('exception', [key, value]);
550640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			}
550740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}, this);
550840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
550940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('request');
551040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.send(data);
551140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.options.async) this.onStateChange();
551240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
551340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
551440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
551540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
551640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	cancel: function(){
551740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!this.running) return this;
551840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.running = false;
551940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var xhr = this.xhr;
552040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.abort();
552140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		clearTimeout(this.timer);
552240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		xhr.onreadystatechange = empty;
552340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
552440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.xhr = new Browser.Request();
552540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.fireEvent('cancel');
552640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
552740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
552840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
552940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
553040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
553140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar methods = {};
553240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
553340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	methods[method] = function(data){
553440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var object = {
553540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			method: method
553640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		};
553740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (data != null) object.data = data;
553840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this.send(object);
553940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	};
554040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
554140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
554240f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikRequest.implement(methods);
554340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
554440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.send = {
554540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
554640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(options){
554740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var send = this.get('send').cancel();
554840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		send.setOptions(options);
554940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
555040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
555140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
555240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
555340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var send = this.retrieve('send');
555440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!send){
555540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			send = new Request({
555640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
555740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
555840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.store('send', send);
555940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
556040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return send;
556140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
556240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
556340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
556440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
556540f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
556640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
556740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	send: function(url){
556840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var sender = this.get('send');
556940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		sender.send({data: this, url: url || sender.options.url});
557040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
557140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
557240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
557340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
557440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
557540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
557640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
557740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
557840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
557940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
558040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
558140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Request.HTML
558240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
558340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Extends the basic Request Class with additional methods for interacting with HTML responses.
558440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
558540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
558640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
558740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Element, Request]
558840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
558940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Request.HTML
559040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
559140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
559240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
559340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
559440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikRequest.HTML = new Class({
559540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
559640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: Request,
559740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
559840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	options: {
559940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		update: false,
560040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		append: false,
560140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		evalScripts: true,
560240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		filter: false,
560340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		headers: {
560440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			Accept: 'text/html, application/xml, text/xml, */*'
560540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
560640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
560740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
560840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	success: function(text){
560940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var options = this.options, response = this.response;
561040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
561140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		response.html = text.stripScripts(function(script){
561240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			response.javascript = script;
561340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
561440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
561540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
561640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (match) response.html = match[1];
561740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var temp = new Element('div').set('html', response.html);
561840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
561940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		response.tree = temp.childNodes;
562040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		response.elements = temp.getElements(options.filter || '*');
562140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
562240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (options.filter) response.tree = response.elements;
562340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (options.update){
562440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var update = document.id(options.update).empty();
562540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (options.filter) update.adopt(response.elements);
562640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else update.set('html', response.html);
562740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} else if (options.append){
562840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var append = document.id(options.append);
562940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			if (options.filter) response.elements.reverse().inject(append);
563040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			else append.adopt(temp.getChildren());
563140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
563240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (options.evalScripts) Browser.exec(response.javascript);
563340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
563440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.onSuccess(response.tree, response.elements, response.html, response.javascript);
563540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
563640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
563740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
563840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
563940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Properties.load = {
564040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
564140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	set: function(options){
564240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var load = this.get('load').cancel();
564340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		load.setOptions(options);
564440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
564540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
564640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
564740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	get: function(){
564840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var load = this.retrieve('load');
564940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!load){
565040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});
565140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.store('load', load);
565240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
565340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return load;
565440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
565540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
565640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
565740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
565840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.implement({
565940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
566040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	load: function(){
566140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));
566240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
566340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
566440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
566540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
566640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
566740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
566840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
566940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
567040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
567140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: JSON
567240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
567340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: JSON encoder and decoder.
567440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
567540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
567640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
567740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikSeeAlso: <http://www.json.org/>
567840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
567940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Array, String, Number, Function]
568040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
568140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: JSON
568240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
568340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
568440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
568540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
568640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (typeof JSON == 'undefined') this.JSON = {};
568740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
568840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
568940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
569040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(){
569140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
569240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
569340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
569440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar escape = function(chr){
569540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
569640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
569740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
569840f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikJSON.validate = function(string){
569940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
570040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
570140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik					replace(/(?:^|:|,)(?:\s*\[)+/g, '');
570240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
570340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (/^[\],:{}\s]*$/).test(string);
570440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
570540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
570640f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikJSON.encode = JSON.stringify ? function(obj){
570740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return JSON.stringify(obj);
570840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik} : function(obj){
570940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (obj && obj.toJSON) obj = obj.toJSON();
571040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
571140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	switch (typeOf(obj)){
571240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'string':
571340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
571440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'array':
571540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return '[' + obj.map(JSON.encode).clean() + ']';
571640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'object': case 'hash':
571740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var string = [];
571840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			Object.each(obj, function(value, key){
571940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				var json = JSON.encode(value);
572040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik				if (json) string.push(JSON.encode(key) + ':' + json);
572140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			});
572240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return '{' + string + '}';
572340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'number': case 'boolean': return '' + obj;
572440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		case 'null': return 'null';
572540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
572640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
572740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return null;
572840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
572940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
573040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikJSON.secure = true;
573140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
573240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
573340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikJSON.decode = function(string, secure){
573440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!string || typeOf(string) != 'string') return null;
573540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
573640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (secure == null) secure = JSON.secure;
573740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (secure){
573840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (JSON.parse) return JSON.parse(string);
573940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');
574040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
574140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
574240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return eval('(' + string + ')');
574340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
574440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
574540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();
574640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
574740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
574840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
574940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
575040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
575140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Request.JSON
575240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
575340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Extends the basic Request Class with additional methods for sending and receiving JSON data.
575440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
575540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
575640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
575740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Request, JSON]
575840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
575940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Request.JSON
576040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
576140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
576240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
576340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
576440f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikRequest.JSON = new Class({
576540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
576640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Extends: Request,
576740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
576840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	options: {
576940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		/*onError: function(text, error){},*/
577040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		secure: true
577140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
577240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
577340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(options){
577440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.parent(options);
577540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		Object.append(this.headers, {
577640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			'Accept': 'application/json',
577740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			'X-Request': 'JSON'
577840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		});
577940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
578040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
578140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	success: function(text){
578240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var json;
578340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		try {
578440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			json = this.response.json = JSON.decode(text, this.options.secure);
578540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		} catch (error){
578640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			this.fireEvent('error', [text, error]);
578740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			return;
578840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
578940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (json == null) this.onFailure();
579040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		else this.onSuccess(json, text);
579140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
579240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
579340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
579440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
579540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
579640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
579740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
579840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
579940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: Cookie
580040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
580140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Class for creating, reading, and deleting browser Cookies.
580240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
580340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
580440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
580540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikcredits:
580640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik  - Based on the functions by Peter-Paul Koch (http://quirksmode.org).
580740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
580840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Options, Browser]
580940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
581040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: Cookie
581140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
581240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
581340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
581440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
581540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar Cookie = new Class({
581640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
581740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Implements: Options,
581840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
581940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	options: {
582040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		path: '/',
582140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		domain: false,
582240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		duration: false,
582340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		secure: false,
582440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		document: document,
582540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		encode: true
582640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
582740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
582840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	initialize: function(key, options){
582940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.key = key;
583040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.setOptions(options);
583140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
583240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
583340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	write: function(value){
583440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.encode) value = encodeURIComponent(value);
583540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.domain) value += '; domain=' + this.options.domain;
583640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.path) value += '; path=' + this.options.path;
583740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.duration){
583840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			var date = new Date();
583940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
584040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			value += '; expires=' + date.toGMTString();
584140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
584240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this.options.secure) value += '; secure';
584340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		this.options.document.cookie = this.key + '=' + value;
584440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
584540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
584640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
584740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	read: function(){
584840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
584940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return (value) ? decodeURIComponent(value[1]) : null;
585040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
585140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
585240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	dispose: function(){
585340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');
585440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return this;
585540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
585640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
585740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
585840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
585940f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikCookie.write = function(key, value, options){
586040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return new Cookie(key, options).write(value);
586140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
586240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
586340f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikCookie.read = function(key){
586440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return new Cookie(key).read();
586540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
586640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
586740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikCookie.dispose = function(key, options){
586840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return new Cookie(key, options).dispose();
586940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
587040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
587140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
587240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*
587340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik---
587440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
587540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikname: DOMReady
587640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
587740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdescription: Contains the custom event domready.
587840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
587940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craiklicense: MIT-style license.
588040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
588140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikrequires: [Browser, Element, Element.Event]
588240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
588340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikprovides: [DOMReady, DomReady]
588440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
588540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik...
588640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik*/
588740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
588840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function(window, document){
588940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
589040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar ready,
589140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	loaded,
589240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	checks = [],
589340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	shouldPoll,
589440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	timer,
589540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	testElement = document.createElement('div');
589640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
589740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar domready = function(){
589840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clearTimeout(timer);
589940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (ready) return;
590040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	Browser.loaded = ready = true;
590140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);
590240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
590340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	document.fireEvent('domready');
590440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	window.fireEvent('domready');
590540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
590640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
590740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar check = function(){
590840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	for (var i = checks.length; i--;) if (checks[i]()){
590940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		domready();
591040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
591140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
591240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return false;
591340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
591440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
591540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar poll = function(){
591640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	clearTimeout(timer);
591740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	if (!check()) timer = setTimeout(poll, 10);
591840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
591940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
592040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikdocument.addListener('DOMContentLoaded', domready);
592140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
592240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*<ltIE8>*/
592340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
592440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// testElement.doScroll() throws when the DOM is not ready, only in the top window
592540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikvar doScrollWorks = function(){
592640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	try {
592740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		testElement.doScroll();
592840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
592940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	} catch (e){}
593040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return false;
593140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
593240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// If doScroll works already, it can't be used to determine domready
593340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik//   e.g. in an iframe
593440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (testElement.doScroll && !doScrollWorks()){
593540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	checks.push(doScrollWorks);
593640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	shouldPoll = true;
593740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik}
593840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/*</ltIE8>*/
593940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
594040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (document.readyState) checks.push(function(){
594140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	var state = document.readyState;
594240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	return (state == 'loaded' || state == 'complete');
594340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
594440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
594540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif ('onreadystatechange' in document) document.addListener('readystatechange', check);
594640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikelse shouldPoll = true;
594740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
594840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikif (shouldPoll) poll();
594940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
595040f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Events.domready = {
595140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	onAdd: function(fn){
595240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (ready) fn.call(this);
595340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
595440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
595540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
595640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// Make sure that domready fires before load
595740f8da8088c9cd699f672242d0cdc3d677353bf8Chris CraikElement.Events.load = {
595840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	base: 'load',
595940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	onAdd: function(fn){
596040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (loaded && this == window) fn.call(this);
596140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	},
596240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	condition: function(){
596340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		if (this == window){
596440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			domready();
596540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik			delete Element.Events.load;
596640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		}
596740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik		return true;
596840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	}
596940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik};
597040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
597140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik// This is based on the custom load event
597240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craikwindow.addEvent('load', function(){
597340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik	loaded = true;
597440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik});
597540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
597640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})(window, document);
597740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik
5978