PageSourceSearch

https://kappalab.com/rw_common/themes/iphone/js/mootools.v1.11.js?rwcache=726139661

js kappalab.com collected 2026-10-07 13:43:08 UTC 53,103 bytes, 2,105 lines download raw bytes

1//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
2
3var MooTools = {
4	version: '1.11'
5};
6
7function $defined(obj){
8	return (obj != undefined);
9};
10
11function $type(obj){
12	if (!$defined(obj)) return false;
13	if (obj.htmlElement) return 'element';
14	var type = typeof obj;
15	if (type == 'object' && obj.nodeName){
16		switch(obj.nodeType){
17			case 1: return 'element';
18			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
19		}
20	}
21	if (type == 'object' || type == 'function'){
22		switch(obj.constructor){
23			case Array: return 'array';
24			case RegExp: return 'regexp';
25			case Class: return 'class';
26		}
27		if (typeof obj.length == 'number'){
28			if (obj.item) return 'collection';
29			if (obj.callee) return 'arguments';
30		}
31	}
32	return type;
33};
34
35function $merge(){
36	var mix = {};
37	for (var i = 0; i < arguments.length; i++){
38		for (var property in arguments[i]){
39			var ap = arguments[i][property];
40			var mp = mix[property];
41			if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap);
42			else mix[property] = ap;
43		}
44	}
45	return mix;
46};
47
48var $extend = function(){
49	var args = arguments;
50	if (!args[1]) args = [this, args[0]];
51	for (var property in args[1]) args[0][property] = args[1][property];
52	return args[0];
53};
54
55var $native = function(){
56	for (var i = 0, l = arguments.length; i < l; i++){
57		arguments[i].extend = function(props){
58			for (var prop in props){
59				if (!this.prototype[prop]) this.prototype[prop] = props[prop];
60				if (!this[prop]) this[prop] = $native.generic(prop);
61			}
62		};
63	}
64};
65
66$native.generic = function(prop){
67	return function(bind){
68		return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1));
69	};
70};
71
72$native(Function, Array, String, Number);
73
74function $chk(obj){
75	return !!(obj || obj === 0);
76};
77
78function $pick(obj, picked){
79	return $defined(obj) ? obj : picked;
80};
81
82function $random(min, max){
83	return Math.floor(Math.random() * (max - min + 1) + min);
84};
85
86function $time(){
87	return new Date().getTime();
88};
89
90function $clear(timer){
91	clearTimeout(timer);
92	clearInterval(timer);
93	return null;
94};
95
96var Abstract = function(obj){
97	obj = obj || {};
98	obj.extend = $extend;
99	return obj;
100};
101
102var Window = new Abstract(window);
103var Document = new Abstract(document);
104document.head = document.getElementsByTagName('head')[0];
105
106window.xpath = !!(document.evaluate);
107if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
108else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true;
109else if (document.getBoxObjectFor != null) window.gecko = true;
110
111window.khtml = window.webkit;
112
113Object.extend = $extend;
114
115if (typeof HTMLElement == 'undefined'){
116	var HTMLElement = function(){};
117	if (window.webkit) document.createElement("iframe");
118	HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {};
119}
120HTMLElement.prototype.htmlElement = function(){};
121
122if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){};
123
124var Class = function(properties){
125	var klass = function(){
126		return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
127	};
128	$extend(klass, this);
129	klass.prototype = properties;
130	klass.constructor = Class;
131	return klass;
132};
133
134Class.empty = function(){};
135
136Class.prototype = {
137
138	extend: function(properties){
139		var proto = new this(null);
140		for (var property in properties){
141			var pp = proto[property];
142			proto[property] = Class.Merge(pp, properties[property]);
143		}
144		return new Class(proto);
145	},
146
147	implement: function(){
148		for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
149	}
150
151};
152
153Class.Merge = function(previous, current){
154	if (previous && previous != current){
155		var type = $type(current);
156		if (type != $type(previous)) return current;
157		switch(type){
158			case 'function':
159				var merged = function(){
160					this.parent = arguments.callee.parent;
161					return current.apply(this, arguments);
162				};
163				merged.parent = previous;
164				return merged;
165			case 'object': return $merge(previous, current);
166		}
167	}
168	return current;
169};
170
171var Chain = new Class({
172
173	chain: function(fn){
174		this.chains = this.chains || [];
175		this.chains.push(fn);
176		return this;
177	},
178
179	callChain: function(){
180		if (this.chains && this.chains.length) this.chains.shift().delay(10, this);
181	},
182
183	clearChain: function(){
184		this.chains = [];
185	}
186
187});
188
189var Events = new Class({
190
191	addEvent: function(type, fn){
192		if (fn != Class.empty){
193			this.$events = this.$events || {};
194			this.$events[type] = this.$events[type] || [];
195			this.$events[type].include(fn);
196		}
197		return this;
198	},
199
200	fireEvent: function(type, args, delay){
201		if (this.$events && this.$events[type]){
202			this.$events[type].each(function(fn){
203				fn.create({'bind': this, 'delay': delay, 'arguments': args})();
204			}, this);
205		}
206		return this;
207	},
208
209	removeEvent: function(type, fn){
210		if (this.$events && this.$events[type]) this.$events[type].remove(fn);
211		return this;
212	}
213
214});
215
216var Options = new Class({
217
218	setOptions: function(){
219		this.options = $merge.apply(null, [this.options].extend(arguments));
220		if (this.addEvent){
221			for (var option in this.options){
222				if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]);
223			}
224		}
225		return this;
226	}
227
228});
229
230Array.extend({
231
232	forEach: function(fn, bind){
233		for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this);
234	},
235
236	filter: function(fn, bind){
237		var results = [];
238		for (var i = 0, j = this.length; i < j; i++){
239			if (fn.call(bind, this[i], i, this)) results.push(this[i]);
240		}
241		return results;
242	},
243
244	map: function(fn, bind){
245		var results = [];
246		for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this);
247		return results;
248	},
249
250	every: function(fn, bind){
251		for (var i = 0, j = this.length; i < j; i++){
252			if (!fn.call(bind, this[i], i, this)) return false;
253		}
254		return true;
255	},
256
257	some: function(fn, bind){
258		for (var i = 0, j = this.length; i < j; i++){
259			if (fn.call(bind, this[i], i, this)) return true;
260		}
261		return false;
262	},
263
264	indexOf: function(item, from){
265		var len = this.length;
266		for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
267			if (this[i] === item) return i;
268		}
269		return -1;
270	},
271
272	copy: function(start, length){
273		start = start || 0;
274		if (start < 0) start = this.length + start;
275		length = length || (this.length - start);
276		var newArray = [];
277		for (var i = 0; i < length; i++) newArray[i] = this[start++];
278		return newArray;
279	},
280
281	remove: function(item){
282		var i = 0;
283		var len = this.length;
284		while (i < len){
285			if (this[i] === item){
286				this.splice(i, 1);
287				len--;
288			} else {
289				i++;
290			}
291		}
292		return this;
293	},
294
295	contains: function(item, from){
296		return this.indexOf(item, from) != -1;
297	},
298
299	associate: function(keys){
300		var obj = {}, length = Math.min(this.length, keys.length);
301		for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
302		return obj;
303	},
304
305	extend: function(array){
306		for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
307		return this;
308	},
309
310	merge: function(array){
311		for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
312		return this;
313	},
314
315	include: function(item){
316		if (!this.contains(item)) this.push(item);
317		return this;
318	},
319
320	getRandom: function(){
321		return this[$random(0, this.length - 1)] || null;
322	},
323
324	getLast: function(){
325		return this[this.length - 1] || null;
326	}
327
328});
329
330Array.prototype.each = Array.prototype.forEach;
331Array.each = Array.forEach;
332
333function $A(array){
334	return Array.copy(array);
335};
336
337function $each(iterable, fn, bind){
338	if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){
339		Array.forEach(iterable, fn, bind);
340	} else {
341		 for (var name in iterable) fn.call(bind || iterable, iterable[name], name);
342	}
343};
344
345Array.prototype.test = Array.prototype.contains;
346
347String.extend({
348
349	test: function(regex, params){
350		return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this);
351	},
352
353	toInt: function(){
354		return parseInt(this, 10);
355	},
356
357	toFloat: function(){
358		return parseFloat(this);
359	},
360
361	camelCase: function(){
362		return this.replace(/-\D/g, function(match){
363			return match.charAt(1).toUpperCase();
364		});
365	},
366
367	hyphenate: function(){
368		return this.replace(/\w[A-Z]/g, function(match){
369			return (match.charAt(0) + '-' + match.charAt(1).toLowerCase());
370		});
371	},
372
373	capitalize: function(){
374		return this.replace(/\b[a-z]/g, function(match){
375			return match.toUpperCase();
376		});
377	},
378
379	trim: function(){
380		return this.replace(/^\s+|\s+$/g, '');
381	},
382
383	clean: function(){
384		return this.replace(/\s{2,}/g, ' ').trim();
385	},
386
387	rgbToHex: function(array){
388		var rgb = this.match(/\d{1,3}/g);
389		return (rgb) ? rgb.rgbToHex(array) : false;
390	},
391
392	hexToRgb: function(array){
393		var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
394		return (hex) ? hex.slice(1).hexToRgb(array) : false;
395	},
396
397	contains: function(string, s){
398		return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
399	},
400
401	escapeRegExp: function(){
402		return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
403	}
404
405});
406
407Array.extend({
408
409	rgbToHex: function(array){
410		if (this.length < 3) return false;
411		if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
412		var hex = [];
413		for (var i = 0; i < 3; i++){
414			var bit = (this[i] - 0).toString(16);
415			hex.push((bit.length == 1) ? '0' + bit : bit);
416		}
417		return array ? hex : '#' + hex.join('');
418	},
419
420	hexToRgb: function(array){
421		if (this.length != 3) return false;
422		var rgb = [];
423		for (var i = 0; i < 3; i++){
424			rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16));
425		}
426		return array ? rgb : 'rgb(' + rgb.join(',') + ')';
427	}
428
429});
430
431Function.extend({
432
433	create: function(options){
434		var fn = this;
435		options = $merge({
436			'bind': fn,
437			'event': false,
438			'arguments': null,
439			'delay': false,
440			'periodical': false,
441			'attempt': false
442		}, options);
443		if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments];
444		return function(event){
445			var args;
446			if (options.event){
447				event = event || window.event;
448				args = [(options.event === true) ? event : new options.event(event)];
449				if (options.arguments) args.extend(options.arguments);
450			}
451			else args = options.arguments || arguments;
452			var returns = function(){
453				return fn.apply($pick(options.bind, fn), args);
454			};
455			if (options.delay) return setTimeout(returns, options.delay);
456			if (options.periodical) return setInterval(returns, options.periodical);
457			if (options.attempt) try {return returns();} catch(err){return false;};
458			return returns();
459		};
460	},
461
462	pass: function(args, bind){
463		return this.create({'arguments': args, 'bind': bind});
464	},
465
466	attempt: function(args, bind){
467		return this.create({'arguments': args, 'bind': bind, 'attempt': true})();
468	},
469
470	bind: function(bind, args){
471		return this.create({'bind': bind, 'arguments': args});
472	},
473
474	bindAsEventListener: function(bind, args){
475		return this.create({'bind': bind, 'event': true, 'arguments': args});
476	},
477
478	delay: function(delay, bind, args){
479		return this.create({'delay': delay, 'bind': bind, 'arguments': args})();
480	},
481
482	periodical: function(interval, bind, args){
483		return this.create({'periodical': interval, 'bind': bind, 'arguments': args})();
484	}
485
486});
487
488Number.extend({
489
490	toInt: function(){
491		return parseInt(this);
492	},
493
494	toFloat: function(){
495		return parseFloat(this);
496	},
497
498	limit: function(min, max){
499		return Math.min(max, Math.max(min, this));
500	},
501
502	round: function(precision){
503		precision = Math.pow(10, precision || 0);
504		return Math.round(this * precision) / precision;
505	},
506
507	times: function(fn){
508		for (var i = 0; i < this; i++) fn(i);
509	}
510
511});
512
513var Element = new Class({
514
515	initialize: function(el, props){
516		if ($type(el) == 'string'){
517			if (window.ie && props && (props.name || props.type)){
518				var name = (props.name) ? ' name="' + props.name + '"' : '';
519				var type = (props.type) ? ' type="' + props.type + '"' : '';
520				delete props.name;
521				delete props.type;
522				el = '<' + el + name + type + '>';
523			}
524			el = document.createElement(el);
525		}
526		el = $(el);
527		return (!props || !el) ? el : el.set(props);
528	}
529
530});
531
532var Elements = new Class({
533
534	initialize: function(elements){
535		return (elements) ? $extend(elements, this) : this;
536	}
537
538});
539
540Elements.extend = function(props){
541	for (var prop in props){
542		this.prototype[prop] = props[prop];
543		this[prop] = $native.generic(prop);
544	}
545};
546
547function $(el){
548	if (!el) return null;
549	if (el.htmlElement) return Garbage.collect(el);
550	if ([window, document].contains(el)) return el;
551	var type = $type(el);
552	if (type == 'string'){
553		el = document.getElementById(el);
554		type = (el) ? 'element' : false;
555	}
556	if (type != 'element') return null;
557	if (el.htmlElement) return Garbage.collect(el);
558	if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el;
559	$extend(el, Element.prototype);
560	el.htmlElement = function(){};
561	return Garbage.collect(el);
562};
563
564document.getElementsBySelector = document.getElementsByTagName;
565
566function $$(){
567	var elements = [];
568	for (var i = 0, j = arguments.length; i < j; i++){
569		var selector = arguments[i];
570		switch($type(selector)){
571			case 'element': elements.push(selector);
572			case 'boolean': break;
573			case false: break;
574			case 'string': selector = document.getElementsBySelector(selector, true);
575			default: elements.extend(selector);
576		}
577	}
578	return $$.unique(elements);
579};
580
581$$.unique = function(array){
582	var elements = [];
583	for (var i = 0, l = array.length; i < l; i++){
584		if (array[i].$included) continue;
585		var element = $(array[i]);
586		if (element && !element.$included){
587			element.$included = true;
588			elements.push(element);
589		}
590	}
591	for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null;
592	return new Elements(elements);
593};
594
595Elements.Multi = function(property){
596	return function(){
597		var args = arguments;
598		var items = [];
599		var elements = true;
600		for (var i = 0, j = this.length, returns; i < j; i++){
601			returns = this[i][property].apply(this[i], args);
602			if ($type(returns) != 'element') elements = false;
603			items.push(returns);
604		};
605		return (elements) ? $$.unique(items) : items;
606	};
607};
608
609Element.extend = function(properties){
610	for (var property in properties){
611		HTMLElement.prototype[property] = properties[property];
612		Element.prototype[property] = properties[property];
613		Element[property] = $native.generic(property);
614		var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property;
615		Elements.prototype[elementsProperty] = Elements.Multi(property);
616	}
617};
618
619Element.extend({
620
621	set: function(props){
622		for (var prop in props){
623			var val = props[prop];
624			switch(prop){
625				case 'styles': this.setStyles(val); break;
626				case 'events': if (this.addEvents) this.addEvents(val); break;
627				case 'properties': this.setProperties(val); break;
628				default: this.setProperty(prop, val);
629			}
630		}
631		return this;
632	},
633
634	inject: function(el, where){
635		el = $(el);
636		switch(where){
637			case 'before': el.parentNode.insertBefore(this, el); break;
638			case 'after':
639				var next = el.getNext();
640				if (!next) el.parentNode.appendChild(this);
641				else el.parentNode.insertBefore(this, next);
642				break;
643			case 'top':
644				var first = el.firstChild;
645				if (first){
646					el.insertBefore(this, first);
647					break;
648				}
649			default: el.appendChild(this);
650		}
651		return this;
652	},
653
654	injectBefore: function(el){
655		return this.inject(el, 'before');
656	},
657
658	injectAfter: function(el){
659		return this.inject(el, 'after');
660	},
661
662	injectInside: function(el){
663		return this.inject(el, 'bottom');
664	},
665
666	injectTop: function(el){
667		return this.inject(el, 'top');
668	},
669
670	adopt: function(){
671		var elements = [];
672		$each(arguments, function(argument){
673			elements = elements.concat(argument);
674		});
675		$$(elements).inject(this);
676		return this;
677	},
678
679	remove: function(){
680		return this.parentNode.removeChild(this);
681	},
682
683	clone: function(contents){
684		var el = $(this.cloneNode(contents !== false));
685		if (!el.$events) return el;
686		el.$events = {};
687		for (var type in this.$events) el.$events[type] = {
688			'keys': $A(this.$events[type].keys),
689			'values': $A(this.$events[type].values)
690		};
691		return el.removeEvents();
692	},
693
694	replaceWith: function(el){
695		el = $(el);
696		this.parentNode.replaceChild(el, this);
697		return el;
698	},
699
700	appendText: function(text){
701		this.appendChild(document.createTextNode(text));
702		return this;
703	},
704
705	hasClass: function(className){
706		return this.className.contains(className, ' ');
707	},
708
709	addClass: function(className){
710		if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
711		return this;
712	},
713
714	removeClass: function(className){
715		this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean();
716		return this;
717	},
718
719	toggleClass: function(className){
720		return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
721	},
722
723	setStyle: function(property, value){
724		switch(property){
725			case 'opacity': return this.setOpacity(parseFloat(value));
726			case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat';
727		}
728		property = property.camelCase();
729		switch($type(value)){
730			case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break;
731			case 'array': value = 'rgb(' + value.join(',') + ')';
732		}
733		this.style[property] = value;
734		return this;
735	},
736
737	setStyles: function(source){
738		switch($type(source)){
739			case 'object': Element.setMany(this, 'setStyle', source); break;
740			case 'string': this.style.cssText = source;
741		}
742		return this;
743	},
744
745	setOpacity: function(opacity){
746		if (opacity == 0){
747			if (this.style.visibility != "hidden") this.style.visibility = "hidden";
748		} else {
749			if (this.style.visibility != "visible") this.style.visibility = "visible";
750		}
751		if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
752		if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")";
753		this.style.opacity = this.$tmp.opacity = opacity;
754		return this;
755	},
756
757	getStyle: function(property){
758		property = property.camelCase();
759		var result = this.style[property];
760		if (!$chk(result)){
761			if (property == 'opacity') return this.$tmp.opacity;
762			result = [];
763			for (var style in Element.Styles){
764				if (property == style){
765					Element.Styles[style].each(function(s){
766						var style = this.getStyle(s);
767						result.push(parseInt(style) ? style : '0px');
768					}, this);
769					if (property == 'border'){
770						var every = result.every(function(bit){
771							return (bit == result[0]);
772						});
773						return (every) ? result[0] : false;
774					}
775					return result.join(' ');
776				}
777			}
778			if (property.contains('border')){
779				if (Element.Styles.border.contains(property)){
780					return ['Width', 'Style', 'Color'].map(function(p){
781						return this.getStyle(property + p);
782					}, this).join(' ');
783				} else if (Element.borderShort.contains(property)){
784					return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){
785						return this.getStyle('border' + p + property.replace('border', ''));
786					}, this).join(' ');
787				}
788			}
789			if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate());
790			else if (this.currentStyle) result = this.currentStyle[property];
791		}
792		if (window.ie) result = Element.fixStyle(property, result, this);
793		if (result && property.test(/color/i) && result.contains('rgb')){
794			return result.split('rgb').splice(1,4).map(function(color){
795				return color.rgbToHex();
796			}).join(' ');
797		}
798		return result;
799	},
800
801	getStyles: function(){
802		return Element.getMany(this, 'getStyle', arguments);
803	},
804
805	walk: function(brother, start){
806		brother += 'Sibling';
807		var el = (start) ? this[start] : this[brother];
808		while (el && $type(el) != 'element') el = el[brother];
809		return $(el);
810	},
811
812	getPrevious: function(){
813		return this.walk('previous');
814	},
815
816	getNext: function(){
817		return this.walk('next');
818	},
819
820	getFirst: function(){
821		return this.walk('next', 'firstChild');
822	},
823
824	getLast: function(){
825		return this.walk('previous', 'lastChild');
826	},
827
828	getParent: function(){
829		return $(this.parentNode);
830	},
831
832	getChildren: function(){
833		return $$(this.childNodes);
834	},
835
836	hasChild: function(el){
837		return !!$A(this.getElementsByTagName('*')).contains(el);
838	},
839
840	getProperty: function(property){
841		var index = Element.Properties[property];
842		if (index) return this[index];
843		var flag = Element.PropertiesIFlag[property] || 0;
844		if (!window.ie || flag) return this.getAttribute(property, flag);
845		var node = this.attributes[property];
846		return (node) ? node.nodeValue : null;
847	},
848
849	removeProperty: function(property){
850		var index = Element.Properties[property];
851		if (index) this[index] = '';
852		else this.removeAttribute(property);
853		return this;
854	},
855
856	getProperties: function(){
857		return Element.getMany(this, 'getProperty', arguments);
858	},
859
860	setProperty: function(property, value){
861		var index = Element.Properties[property];
862		if (index) this[index] = value;
863		else this.setAttribute(property, value);
864		return this;
865	},
866
867	setProperties: function(source){
868		return Element.setMany(this, 'setProperty', source);
869	},
870
871	setHTML: function(){
872		this.innerHTML = $A(arguments).join('');
873		return this;
874	},
875
876	setText: function(text){
877		var tag = this.getTag();
878		if (['style', 'script'].contains(tag)){
879			if (window.ie){
880				if (tag == 'style') this.styleSheet.cssText = text;
881				else if (tag ==  'script') this.setProperty('text', text);
882				return this;
883			} else {
884				this.removeChild(this.firstChild);
885				return this.appendText(text);
886			}
887		}
888		this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text;
889		return this;
890	},
891
892	getText: function(){
893		var tag = this.getTag();
894		if (['style', 'script'].contains(tag)){
895			if (window.ie){
896				if (tag == 'style') return this.styleSheet.cssText;
897				else if (tag ==  'script') return this.getProperty('text');
898			} else {
899				return this.innerHTML;
900			}
901		}
902		return ($pick(this.innerText, this.textContent));
903	},
904
905	getTag: function(){
906		return this.tagName.toLowerCase();
907	},
908
909	empty: function(){
910		Garbage.trash(this.getElementsByTagName('*'));
911		return this.setHTML('');
912	}
913
914});
915
916Element.fixStyle = function(property, result, element){
917	if ($chk(parseInt(result))) return result;
918	if (['height', 'width'].contains(property)){
919		var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'];
920		var size = 0;
921		values.each(function(value){
922			size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt();
923		});
924		return element['offset' + property.capitalize()] - size + 'px';
925	} else if (property.test(/border(.+)Width|margin|padding/)){
926		return '0px';
927	}
928	return result;
929};
930
931Element.Styles = {'border': [], 'padding': [], 'margin': []};
932['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
933	for (var style in Element.Styles) Element.Styles[style].push(style + direction);
934});
935
936Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor'];
937
938Element.getMany = function(el, method, keys){
939	var result = {};
940	$each(keys, function(key){
941		result[key] = el[method](key);
942	});
943	return result;
944};
945
946Element.setMany = function(el, method, pairs){
947	for (var key in pairs) el[method](key, pairs[key]);
948	return el;
949};
950
951Element.Properties = new Abstract({
952	'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan',
953	'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength',
954	'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value',
955	'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected'
956});
957Element.PropertiesIFlag = {
958	'href': 2, 'src': 2
959};
960
961Element.Methods = {
962	Listeners: {
963		addListener: function(type, fn){
964			if (this.addEventListener) this.addEventListener(type, fn, false);
965			else this.attachEvent('on' + type, fn);
966			return this;
967		},
968
969		removeListener: function(type, fn){
970			if (this.removeEventListener) this.removeEventListener(type, fn, false);
971			else this.detachEvent('on' + type, fn);
972			return this;
973		}
974	}
975};
976
977window.extend(Element.Methods.Listeners);
978document.extend(Element.Methods.Listeners);
979Element.extend(Element.Methods.Listeners);
980
981var Garbage = {
982
983	elements: [],
984
985	collect: function(el){
986		if (!el.$tmp){
987			Garbage.elements.push(el);
988			el.$tmp = {'opacity': 1};
989		}
990		return el;
991	},
992
993	trash: function(elements){
994		for (var i = 0, j = elements.length, el; i < j; i++){
995			if (!(el = elements[i]) || !el.$tmp) continue;
996			if (el.$events) el.fireEvent('trash').removeEvents();
997			for (var p in el.$tmp) el.$tmp[p] = null;
998			for (var d in Element.prototype) el[d] = null;
999			Garbage.elements[Garbage.elements.indexOf(el)] = null;
1000			el.htmlElement = el.$tmp = el = null;
1001		}
1002		Garbage.elements.remove(null);
1003	},
1004
1005	empty: function(){
1006		Garbage.collect(window);
1007		Garbage.collect(document);
1008		Garbage.trash(Garbage.elements);
1009	}
1010
1011};
1012
1013window.addListener('beforeunload', function(){
1014	window.addListener('unload', Garbage.empty);
1015	if (window.ie) window.addListener('unload', CollectGarbage);
1016});
1017
1018var Event = new Class({
1019
1020	initialize: function(event){
1021		if (event && event.$extended) return event;
1022		this.$extended = true;
1023		event = event || window.event;
1024		this.event = event;
1025		this.type = event.type;
1026		this.target = event.target || event.srcElement;
1027		if (this.target.nodeType == 3) this.target = this.target.parentNode;
1028		this.shift = event.shiftKey;
1029		this.control = event.ctrlKey;
1030		this.alt = event.altKey;
1031		this.meta = event.metaKey;
1032		if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){
1033			this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
1034		} else if (this.type.contains('key')){
1035			this.code = event.which || event.keyCode;
1036			for (var name in Event.keys){
1037				if (Event.keys[name] == this.code){
1038					this.key = name;
1039					break;
1040				}
1041			}
1042			if (this.type == 'keydown'){
1043				var fKey = this.code - 111;
1044				if (fKey > 0 && fKey < 13) this.key = 'f' + fKey;
1045			}
1046			this.key = this.key || String.fromCharCode(this.code).toLowerCase();
1047		} else if (this.type.test(/(click|mouse|menu)/)){
1048			this.page = {
1049				'x': event.pageX || event.clientX + document.documentElement.scrollLeft,
1050				'y': event.pageY || event.clientY + document.documentElement.scrollTop
1051			};
1052			this.client = {
1053				'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
1054				'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
1055			};
1056			this.rightClick = (event.which == 3) || (event.button == 2);
1057			switch(this.type){
1058				case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break;
1059				case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement;
1060			}
1061			this.fixRelatedTarget();
1062		}
1063		return this;
1064	},
1065
1066	stop: function(){
1067		return this.stopPropagation().preventDefault();
1068	},
1069
1070	stopPropagation: function(){
1071		if (this.event.stopPropagation) this.event.stopPropagation();
1072		else this.event.cancelBubble = true;
1073		return this;
1074	},
1075
1076	preventDefault: function(){
1077		if (this.event.preventDefault) this.event.preventDefault();
1078		else this.event.returnValue = false;
1079		return this;
1080	}
1081
1082});
1083
1084Event.fix = {
1085
1086	relatedTarget: function(){
1087		if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode;
1088	},
1089
1090	relatedTargetGecko: function(){
1091		try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;}
1092	}
1093
1094};
1095
1096Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget;
1097
1098Event.keys = new Abstract({
1099	'enter': 13,
1100	'up': 38,
1101	'down': 40,
1102	'left': 37,
1103	'right': 39,
1104	'esc': 27,
1105	'space': 32,
1106	'backspace': 8,
1107	'tab': 9,
1108	'delete': 46
1109});
1110
1111Element.Methods.Events = {
1112
1113	addEvent: function(type, fn){
1114		this.$events = this.$events || {};
1115		this.$events[type] = this.$events[type] || {'keys': [], 'values': []};
1116		if (this.$events[type].keys.contains(fn)) return this;
1117		this.$events[type].keys.push(fn);
1118		var realType = type;
1119		var custom = Element.Events[type];
1120		if (custom){
1121			if (custom.add) custom.add.call(this, fn);
1122			if (custom.map) fn = custom.map;
1123			if (custom.type) realType = custom.type;
1124		}
1125		if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true});
1126		this.$events[type].values.push(fn);
1127		return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn
1127) : this;
1128	},
1129
1130	removeEvent: function(type, fn){
1131		if (!this.$events || !this.$events[type]) return this;
1132		var pos = this.$events[type].keys.indexOf(fn);
1133		if (pos == -1) return this;
1134		var key = this.$events[type].keys.splice(pos,1)[0];
1135		var value = this.$events[type].values.splice(pos,1)[0];
1136		var custom = Element.Events[type];
1137		if (custom){
1138			if (custom.remove) custom.remove.call(this, fn);
1139			if (custom.type) type = custom.type;
1140		}
1141		return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this;
1142	},
1143
1144	addEvents: function(source){
1145		return Element.setMany(this, 'addEvent', source);
1146	},
1147
1148	removeEvents: function(type){
1149		if (!this.$events) return this;
1150		if (!type){
1151			for (var evType in this.$events) this.removeEvents(evType);
1152			this.$events = null;
1153		} else if (this.$events[type]){
1154			this.$events[type].keys.each(function(fn){
1155				this.removeEvent(type, fn);
1156			}, this);
1157			this.$events[type] = null;
1158		}
1159		return this;
1160	},
1161
1162	fireEvent: function(type, args, delay){
1163		if (this.$events && this.$events[type]){
1164			this.$events[type].keys.each(function(fn){
1165				fn.create({'bind': this, 'delay': delay, 'arguments': args})();
1166			}, this);
1167		}
1168		return this;
1169	},
1170
1171	cloneEvents: function(from, type){
1172		if (!from.$events) return this;
1173		if (!type){
1174			for (var evType in from.$events) this.cloneEvents(from, evType);
1175		} else if (from.$events[type]){
1176			from.$events[type].keys.each(function(fn){
1177				this.addEvent(type, fn);
1178			}, this);
1179		}
1180		return this;
1181	}
1182
1183};
1184
1185window.extend(Element.Methods.Events);
1186document.extend(Element.Methods.Events);
1187Element.extend(Element.Methods.Events);
1188
1189Element.Events = new Abstract({
1190
1191	'mouseenter': {
1192		type: 'mouseover',
1193		map: function(event){
1194			event = new Event(event);
1195			if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event);
1196		}
1197	},
1198
1199	'mouseleave': {
1200		type: 'mouseout',
1201		map: function(event){
1202			event = new Event(event);
1203			if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event);
1204		}
1205	},
1206
1207	'mousewheel': {
1208		type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel'
1209	}
1210
1211});
1212
1213Element.NativeEvents = [
1214	'click', 'dblclick', 'mouseup', 'mousedown',
1215	'mousewheel', 'DOMMouseScroll',
1216	'mouseover', 'mouseout', 'mousemove',
1217	'keydown', 'keypress', 'keyup',
1218	'load', 'unload', 'beforeunload', 'resize', 'move',
1219	'focus', 'blur', 'change', 'submit', 'reset', 'select',
1220	'error', 'abort', 'contextmenu', 'scroll'
1221];
1222
1223Function.extend({
1224
1225	bindWithEvent: function(bind, args){
1226		return this.create({'bind': bind, 'arguments': args, 'event': Event});
1227	}
1228
1229});
1230
1231Elements.extend({
1232
1233	filterByTag: function(tag){
1234		return new Elements(this.filter(function(el){
1235			return (Element.getTag(el) == tag);
1236		}));
1237	},
1238
1239	filterByClass: function(className, nocash){
1240		var elements = this.filter(function(el){
1241			return (el.className && el.className.contains(className, ' '));
1242		});
1243		return (nocash) ? elements : new Elements(elements);
1244	},
1245
1246	filterById: function(id, nocash){
1247		var elements = this.filter(function(el){
1248			return (el.id == id);
1249		});
1250		return (nocash) ? elements : new Elements(elements);
1251	},
1252
1253	filterByAttribute: function(name, operator, value, nocash){
1254		var elements = this.filter(function(el){
1255			var current = Element.getProperty(el, name);
1256			if (!current) return false;
1257			if (!operator) return true;
1258			switch(operator){
1259				case '=': return (current == value);
1260				case '*=': return (current.contains(value));
1261				case '^=': return (current.substr(0, value.length) == value);
1262				case '$=': return (current.substr(current.length - value.length) == value);
1263				case '!=': return (current != value);
1264				case '~=': return current.contains(value, ' ');
1265			}
1266			return false;
1267		});
1268		return (nocash) ? elements : new Elements(elements);
1269	}
1270
1271});
1272
1273function $E(selector, filter){
1274	return ($(filter) || document).getElement(selector);
1275};
1276
1277function $ES(selector, filter){
1278	return ($(filter) || document).getElementsBySelector(selector);
1279};
1280
1281$$.shared = {
1282
1283	'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,
1284
1285	'xpath': {
1286
1287		getParam: function(items, context, param, i){
1288			var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]];
1289			if (param[2]) temp.push('[@id="', param[2], '"]');
1290			if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]');
1291			if (param[4]){
1292				if (param[5] && param[6]){
1293					switch(param[5]){
1294						case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break;
1295						case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break;
1296						case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break;
1297						case '=': temp.push('[@', param[4], '="', param[6], '"]'); break;
1298						case '!=': temp.push('[@', param[4], '!="', param[6], '"]');
1299					}
1300				} else {
1301					temp.push('[@', param[4], ']');
1302				}
1303			}
1304			items.push(temp.join(''));
1305			return items;
1306		},
1307
1308		getItems: function(items, context, nocash){
1309			var elements = [];
1310			var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
1311			for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i));
1312			return (nocash) ? elements : new Elements(elements.map($));
1313		}
1314
1315	},
1316
1317	'normal': {
1318
1319		getParam: function(items, context, param, i){
1320			if (i == 0){
1321				if (param[2]){
1322					var el = context.getElementById(param[2]);
1323					if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false;
1324					items = [el];
1325				} else {
1326					items = $A(context.getElementsByTagName(param[1]));
1327				}
1328			} else {
1329				items = $$.shared.getElementsByTagName(items, param[1]);
1330				if (param[2]) items = Elements.filterById(items, param[2], true);
1331			}
1332			if (param[3]) items = Elements.filterByClass(items, param[3], true);
1333			if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true);
1334			return items;
1335		},
1336
1337		getItems: function(items, context, nocash){
1338			return (nocash) ? items : $$.unique(items);
1339		}
1340
1341	},
1342
1343	resolver: function(prefix){
1344		return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false;
1345	},
1346
1347	getElementsByTagName: function(context, tagName){
1348		var found = [];
1349		for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName));
1350		return found;
1351	}
1352
1353};
1354
1355$$.shared.method = (window.xpath) ? 'xpath' : 'normal';
1356
1357Element.Methods.Dom = {
1358
1359	getElements: function(selector, nocash){
1360		var items = [];
1361		selector = selector.trim().split(' ');
1362		for (var i = 0, j = selector.length; i < j; i++){
1363			var sel = selector[i];
1364			var param = sel.match($$.shared.regexp);
1365			if (!param) break;
1366			param[1] = param[1] || '*';
1367			var temp = $$.shared[$$.shared.method].getParam(items, this, param, i);
1368			if (!temp) break;
1369			items = temp;
1370		}
1371		return $$.shared[$$.shared.method].getItems(items, this, nocash);
1372	},
1373
1374	getElement: function(selector){
1375		return $(this.getElements(selector, true)[0] || false);
1376	},
1377
1378	getElementsBySelector: function(selector, nocash){
1379		var elements = [];
1380		selector = selector.split(',');
1381		for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true));
1382		return (nocash) ? elements : $$.unique(elements);
1383	}
1384
1385};
1386
1387Element.extend({
1388
1389	getElementById: function(id){
1390		var el = document.getElementById(id);
1391		if (!el) return false;
1392		for (var parent = el.parentNode; parent != this; parent = parent.parentNode){
1393			if (!parent) return false;
1394		}
1395		return el;
1396	}/*compatibility*/,
1397
1398	getElementsByClassName: function(className){ 
1399		return this.getElements('.' + className); 
1400	}
1401
1402});
1403
1404document.extend(Element.Methods.Dom);
1405Element.extend(Element.Methods.Dom);
1406
1407Element.extend({
1408
1409	getValue: function(){
1410		switch(this.getTag()){
1411			case 'select':
1412				var values = [];
1413				$each(this.options, function(option){
1414					if (option.selected) values.push($pick(option.value, option.text));
1415				});
1416				return (this.multiple) ? values : values[0];
1417			case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break;
1418			case 'textarea': return this.value;
1419		}
1420		return false;
1421	},
1422
1423	getFormElements: function(){
1424		return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea'));
1425	},
1426
1427	toQueryString: function(){
1428		var queryString = [];
1429		this.getFormElements().each(function(el){
1430			var name = el.name;
1431			var value = el.getValue();
1432			if (value === false || !name || el.disabled) return;
1433			var qs = function(val){
1434				queryString.push(name + '=' + encodeURIComponent(val));
1435			};
1436			if ($type(value) == 'array') value.each(qs);
1437			else qs(value);
1438		});
1439		return queryString.join('&');
1440	}
1441
1442});
1443
1444Element.extend({
1445
1446	scrollTo: function(x, y){
1447		this.scrollLeft = x;
1448		this.scrollTop = y;
1449	},
1450
1451	getSize: function(){
1452		return {
1453			'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
1454			'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
1455			'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight}
1456		};
1457	},
1458
1459	getPosition: function(overflown){
1460		overflown = overflown || [];
1461		var el = this, left = 0, top = 0;
1462		do {
1463			left += el.offsetLeft || 0;
1464			top += el.offsetTop || 0;
1465			el = el.offsetParent;
1466		} while (el);
1467		overflown.each(function(element){
1468			left -= element.scrollLeft || 0;
1469			top -= element.scrollTop || 0;
1470		});
1471		return {'x': left, 'y': top};
1472	},
1473
1474	getTop: function(overflown){
1475		return this.getPosition(overflown).y;
1476	},
1477
1478	getLeft: function(overflown){
1479		return this.getPosition(overflown).x;
1480	},
1481
1482	getCoordinates: function(overflown){
1483		var position = this.getPosition(overflown);
1484		var obj = {
1485			'width': this.offsetWidth,
1486			'height': this.offsetHeight,
1487			'left': position.x,
1488			'top': position.y
1489		};
1490		obj.right = obj.left + obj.width;
1491		obj.bottom = obj.top + obj.height;
1492		return obj;
1493	}
1494
1495});
1496
1497Element.Events.domready = {
1498
1499	add: function(fn){
1500		if (window.loaded){
1501			fn.call(this);
1502			return;
1503		}
1504		var domReady = function(){
1505			if (window.loaded) return;
1506			window.loaded = true;
1507			window.timer = $clear(window.timer);
1508			this.fireEvent('domready');
1509		}.bind(this);
1510		if (document.readyState && window.webkit){
1511			window.timer = function(){
1512				if (['loaded','complete'].contains(document.readyState)) domReady();
1513			}.periodical(50);
1514		} else if (document.readyState && window.ie){
1515			if (!$('ie_ready')){
1516				var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
1517				document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
1518				$('ie_ready').onreadystatechange = function(){
1519					if (this.readyState == 'complete') domReady();
1520				};
1521			}
1522		} else {
1523			window.addListener("load", domReady);
1524			document.addListener("DOMContentLoaded", domReady);
1525		}
1526	}
1527
1528};
1529
1530window.onDomReady = function(fn){ 
1531	return this.addEvent('domready', fn); 
1532};
1533
1534window.extend({
1535
1536	getWidth: function(){
1537		if (this.webkit419) return this.innerWidth;
1538		if (this.opera) return document.body.clientWidth;
1539		return document.documentElement.clientWidth;
1540	},
1541
1542	getHeight: function(){
1543		if (this.webkit419) return this.innerHeight;
1544		if (this.opera) return document.body.clientHeight;
1545		return document.documentElement.clientHeight;
1546	},
1547
1548	getScrollWidth: function(){
1549		if (this.ie) return Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth);
1550		if (this.webkit) return document.body.scrollWidth;
1551		return document.documentElement.scrollWidth;
1552	},
1553
1554	getScrollHeight: function(){
1555		if (this.ie) return Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight);
1556		if (this.webkit) return document.body.scrollHeight;
1557		return document.documentElement.scrollHeight;
1558	},
1559
1560	getScrollLeft: function(){
1561		return this.pageXOffset || document.documentElement.scrollLeft;
1562	},
1563
1564	getScrollTop: function(){
1565		return this.pageYOffset || document.documentElement.scrollTop;
1566	},
1567
1568	getSize: function(){
1569		return {
1570			'size': {'x': this.getWidth(), 'y': this.getHeight()},
1571			'scrollSize': {'x': this.getScrollWidth(), 'y': this.getScrollHeight()},
1572			'scroll': {'x': this.getScrollLeft(), 'y': this.getScrollTop()}
1573		};
1574	},
1575	getPosition: function(){return {'x': 0, 'y': 0};}
1576
1577});
1578
1579var Fx = {};
1580
1581Fx.Base = new Class({
1582
1583	options: {
1584		onStart: Class.empty,
1585		onComplete: Class.empty,
1586		onCancel: Class.empty,
1587		transition: function(p){
1588			return -(Math.cos(Math.PI * p) - 1) / 2;
1589		},
1590		duration: 500,
1591		unit: 'px',
1592		wait: true,
1593		fps: 50
1594	},
1595
1596	initialize: function(options){
1597		this.element = this.element || null;
1598		this.setOptions(options);
1599		if (this.options.initialize) this.options.initialize.call(this);
1600	},
1601
1602	step: function(){
1603		var time = $time();
1604		if (time < this.time + this.options.duration){
1605			this.delta = this.options.transition((time - this.time) / this.options.duration);
1606			this.setNow();
1607			this.increase();
1608		} else {
1609			this.stop(true);
1610			this.set(this.to);
1611			this.fireEvent('onComplete', this.element, 10);
1612			this.callChain();
1613		}
1614	},
1615
1616	set: function(to){
1617		this.now = to;
1618		this.increase();
1619		return this;
1620	},
1621
1622	setNow: function(){
1623		this.now = this.compute(this.from, this.to);
1624	},
1625
1626	compute: function(from, to){
1627		return (to - from) * this.delta + from;
1628	},
1629
1630	start: function(from, to){
1631		if (!this.options.wait) this.stop();
1632		else if (this.timer) return this;
1633		this.from = from;
1634		this.to = to;
1635		this.change = this.to - this.from;
1636		this.time = $time();
1637		this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
1638		this.fireEvent('onStart', this.element);
1639		return this;
1640	},
1641
1642	stop: function(end){
1643		if (!this.timer) return this;
1644		this.timer = $clear(this.timer);
1645		if (!end) this.fireEvent('onCancel', this.element);
1646		return this;
1647	}/*compatibility*/,
1648
1649	custom: function(from, to){
1650		return this.start(from, to);
1651	},
1652
1653	clearTimer: function(end){
1654		return this.stop(end);
1655	}
1656
1657});
1658
1659Fx.Base.implement(new Chain, new Events, new Options);
1660
1661Fx.CSS = {
1662
1663	select: function(property, to){
1664		if (property.test(/color/i)) return this.Color;
1665		var type = $type(to);
1666		if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi;
1667		return this.Single;
1668	},
1669
1670	parse: function(el, property, fromTo){
1671		if (!fromTo.push) fromTo = [fromTo];
1672		var from = fromTo[0], to = fromTo[1];
1673		if (!$chk(to)){
1674			to = from;
1675			from = el.getStyle(property);
1676		}
1677		var css = this.select(property, to);
1678		return {'from': css.parse(from), 'to': css.parse(to), 'css': css};
1679	}
1680
1681};
1682
1683Fx.CSS.Single = {
1684
1685	parse: function(value){
1686		return parseFloat(value);
1687	},
1688
1689	getNow: function(from, to, fx){
1690		return fx.compute(from, to);
1691	},
1692
1693	getValue: function(value, unit, property){
1694		if (unit == 'px' && property != 'opacity') value = Math.round(value);
1695		return value + unit;
1696	}
1697
1698};
1699
1700Fx.CSS.Multi = {
1701
1702	parse: function(value){
1703		return value.push ? value : value.split(' ').map(function(v){
1704			return parseFloat(v);
1705		});
1706	},
1707
1708	getNow: function(from, to, fx){
1709		var now = [];
1710		for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]);
1711		return now;
1712	},
1713
1714	getValue: function(value, unit, property){
1715		if (unit == 'px' && property != 'opacity') value = value.map(Math.round);
1716		return value.join(unit + ' ') + unit;
1717	}
1718
1719};
1720
1721Fx.CSS.Color = {
1722
1723	parse: function(value){
1724		return value.push ? value : value.hexToRgb(true);
1725	},
1726
1727	getNow: function(from, to, fx){
1728		var now = [];
1729		for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
1730		return now;
1731	},
1732
1733	getValue: function(value){
1734		return 'rgb(' + value.join(',') + ')';
1735	}
1736
1737};
1738
1739Fx.Style = Fx.Base.extend({
1740
1741	initialize: function(el, property, options){
1742		this.element = $(el);
1743		this.property = property;
1744		this.parent(options);
1745	},
1746
1747	hide: function(){
1748		return this.set(0);
1749	},
1750
1751	setNow: function(){
1752		this.now = this.css.getNow(this.from, this.to, this);
1753	},
1754
1755	set: function(to){
1756		this.css = Fx.CSS.select(this.property, to);
1757		return this.parent(this.css.parse(to));
1758	},
1759
1760	start: function(from, to){
1761		if (this.timer && this.options.wait) return this;
1762		var parsed = Fx.CSS.parse(this.element, this.property, [from, to]);
1763		this.css = parsed.css;
1764		return this.parent(parsed.from, parsed.to);
1765	},
1766
1767	increase: function(){
1768		this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit, this.property));
1769	}
1770
1771});
1772
1773Element.extend({
1774
1775	effect: function(property, options){
1776		return new Fx.Style(this, property, options);
1777	}
1778
1779});
1780
1781Fx.Styles = Fx.Base.extend({
1782
1783	initialize: function(el, options){
1784		this.element = $(el);
1785		this.parent(options);
1786	},
1787
1788	setNow: function(){
1789		for (var p in this.from) this.now[p] = this.css[p].getNow(this.from[p], this.to[p], this);
1790	},
1791
1792	set: function(to){
1793		var parsed = {};
1794		this.css = {};
1795		for (var p in to){
1796			this.css[p] = Fx.CSS.select(p, to[p]);
1797			parsed[p] = this.css[p].parse(to[p]);
1798		}
1799		return this.parent(parsed);
1800	},
1801
1802	start: function(obj){
1803		if (this.timer && this.options.wait) return this;
1804		this.now = {};
1805		this.css = {};
1806		var from = {}, to = {};
1807		for (var p in obj){
1808			var parsed = Fx.CSS.parse(this.element, p, obj[p]);
1809			from[p] = parsed.from;
1810			to[p] = parsed.to;
1811			this.css[p] = parsed.css;
1812		}
1813		return this.parent(from, to);
1814	},
1815
1816	increase: function(){
1817		for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p));
1818	}
1819
1820});
1821
1822Element.extend({
1823
1824	effects: function(options){
1825		return new Fx.Styles(this, options);
1826	}
1827
1828});
1829
1830Fx.Elements = Fx.Base.extend({
1831
1832	initialize: function(elements, options){
1833		this.elements = $$(elements);
1834		this.parent(options);
1835	},
1836
1837	setNow: function(){
1838		for (var i in this.from){
1839			var iFrom = this.from[i], iTo = this.to[i], iCss = this.css[i], iNow = this.now[i] = {};
1840			for (var p in iFrom) iNow[p] = iCss[p].getNow(iFrom[p], iTo[p], this);
1841		}
1842	},
1843
1844	set: function(to){
1845		var parsed = {};
1846		this.css = {};
1847		for (var i in to){
1848			var iTo = to[i], iCss = this.css[i] = {}, iParsed = parsed[i] = {};
1849			for (var p in iTo){
1850				iCss[p] = Fx.CSS.select(p, iTo[p]);
1851				iParsed[p] = iCss[p].parse(iTo[p]);
1852			}
1853		}
1854		return this.parent(parsed);
1855	},
1856
1857	start: function(obj){
1858		if (this.timer && this.options.wait) return this;
1859		this.now = {};
1860		this.css = {};
1861		var from = {}, to = {};
1862		for (var i in obj){
1863			var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {}, iCss = this.css[i] = {};
1864			for (var p in iProps){
1865				var parsed = Fx.CSS.parse(this.elements[i], p, iProps[p]);
1866				iFrom[p] = parsed.from;
1867				iTo[p] = parsed.to;
1868				iCss[p] = parsed.css;
1869			}
1870		}
1871		return this.parent(from, to);
1872	},
1873
1874	increase: function(){
1875		for (var i in this.now){
1876			var iNow = this.now[i], iCss = this.css[i];
1877			for (var p in iNow) this.elements[i].setStyle(p, iCss[p].getValue(iNow[p], this.options.unit, p));
1878		}
1879	}
1880
1881});
1882
1883Fx.Scroll = Fx.Base.extend({
1884
1885	options: {
1886		overflown: [],
1887		offset: {'x': 0, 'y': 0},
1888		wheelStops: true
1889	},
1890
1891	initialize: function(element, options){
1892		this.now = [];
1893		this.element = $(element);
1894		this.bound = {'stop': this.stop.bind(this, false)};
1895		this.parent(options);
1896		if (this.options.wheelStops){
1897			this.addEvent('onStart', function(){
1898				document.addEvent('mousewheel', this.bound.stop);
1899			}.bind(this));
1900			this.addEvent('onComplete', function(){
1901				document.removeEvent('mousewheel', this.bound.stop);
1902			}.bind(this));
1903		}
1904	},
1905
1906	setNow: function(){
1907		for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
1908	},
1909
1910	scrollTo: function(x, y){
1911		if (this.timer && this.options.wait) return this;
1912		var el = this.element.getSize();
1913		var values = {'x': x, 'y': y};
1914		for (var z in el.size){
1915			var max = el.scrollSize[z] - el.size[z];
1916			if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
1917			else values[z] = el.scroll[z];
1918			values[z] += this.options.offset[z];
1919		}
1920		return this.start([el.scroll.x, el.scroll.y], [values.x, values.y]);
1921	},
1922
1923	toTop: function(){
1924		return this.scrollTo(false, 0);
1925	},
1926
1927	toBottom: function(){
1928		return this.scrollTo(false, 'full');
1929	},
1930
1931	toLeft: function(){
1932		return this.scrollTo(0, false);
1933	},
1934
1935	toRight: function(){
1936		return this.scrollTo('full', false);
1937	},
1938
1939	toElement: function(el){
1940		var parent = this.element.getPosition(this.options.overflown);
1941		var target = $(el).getPosition(this.options.overflown);
1942		return this.scrollTo(target.x - parent.x, target.y - parent.y);
1943	},
1944
1945	increase: function(){
1946		this.element.scrollTo(this.now[0], this.now[1]);
1947	}
1948
1949});
1950
1951Fx.Slide = Fx.Base.extend({
1952
1953	options: {
1954		mode: 'vertical'
1955	},
1956
1957	initialize: function(el, options){
1958		this.element = $(el);
1959		this.wrapper = new Element('div', {'styles': $extend(this.element.getStyles('margin'), {'overflow': 'hidden'})}).injectAfter(this.element).adopt(this.element);
1960		this.element.setStyle('margin', 0);
1961		this.setOptions(options);
1962		this.now = [];
1963		this.parent(this.options);
1964		this.open = true;
1965		this.addEvent('onComplete', function(){
1966			this.open = (this.now[0] === 0);
1967		});
1968		if (window.webkit419) this.addEvent('onComplete', function(){
1969			if (this.open) this.element.remove().inject(this.wrapper);
1970		});
1971	},
1972
1973	setNow: function(){
1974		for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
1975	},
1976
1977	vertical: function(){
1978		this.margin = 'margin-top';
1979		this.layout = 'height';
1980		this.offset = this.element.offsetHeight;
1981	},
1982
1983	horizontal: function(){
1984		this.margin = 'margin-left';
1985		this.layout = 'width';
1986		this.offset = this.element.offsetWidth;
1987	},
1988
1989	slideIn: function(mode){
1990		this[mode || this.options.mode]();
1991		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
1992	},
1993
1994	slideOut: function(mode){
1995		this[mode || this.options.mode]();
1996		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [-this.offset, 0]);
1997	},
1998
1999	hide: function(mode){
2000		this[mode || this.options.mode]();
2001		this.open = false;
2002		return this.set([-this.offset, 0]);
2003	},
2004
2005	show: function(mode){
2006		this[mode || this.options.mode]();
2007		this.open = true;
2008		return this.set([0, this.offset]);
2009	},
2010
2011	toggle: function(mode){
2012		if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.slideIn(mode);
2013		return this.slideOut(mode);
2014	},
2015
2016	increase: function(){
2017		this.element.setStyle(this.margin, this.now[0] + this.options.unit);
2018		this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
2019	}
2020
2021});
2022
2023Fx.Transition = function(transition, params){
2024	params = params || [];
2025	if ($type(params) != 'array') params = [params];
2026	return $extend(transition, {
2027		easeIn: function(pos){
2028			return transition(pos, params);
2029		},
2030		easeOut: function(pos){
2031			return 1 - transition(1 - pos, params);
2032		},
2033		easeInOut: function(pos){
2034			return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
2035		}
2036	});
2037};
2038
2039Fx.Transitions = new Abstract({
2040
2041	linear: function(p){
2042		return p;
2043	}
2044
2045});
2046
2047Fx.Transitions.extend = function(transitions){
2048	for (var transition in transitions){
2049		Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
2050		Fx.Transitions.compat(transition);
2051	}
2052};
2053
2054Fx.Transitions.compat = function(transition){
2055	['In', 'Out', 'InOut'].each(function(easeType){
2056		Fx.Transitions[transition.toLowerCase() + easeType] = Fx.Transitions[transition]['ease' + easeType];
2057	});
2058};
2059
2060Fx.Transitions.extend({
2061
2062	Pow: function(p, x){
2063		return Math.pow(p, x[0] || 6);
2064	},
2065
2066	Expo: function(p){
2067		return Math.pow(2, 8 * (p - 1));
2068	},
2069
2070	Circ: function(p){
2071		return 1 - Math.sin(Math.acos(p));
2072	},
2073
2074	Sine: function(p){
2075		return 1 - Math.sin((1 - p) * Math.PI / 2);
2076	},
2077
2078	Back: function(p, x){
2079		x = x[0] || 1.618;
2080		return Math.pow(p, 2) * ((x + 1) * p - x);
2081	},
2082
2083	Bounce: function(p){
2084		var value;
2085		for (var a = 0, b = 1; 1; a += b, b /= 2){
2086			if (p >= (7 - 4 * a) / 11){
2087				value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
2088				break;
2089			}
2090		}
2091		return value;
2092	},
2093
2094	Elastic: function(p, x){
2095		return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
2096	}
2097
2098});
2099
2100['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
2101	Fx.Transitions[transition] = new Fx.Transition(function(p){
2102		return Math.pow(p, [i + 2]);
2103	});
2104	Fx.Transitions.compat(transition);
2105});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.