/* --- MooTools: the javascript framework web build: - http://mootools.net/core/76bf47062d6c1983d66ce47ad66aa0e0 packager build: - 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 Core/Swiff ... */ /* --- name: Core description: The heart of MooTools. license: MIT-style license. copyright: Copyright (c) 2006-2012 [Valerio Proietti](http://mad4milk.net/). authors: The MooTools production team (http://mootools.net/developers/) inspiration: - 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) - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) provides: [Core, MooTools, Type, typeOf, instanceOf, Native] ... */ (function () { this.MooTools = { version: "1.4.5", build: "ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0", }; // typeOf, instanceOf var typeOf = (this.typeOf = function (item) { if (item == null) return "null"; if (item.$family != null) return item.$family(); if (item.nodeName) { if (item.nodeType == 1) return "element"; if (item.nodeType == 3) return /\S/.test(item.nodeValue) ? "textnode" : "whitespace"; } else if (typeof item.length == "number") { if (item.callee) return "arguments"; if ("item" in item) return "collection"; } return typeof item; }); var instanceOf = (this.instanceOf = function (item, object) { if (item == null) return false; var constructor = item.$constructor || item.constructor; while (constructor) { if (constructor === object) return true; constructor = constructor.parent; } /**/ if (!item.hasOwnProperty) return false; /**/ return item instanceof object; }); // Function overloading var Function = this.Function; var enumerables = true; for (var i in { toString: 1 }) enumerables = null; if (enumerables) enumerables = [ "hasOwnProperty", "valueOf", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "constructor", ]; Function.prototype.overloadSetter = function (usePlural) { var self = this; return function (a, b) { if (a == null) return this; if (usePlural || typeof a != "string") { for (var k in a) self.call(this, k, a[k]); if (enumerables) for (var i = enumerables.length; i--; ) { k = enumerables[i]; if (a.hasOwnProperty(k)) self.call(this, k, a[k]); } } else { self.call(this, a, b); } return this; }; }; Function.prototype.overloadGetter = function (usePlural) { var self = this; return function (a) { var args, result; if (typeof a != "string") args = a; else if (arguments.length > 1) args = arguments; else if (usePlural) args = [a]; if (args) { result = {}; for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]); } else { result = self.call(this, a); } return result; }; }; Function.prototype.extend = function (key, value) { this[key] = value; }.overloadSetter(); Function.prototype.implement = function (key, value) { this.prototype[key] = value; }.overloadSetter(); // From var slice = Array.prototype.slice; Function.from = function (item) { return typeOf(item) == "function" ? item : function () { return item; }; }; Array.from = function (item) { if (item == null) return []; return Type.isEnumerable(item) && typeof item != "string" ? typeOf(item) == "array" ? item : slice.call(item) : [item]; }; Number.from = function (item) { var number = parseFloat(item); return isFinite(number) ? number : null; }; String.from = function (item) { return item + ""; }; // hide, protect Function.implement({ hide: function () { this.$hidden = true; return this; }, protect: function () { this.$protected = true; return this; }, }); // Type var Type = (this.Type = function (name, object) { if (name) { var lower = name.toLowerCase(); var typeCheck = function (item) { return typeOf(item) == lower; }; Type["is" + name] = typeCheck; if (object != null) { object.prototype.$family = function () { return lower; }.hide(); //<1.2compat> object.type = typeCheck; // } } if (object == null) return null; object.extend(this); object.$constructor = Type; object.prototype.$constructor = object; return object; }); var toString = Object.prototype.toString; Type.isEnumerable = function (item) { return ( item != null && typeof item.length == "number" && toString.call(item) != "[object Function]" ); }; var hooks = {}; var hooksOf = function (object) { var type = typeOf(object.prototype); return hooks[type] || (hooks[type] = []); }; var implement = function (name, method) { if (method && method.$hidden) return; var hooks = hooksOf(this); for (var i = 0; i < hooks.length; i++) { var hook = hooks[i]; if (typeOf(hook) == "type") implement.call(hook, name, method); else hook.call(this, name, method); } var previous = this.prototype[name]; if (previous == null || !previous.$protected) this.prototype[name] = method; if (this[name] == null && typeOf(method) == "function") extend.call(this, name, function (item) { return method.apply(item, slice.call(arguments, 1)); }); }; var extend = function (name, method) { if (method && method.$hidden) return; var previous = this[name]; if (previous == null || !previous.$protected) this[name] = method; }; Type.implement({ implement: implement.overloadSetter(), extend: extend.overloadSetter(), alias: function (name, existing) { implement.call(this, name, this.prototype[existing]); }.overloadSetter(), mirror: function (hook) { hooksOf(this).push(hook); return this; }, }); new Type("Type", Type); // Default Types var force = function (name, object, methods) { var isType = object != Object, prototype = object.prototype; if (isType) object = new Type(name, object); for (var i = 0, l = methods.length; i < l; i++) { var key = methods[i], generic = object[key], proto = prototype[key]; if (generic) generic.protect(); if (isType && proto) object.implement(key, proto.protect()); } if (isType) { var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]); object.forEachMethod = function (fn) { if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++) { fn.call(prototype, prototype[methods[i]], methods[i]); } for (var key in prototype) fn.call(prototype, prototype[key], key); }; } return force; }; force("String", String, [ "charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "quote", "replace", "search", "slice", "split", "substr", "substring", "trim", "toLowerCase", "toUpperCase", ])("Array", Array, [ "pop", "push", "reverse", "shift", "sort", "splice", "unshift", "concat", "join", "slice", "indexOf", "lastIndexOf", "filter", "forEach", "every", "map", "some", "reduce", "reduceRight", ])("Number", Number, [ "toExponential", "toFixed", "toLocaleString", "toPrecision", ])("Function", Function, ["apply", "call", "bind"])("RegExp", RegExp, [ "exec", "test", ])("Object", Object, [ "create", "defineProperty", "defineProperties", "keys", "getPrototypeOf", "getOwnPropertyDescriptor", "getOwnPropertyNames", "preventExtensions", "isExtensible", "seal", "isSealed", "freeze", "isFrozen", ])("Date", Date, ["now"]); Object.extend = extend.overloadSetter(); Date.extend("now", function () { return +new Date(); }); new Type("Boolean", Boolean); // fixes NaN returning as Number Number.prototype.$family = function () { return isFinite(this) ? "number" : "null"; }.hide(); // Number.random Number.extend("random", function (min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }); // forEach, each var hasOwnProperty = Object.prototype.hasOwnProperty; Object.extend("forEach", function (object, fn, bind) { for (var key in object) { if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object); } }); Object.each = Object.forEach; Array.implement({ forEach: function (fn, bind) { for (var i = 0, l = this.length; i < l; i++) { if (i in this) fn.call(bind, this[i], i, this); } }, each: function (fn, bind) { Array.forEach(this, fn, bind); return this; }, }); // Array & Object cloning, Object merging and appending var cloneOf = function (item) { switch (typeOf(item)) { case "array": return item.clone(); case "object": return Object.clone(item); default: return item; } }; Array.implement("clone", function () { var i = this.length, clone = new Array(i); while (i--) clone[i] = cloneOf(this[i]); return clone; }); var mergeOne = function (source, key, current) { switch (typeOf(current)) { case "object": if (typeOf(source[key]) == "object") Object.merge(source[key], current); else source[key] = Object.clone(current); break; case "array": source[key] = current.clone(); break; default: source[key] = current; } return source; }; Object.extend({ merge: function (source, k, v) { if (typeOf(k) == "string") return mergeOne(source, k, v); for (var i = 1, l = arguments.length; i < l; i++) { var object = arguments[i]; for (var key in object) mergeOne(source, key, object[key]); } return source; }, clone: function (object) { var clone = {}; for (var key in object) clone[key] = cloneOf(object[key]); return clone; }, append: function (original) { for (var i = 1, l = arguments.length; i < l; i++) { var extended = arguments[i] || {}; for (var key in extended) original[key] = extended[key]; } return original; }, }); // Object-less types ["Object", "WhiteSpace", "TextNode", "Collection", "Arguments"].each( function (name) { new Type(name); }, ); // Unique ID var UID = Date.now(); String.extend("uniqueID", function () { return (UID++).toString(36); }); //<1.2compat> var Hash = (this.Hash = new Type("Hash", function (object) { if (typeOf(object) == "hash") object = Object.clone(object.getClean()); for (var key in object) this[key] = object[key]; return this; })); Hash.implement({ forEach: function (fn, bind) { Object.forEach(this, fn, bind); }, getClean: function () { var clean = {}; for (var key in this) { if (this.hasOwnProperty(key)) clean[key] = this[key]; } return clean; }, getLength: function () { var length = 0; for (var key in this) { if (this.hasOwnProperty(key)) length++; } return length; }, }); Hash.alias("each", "forEach"); Object.type = Type.isObject; var Native = (this.Native = function (properties) { return new Type(properties.name, properties.initialize); }); Native.type = Type.type; Native.implement = function (objects, methods) { for (var i = 0; i < objects.length; i++) objects[i].implement(methods); return Native; }; var arrayType = Array.type; Array.type = function (item) { return instanceOf(item, Array) || arrayType(item); }; this.$A = function (item) { return Array.from(item).slice(); }; this.$arguments = function (i) { return function () { return arguments[i]; }; }; this.$chk = function (obj) { return !!(obj || obj === 0); }; this.$clear = function (timer) { clearTimeout(timer); clearInterval(timer); return null; }; this.$defined = function (obj) { return obj != null; }; this.$each = function (iterable, fn, bind) { var type = typeOf(iterable); (type == "arguments" || type == "collection" || type == "array" || type == "elements" ? Array : Object ).each(iterable, fn, bind); }; this.$empty = function () {}; this.$extend = function (original, extended) { return Object.append(original, extended); }; this.$H = function (object) { return new Hash(object); }; this.$merge = function () { var args = Array.slice(arguments); args.unshift({}); return Object.merge.apply(null, args); }; this.$lambda = Function.from; this.$mixin = Object.merge; this.$random = Number.random; this.$splat = Array.from; this.$time = Date.now; this.$type = function (object) { var type = typeOf(object); if (type == "elements") return "array"; return type == "null" ? false : type; }; this.$unlink = function (object) { switch (typeOf(object)) { case "object": return Object.clone(object); case "array": return Array.clone(object); case "hash": return new Hash(object); default: return object; } }; // })(); /* --- name: Array description: Contains Array Prototypes like each, contains, and erase. license: MIT-style license. requires: Type provides: Array ... */ Array.implement({ /**/ every: function (fn, bind) { for (var i = 0, l = this.length >>> 0; i < l; i++) { if (i in this && !fn.call(bind, this[i], i, this)) return false; } return true; }, filter: function (fn, bind) { var results = []; for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this) { value = this[i]; if (fn.call(bind, value, i, this)) results.push(value); } return results; }, indexOf: function (item, from) { var length = this.length >>> 0; for ( var i = from < 0 ? Math.max(0, length + from) : from || 0; i < length; i++ ) { if (this[i] === item) return i; } return -1; }, map: function (fn, bind) { var length = this.length >>> 0, results = Array(length); for (var i = 0; i < length; i++) { if (i in this) results[i] = fn.call(bind, this[i], i, this); } return results; }, some: function (fn, bind) { for (var i = 0, l = this.length >>> 0; i < l; i++) { if (i in this && fn.call(bind, this[i], i, this)) return true; } return false; }, /**/ clean: function () { return this.filter(function (item) { return item != null; }); }, invoke: function (methodName) { var args = Array.slice(arguments, 1); return this.map(function (item) { return item[methodName].apply(item, args); }); }, associate: function (keys) { var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; }, link: function (object) { var result = {}; for (var i = 0, l = this.length; i < l; i++) { for (var key in object) { if (object[key](this[i])) { result[key] = this[i]; delete object[key]; break; } } } return result; }, contains: function (item, from) { return this.indexOf(item, from) != -1; }, append: function (array) { this.push.apply(this, array); return this; }, getLast: function () { return this.length ? this[this.length - 1] : null; }, getRandom: function () { return this.length ? this[Number.random(0, this.length - 1)] : null; }, include: function (item) { if (!this.contains(item)) this.push(item); return this; }, combine: function (array) { for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); return this; }, erase: function (item) { for (var i = this.length; i--; ) { if (this[i] === item) this.splice(i, 1); } return this; }, empty: function () { this.length = 0; return this; }, flatten: function () { var array = []; for (var i = 0, l = this.length; i < l; i++) { var type = typeOf(this[i]); if (type == "null") continue; array = array.concat( type == "array" || type == "collection" || type == "arguments" || instanceOf(this[i], Array) ? Array.flatten(this[i]) : this[i], ); } return array; }, pick: function () { for (var i = 0, l = this.length; i < l; i++) { if (this[i] != null) return this[i]; } return null; }, hexToRgb: function (array) { if (this.length != 3) return null; var rgb = this.map(function (value) { if (value.length == 1) value += value; return value.toInt(16); }); return array ? rgb : "rgb(" + rgb + ")"; }, rgbToHex: function (array) { if (this.length < 3) return null; if (this.length == 4 && this[3] == 0 && !array) return "transparent"; var hex = []; for (var i = 0; i < 3; i++) { var bit = (this[i] - 0).toString(16); hex.push(bit.length == 1 ? "0" + bit : bit); } return array ? hex : "#" + hex.join(""); }, }); //<1.2compat> Array.alias("extend", "append"); var $pick = function () { return Array.from(arguments).pick(); }; // /* --- name: String description: Contains String Prototypes like camelCase, capitalize, test, and toInt. license: MIT-style license. requires: Type provides: String ... */ String.implement({ test: function (regex, params) { return ( typeOf(regex) == "regexp" ? regex : new RegExp("" + regex, params) ).test(this); }, contains: function (string, separator) { return separator ? (separator + this + separator).indexOf(separator + string + separator) > -1 : String(this).indexOf(string) > -1; }, trim: function () { return String(this).replace(/^\s+|\s+$/g, ""); }, clean: function () { return String(this).replace(/\s+/g, " ").trim(); }, camelCase: function () { return String(this).replace(/-\D/g, function (match) { return match.charAt(1).toUpperCase(); }); }, hyphenate: function () { return String(this).replace(/[A-Z]/g, function (match) { return "-" + match.charAt(0).toLowerCase(); }); }, capitalize: function () { return String(this).replace(/\b[a-z]/g, function (match) { return match.toUpperCase(); }); }, escapeRegExp: function () { return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); }, toInt: function (base) { return parseInt(this, base || 10); }, toFloat: function () { return parseFloat(this); }, hexToRgb: function (array) { var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); return hex ? hex.slice(1).hexToRgb(array) : null; }, rgbToHex: function (array) { var rgb = String(this).match(/\d{1,3}/g); return rgb ? rgb.rgbToHex(array) : null; }, substitute: function (object, regexp) { return String(this).replace( regexp || /\\?\{([^{}]+)\}/g, function (match, name) { if (match.charAt(0) == "\\") return match.slice(1); return object[name] != null ? object[name] : ""; }, ); }, }); /* --- name: Number description: Contains Number Prototypes like limit, round, times, and ceil. license: MIT-style license. requires: Type provides: Number ... */ Number.implement({ limit: function (min, max) { return Math.min(max, Math.max(min, this)); }, round: function (precision) { precision = Math.pow(10, precision || 0).toFixed( precision < 0 ? -precision : 0, ); return Math.round(this * precision) / precision; }, times: function (fn, bind) { for (var i = 0; i < this; i++) fn.call(bind, i, this); }, toFloat: function () { return parseFloat(this); }, toInt: function (base) { return parseInt(this, base || 10); }, }); Number.alias("each", "times"); (function (math) { var methods = {}; math.each(function (name) { if (!Number[name]) methods[name] = function () { return Math[name].apply(null, [this].concat(Array.from(arguments))); }; }); Number.implement(methods); })([ "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "exp", "floor", "log", "max", "min", "pow", "sin", "sqrt", "tan", ]); /* --- name: Function description: Contains Function Prototypes like create, bind, pass, and delay. license: MIT-style license. requires: Type provides: Function ... */ Function.extend({ attempt: function () { for (var i = 0, l = arguments.length; i < l; i++) { try { return arguments[i](); } catch (e) {} } return null; }, }); Function.implement({ attempt: function (args, bind) { try { return this.apply(bind, Array.from(args)); } catch (e) {} return null; }, /**/ bind: function (that) { var self = this, args = arguments.length > 1 ? Array.slice(arguments, 1) : null, F = function () {}; var bound = function () { var context = that, length = arguments.length; if (this instanceof bound) { F.prototype = self.prototype; context = new F(); } var result = !args && !length ? self.call(context) : self.apply( context, args && length ? args.concat(Array.slice(arguments)) : args || arguments, ); return context == that ? result : context; }; return bound; }, /**/ pass: function (args, bind) { var self = this; if (args != null) args = Array.from(args); return function () { return self.apply(bind, args || arguments); }; }, delay: function (delay, bind, args) { return setTimeout(this.pass(args == null ? [] : args, bind), delay); }, periodical: function (periodical, bind, args) { return setInterval(this.pass(args == null ? [] : args, bind), periodical); }, }); //<1.2compat> delete Function.prototype.bind; Function.implement({ create: function (options) { var self = this; options = options || {}; return function (event) { var args = options.arguments; args = args != null ? Array.from(args) : Array.slice(arguments, options.event ? 1 : 0); if (options.event) args = [event || window.event].extend(args); var returns = function () { return self.apply(options.bind || null, args); }; if (options.delay) return setTimeout(returns, options.delay); if (options.periodical) return setInterval(returns, options.periodical); if (options.attempt) return Function.attempt(returns); return returns(); }; }, bind: function (bind, args) { var self = this; if (args != null) args = Array.from(args); return function () { return self.apply(bind, args || arguments); }; }, bindWithEvent: function (bind, args) { var self = this; if (args != null) args = Array.from(args); return function (event) { return self.apply(bind, args == null ? arguments : [event].concat(args)); }; }, run: function (args, bind) { return this.apply(bind, Array.from(args)); }, }); if (Object.create == Function.prototype.create) Object.create = null; var $try = Function.attempt; // /* --- name: Object description: Object generic methods license: MIT-style license. requires: Type provides: [Object, Hash] ... */ (function () { var hasOwnProperty = Object.prototype.hasOwnProperty; Object.extend({ subset: function (object, keys) { var results = {}; for (var i = 0, l = keys.length; i < l; i++) { var k = keys[i]; if (k in object) results[k] = object[k]; } return results; }, map: function (object, fn, bind) { var results = {}; for (var key in object) { if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object); } return results; }, filter: function (object, fn, bind) { var results = {}; for (var key in object) { var value = object[key]; if ( hasOwnProperty.call(object, key) && fn.call(bind, value, key, object) ) results[key] = value; } return results; }, every: function (object, fn, bind) { for (var key in object) { if ( hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key) ) return false; } return true; }, some: function (object, fn, bind) { for (var key in object) { if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true; } return false; }, keys: function (object) { var keys = []; for (var key in object) { if (hasOwnProperty.call(object, key)) keys.push(key); } return keys; }, values: function (object) { var values = []; for (var key in object) { if (hasOwnProperty.call(object, key)) values.push(object[key]); } return values; }, getLength: function (object) { return Object.keys(object).length; }, keyOf: function (object, value) { for (var key in object) { if (hasOwnProperty.call(object, key) && object[key] === value) return key; } return null; }, contains: function (object, value) { return Object.keyOf(object, value) != null; }, toQueryString: function (object, base) { var queryString = []; Object.each(object, function (value, key) { if (base) key = base + "[" + key + "]"; var result; switch (typeOf(value)) { case "object": result = Object.toQueryString(value, key); break; case "array": var qs = {}; value.each(function (val, i) { qs[i] = val; }); result = Object.toQueryString(qs, key); break; default: result = key + "=" + encodeURIComponent(value); } if (value != null) queryString.push(result); }); return queryString.join("&"); }, }); })(); //<1.2compat> Hash.implement({ has: Object.prototype.hasOwnProperty, keyOf: function (value) { return Object.keyOf(this, value); }, hasValue: function (value) { return Object.contains(this, value); }, extend: function (properties) { Hash.each( properties || {}, function (value, key) { Hash.set(this, key, value); }, this, ); return this; }, combine: function (properties) { Hash.each( properties || {}, function (value, key) { Hash.include(this, key, value); }, this, ); return this; }, erase: function (key) { if (this.hasOwnProperty(key)) delete this[key]; return this; }, get: function (key) { return this.hasOwnProperty(key) ? this[key] : null; }, set: function (key, value) { if (!this[key] || this.hasOwnProperty(key)) this[key] = value; return this; }, empty: function () { Hash.each( this, function (value, key) { delete this[key]; }, this, ); return this; }, include: function (key, value) { if (this[key] == null) this[key] = value; return this; }, map: function (fn, bind) { return new Hash(Object.map(this, fn, bind)); }, filter: function (fn, bind) { return new Hash(Object.filter(this, fn, bind)); }, every: function (fn, bind) { return Object.every(this, fn, bind); }, some: function (fn, bind) { return Object.some(this, fn, bind); }, getKeys: function () { return Object.keys(this); }, getValues: function () { return Object.values(this); }, toQueryString: function (base) { return Object.toQueryString(this, base); }, }); Hash.extend = Object.append; Hash.alias({ indexOf: "keyOf", contains: "hasValue" }); // /* --- name: Browser description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash. license: MIT-style license. requires: [Array, Function, Number, String] provides: [Browser, Window, Document] ... */ (function () { var document = this.document; var window = (document.window = this); var ua = navigator.userAgent.toLowerCase(), platform = navigator.platform.toLowerCase(), UA = ua.match( /(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/, ) || [null, "unknown", 0], mode = UA[1] == "ie" && document.documentMode; var Browser = (this.Browser = { extend: Function.prototype.extend, name: UA[1] == "version" ? UA[3] : UA[1], version: mode || parseFloat(UA[1] == "opera" && UA[4] ? UA[4] : UA[2]), Platform: { name: ua.match(/ip(?:ad|od|hone)/) ? "ios" : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ["other"])[0], }, Features: { xpath: !!document.evaluate, air: !!window.runtime, query: !!document.querySelector, json: !!window.JSON, }, Plugins: {}, }); Browser[Browser.name] = true; Browser[Browser.name + parseInt(Browser.version, 10)] = true; Browser.Platform[Browser.Platform.name] = true; // Request Browser.Request = (function () { var XMLHTTP = function () { return new XMLHttpRequest(); }; var MSXML2 = function () { return new ActiveXObject("MSXML2.XMLHTTP"); }; var MSXML = function () { return new ActiveXObject("Microsoft.XMLHTTP"); }; return Function.attempt( function () { XMLHTTP(); return XMLHTTP; }, function () { MSXML2(); return MSXML2; }, function () { MSXML(); return MSXML; }, ); })(); Browser.Features.xhr = !!Browser.Request; // Flash detection var version = ( Function.attempt( function () { return navigator.plugins["Shockwave Flash"].description; }, function () { return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable( "$version", ); }, ) || "0 r0" ).match(/\d+/g); Browser.Plugins.Flash = { version: Number(version[0] || "0." + version[1]) || 0, build: Number(version[2]) || 0, }; // String scripts Browser.exec = function (text) { if (!text) return text; if (window.execScript) { window.execScript(text); } else { var script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.text = text; document.head.appendChild(script); document.head.removeChild(script); } return text; }; String.implement("stripScripts", function (exec) { var scripts = ""; var text = this.replace( /]*>([\s\S]*?)<\/script>/gi, function (all, code) { scripts += code + "\n"; return ""; }, ); if (exec === true) Browser.exec(scripts); else if (typeOf(exec) == "function") exec(scripts, text); return text; }); // Window, Document Browser.extend({ Document: this.Document, Window: this.Window, Element: this.Element, Event: this.Event, }); this.Window = this.$constructor = new Type("Window", function () {}); this.$family = Function.from("window").hide(); Window.mirror(function (name, method) { window[name] = method; }); this.Document = document.$constructor = new Type("Document", function () {}); document.$family = Function.from("document").hide(); Document.mirror(function (name, method) { document[name] = method; }); document.html = document.documentElement; if (!document.head) document.head = document.getElementsByTagName("head")[0]; if (document.execCommand) try { document.execCommand("BackgroundImageCache", false, true); } catch (e) {} /**/ if (this.attachEvent && !this.addEventListener) { var unloadEvent = function () { this.detachEvent("onunload", unloadEvent); document.head = document.html = document.window = null; }; this.attachEvent("onunload", unloadEvent); } // IE fails on collections and ) var arrayFrom = Array.from; try { arrayFrom(document.html.childNodes); } catch (e) { Array.from = function (item) { if ( typeof item != "string" && Type.isEnumerable(item) && typeOf(item) != "array" ) { var i = item.length, array = new Array(i); while (i--) array[i] = item[i]; return array; } return arrayFrom(item); }; var prototype = Array.prototype, slice = prototype.slice; [ "pop", "push", "reverse", "shift", "sort", "splice", "unshift", "concat", "join", "slice", ].each(function (name) { var method = prototype[name]; Array[name] = function (item) { return method.apply(Array.from(item), slice.call(arguments, 1)); }; }); } /**/ //<1.2compat> if (Browser.Platform.ios) Browser.Platform.ipod = true; Browser.Engine = {}; var setEngine = function (name, version) { Browser.Engine.name = name; Browser.Engine[name + version] = true; Browser.Engine.version = version; }; if (Browser.ie) { Browser.Engine.trident = true; switch (Browser.version) { case 6: setEngine("trident", 4); break; case 7: setEngine("trident", 5); break; case 8: setEngine("trident", 6); } } if (Browser.firefox) { Browser.Engine.gecko = true; if (Browser.version >= 3) setEngine("gecko", 19); else setEngine("gecko", 18); } if (Browser.safari || Browser.chrome) { Browser.Engine.webkit = true; switch (Browser.version) { case 2: setEngine("webkit", 419); break; case 3: setEngine("webkit", 420); break; case 4: setEngine("webkit", 525); } } if (Browser.opera) { Browser.Engine.presto = true; if (Browser.version >= 9.6) setEngine("presto", 960); else if (Browser.version >= 9.5) setEngine("presto", 950); else setEngine("presto", 925); } if (Browser.name == "unknown") { switch ((ua.match(/(?:webkit|khtml|gecko)/) || [])[0]) { case "webkit": case "khtml": Browser.Engine.webkit = true; break; case "gecko": Browser.Engine.gecko = true; } } this.$exec = Browser.exec; // })(); /* --- name: Event description: Contains the Event Type, to make the event object cross-browser. license: MIT-style license. requires: [Window, Document, Array, Function, String, Object] provides: Event ... */ (function () { var _keys = {}; var DOMEvent = (this.DOMEvent = new Type("DOMEvent", function (event, win) { if (!win) win = window; event = event || win.event; if (event.$extended) return event; this.event = event; this.$extended = true; this.shift = event.shiftKey; this.control = event.ctrlKey; this.alt = event.altKey; this.meta = event.metaKey; var type = (this.type = event.type); var target = event.target || event.srcElement; while (target && target.nodeType == 3) target = target.parentNode; this.target = document.id(target); if (type.indexOf("key") == 0) { var code = (this.code = event.which || event.keyCode); this.key = _keys[code] /*<1.3compat>*/ || Object.keyOf(Event.Keys, code) /**/; if (type == "keydown") { if (code > 111 && code < 124) this.key = "f" + (code - 111); else if (code > 95 && code < 106) this.key = code - 96; } if (this.key == null) this.key = String.fromCharCode(code).toLowerCase(); } else if ( type == "click" || type == "dblclick" || type == "contextmenu" || type == "DOMMouseScroll" || type.indexOf("mouse") == 0 ) { var doc = win.document; doc = !doc.compatMode || doc.compatMode == "CSS1Compat" ? doc.html : doc.body; this.page = { x: event.pageX != null ? event.pageX : event.clientX + doc.scrollLeft, y: event.pageY != null ? event.pageY : event.clientY + doc.scrollTop, }; this.client = { x: event.pageX != null ? event.pageX - win.pageXOffset : event.clientX, y: event.pageY != null ? event.pageY - win.pageYOffset : event.clientY, }; if (type == "DOMMouseScroll" || type == "mousewheel") this.wheel = event.wheelDelta ? event.wheelDelta / 120 : -(event.detail || 0) / 3; this.rightClick = event.which == 3 || event.button == 2; if (type == "mouseover" || type == "mouseout") { var related = event.relatedTarget || event[(type == "mouseover" ? "from" : "to") + "Element"]; while (related && related.nodeType == 3) related = related.parentNode; this.relatedTarget = document.id(related); } } else if (type.indexOf("touch") == 0 || type.indexOf("gesture") == 0) { this.rotation = event.rotation; this.scale = event.scale; this.targetTouches = event.targetTouches; this.changedTouches = event.changedTouches; var touches = (this.touches = event.touches); if (touches && touches[0]) { var touch = touches[0]; this.page = { x: touch.pageX, y: touch.pageY }; this.client = { x: touch.clientX, y: touch.clientY }; } } if (!this.client) this.client = {}; if (!this.page) this.page = {}; })); DOMEvent.implement({ stop: function () { return this.preventDefault().stopPropagation(); }, stopPropagation: function () { if (this.event.stopPropagation) this.event.stopPropagation(); else this.event.cancelBubble = true; return this; }, preventDefault: function () { if (this.event.preventDefault) this.event.preventDefault(); else this.event.returnValue = false; return this; }, }); DOMEvent.defineKey = function (code, key) { _keys[code] = key; return this; }; DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true); DOMEvent.defineKeys({ 38: "up", 40: "down", 37: "left", 39: "right", 27: "esc", 32: "space", 8: "backspace", 9: "tab", 46: "delete", 13: "enter", }); })(); /*<1.3compat>*/ var Event = DOMEvent; Event.Keys = {}; /**/ /*<1.2compat>*/ Event.Keys = new Hash(Event.Keys); /**/ /* --- name: Class description: Contains the Class Function for easily creating, extending, and implementing reusable Classes. license: MIT-style license. requires: [Array, String, Function, Number] provides: Class ... */ (function () { var Class = (this.Class = new Type("Class", function (params) { if (instanceOf(params, Function)) params = { initialize: params }; var newClass = function () { reset(this); if (newClass.$prototyping) return this; this.$caller = null; var value = this.initialize ? this.initialize.apply(this, arguments) : this; this.$caller = this.caller = null; return value; } .extend(this) .implement(params); newClass.$constructor = Class; newClass.prototype.$constructor = newClass; newClass.prototype.parent = parent; return newClass; })); var parent = function () { if (!this.$caller) throw new Error('The method "parent" cannot be called.'); var name = this.$caller.$name, parent = this.$caller.$owner.parent, previous = parent ? parent.prototype[name] : null; if (!previous) throw new Error('The method "' + name + '" has no parent.'); return previous.apply(this, arguments); }; var reset = function (object) { for (var key in object) { var value = object[key]; switch (typeOf(value)) { case "object": var F = function () {}; F.prototype = value; object[key] = reset(new F()); break; case "array": object[key] = value.clone(); break; } } return object; }; var wrap = function (self, key, method) { if (method.$origin) method = method.$origin; var wrapper = function () { if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.'); var caller = this.caller, current = this.$caller; this.caller = current; this.$caller = wrapper; var result = method.apply(this, arguments); this.$caller = current; this.caller = caller; return result; }.extend({ $owner: self, $origin: method, $name: key }); return wrapper; }; var implement = function (key, value, retain) { if (Class.Mutators.hasOwnProperty(key)) { value = Class.Mutators[key].call(this, value); if (value == null) return this; } if (typeOf(value) == "function") { if (value.$hidden) return this; this.prototype[key] = retain ? value : wrap(this, key, value); } else { Object.merge(this.prototype, key, value); } return this; }; var getInstance = function (klass) { klass.$prototyping = true; var proto = new klass(); delete klass.$prototyping; return proto; }; Class.implement("implement", implement.overloadSetter()); Class.Mutators = { Extends: function (parent) { this.parent = parent; this.prototype = getInstance(parent); }, Implements: function (items) { Array.from(items).each(function (item) { var instance = new item(); for (var key in instance) implement.call(this, key, instance[key], true); }, this); }, }; })(); /* --- name: Class.Extras description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks. license: MIT-style license. requires: Class provides: [Class.Extras, Chain, Events, Options] ... */ (function () { this.Chain = new Class({ $chain: [], chain: function () { this.$chain.append(Array.flatten(arguments)); return this; }, callChain: function () { return this.$chain.length ? this.$chain.shift().apply(this, arguments) : false; }, clearChain: function () { this.$chain.empty(); return this; }, }); var removeOn = function (string) { return string.replace(/^on([A-Z])/, function (full, first) { return first.toLowerCase(); }); }; this.Events = new Class({ $events: {}, addEvent: function (type, fn, internal) { type = removeOn(type); /*<1.2compat>*/ if (fn == $empty) return this; /**/ this.$events[type] = (this.$events[type] || []).include(fn); if (internal) fn.internal = true; return this; }, addEvents: function (events) { for (var type in events) this.addEvent(type, events[type]); return this; }, fireEvent: function (type, args, delay) { type = removeOn(type); var events = this.$events[type]; if (!events) return this; args = Array.from(args); events.each(function (fn) { if (delay) fn.delay(delay, this, args); else fn.apply(this, args); }, this); return this; }, removeEvent: function (type, fn) { type = removeOn(type); var events = this.$events[type]; if (events && !fn.internal) { var index = events.indexOf(fn); if (index != -1) delete events[index]; } return this; }, removeEvents: function (events) { var type; if (typeOf(events) == "object") { for (type in events) this.removeEvent(type, events[type]); return this; } if (events) events = removeOn(events); for (type in this.$events) { if (events && events != type) continue; var fns = this.$events[type]; for (var i = fns.length; i--; ) if (i in fns) { this.removeEvent(type, fns[i]); } } return this; }, }); this.Options = new Class({ setOptions: function () { var options = (this.options = Object.merge.apply( null, [{}, this.options].append(arguments), )); if (this.addEvent) for (var option in options) { if (typeOf(options[option]) != "function" || !/^on[A-Z]/.test(option)) continue; this.addEvent(option, options[option]); delete options[option]; } return this; }, }); })(); /* --- name: Slick.Parser description: Standalone CSS3 Selector parser provides: Slick.Parser ... */ (function () { var parsed, separatorIndex, combinatorIndex, reversed, cache = {}, reverseCache = {}, reUnescape = /\\/g; var parse = function (expression, isReversed) { if (expression == null) return null; if (expression.Slick === true) return expression; expression = ("" + expression).replace(/^\s+|\s+$/g, ""); reversed = !!isReversed; var currentCache = reversed ? reverseCache : cache; if (currentCache[expression]) return currentCache[expression]; parsed = { Slick: true, expressions: [], raw: expression, reverse: function () { return parse(this.raw, true); }, }; separatorIndex = -1; while (expression != (expression = expression.replace(regexp, parser))); parsed.length = parsed.expressions.length; return (currentCache[parsed.raw] = reversed ? reverse(parsed) : parsed); }; var reverseCombinator = function (combinator) { if (combinator === "!") return " "; else if (combinator === " ") return "!"; else if (/^!/.test(combinator)) return combinator.replace(/^!/, ""); else return "!" + combinator; }; var reverse = function (expression) { var expressions = expression.expressions; for (var i = 0; i < expressions.length; i++) { var exp = expressions[i]; var last = { parts: [], tag: "*", combinator: reverseCombinator(exp[0].combinator), }; for (var j = 0; j < exp.length; j++) { var cexp = exp[j]; if (!cexp.reverseCombinator) cexp.reverseCombinator = " "; cexp.combinator = cexp.reverseCombinator; delete cexp.reverseCombinator; } exp.reverse().push(last); } return expression; }; var escapeRegExp = function (string) { // Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan MIT License return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function (match) { return "\\" + match; }); }; var regexp = new RegExp( /* #!/usr/bin/env ruby puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'') __END__ "(?x)^(?:\ \\s* ( , ) \\s* # Separator \n\ | \\s* ( + ) \\s* # Combinator \n\ | ( \\s+ ) # CombinatorChildren \n\ | ( + | \\* ) # Tag \n\ | \\# ( + ) # ID \n\ | \\. ( + ) # ClassName \n\ | # Attribute \n\ \\[ \ \\s* (+) (?: \ \\s* ([*^$!~|]?=) (?: \ \\s* (?:\ ([\"']?)(.*?)\\9 \ )\ ) \ )? \\s* \ \\](?!\\]) \n\ | :+ ( + )(?:\ \\( (?:\ (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\ ) \\)\ )?\ )" */ "^(?:\\s*(,)\\s*|\\s*(+)\\s*|(\\s+)|(+|\\*)|\\#(+)|\\.(+)|\\[\\s*(+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)" .replace(//, "[" + escapeRegExp(">+~`!@$%^&={}\\;/g, "(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])") .replace(//g, "(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])"), ); function parser( rawMatch, separator, combinator, combinatorChildren, tagName, id, className, attributeKey, attributeOperator, attributeQuote, attributeValue, pseudoMarker, pseudoClass, pseudoQuote, pseudoClassQuotedValue, pseudoClassValue, ) { if (separator || separatorIndex === -1) { parsed.expressions[++separatorIndex] = []; combinatorIndex = -1; if (separator) return ""; } if (combinator || combinatorChildren || combinatorIndex === -1) { combinator = combinator || " "; var currentSeparator = parsed.expressions[separatorIndex]; if (reversed && currentSeparator[combinatorIndex]) currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator); currentSeparator[++combinatorIndex] = { combinator: combinator, tag: "*", }; } var currentParsed = parsed.expressions[separatorIndex][combinatorIndex]; if (tagName) { currentParsed.tag = tagName.replace(reUnescape, ""); } else if (id) { currentParsed.id = id.replace(reUnescape, ""); } else if (className) { className = className.replace(reUnescape, ""); if (!currentParsed.classList) currentParsed.classList = []; if (!currentParsed.classes) currentParsed.classes = []; currentParsed.classList.push(className); currentParsed.classes.push({ value: className, regexp: new RegExp("(^|\\s)" + escapeRegExp(className) + "(\\s|$)"), }); } else if (pseudoClass) { pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue; pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, "") : null; if (!currentParsed.pseudos) currentParsed.pseudos = []; currentParsed.pseudos.push({ key: pseudoClass.replace(reUnescape, ""), value: pseudoClassValue, type: pseudoMarker.length == 1 ? "class" : "element", }); } else if (attributeKey) { attributeKey = attributeKey.replace(reUnescape, ""); attributeValue = (attributeValue || "").replace(reUnescape, ""); var test, regexp; switch (attributeOperator) { case "^=": regexp = new RegExp("^" + escapeRegExp(attributeValue)); break; case "$=": regexp = new RegExp(escapeRegExp(attributeValue) + "$"); break; case "~=": regexp = new RegExp( "(^|\\s)" + escapeRegExp(attributeValue) + "(\\s|$)", ); break; case "|=": regexp = new RegExp("^" + escapeRegExp(attributeValue) + "(-|$)"); break; case "=": test = function (value) { return attributeValue == value; }; break; case "*=": test = function (value) { return value && value.indexOf(attributeValue) > -1; }; break; case "!=": test = function (value) { return attributeValue != value; }; break; default: test = function (value) { return !!value; }; } if (attributeValue == "" && /^[*$^]=$/.test(attributeOperator)) test = function () { return false; }; if (!test) test = function (value) { return value && regexp.test(value); }; if (!currentParsed.attributes) currentParsed.attributes = []; currentParsed.attributes.push({ key: attributeKey, operator: attributeOperator, value: attributeValue, test: test, }); } return ""; } // Slick NS var Slick = this.Slick || {}; Slick.parse = function (expression) { return parse(expression); }; Slick.escapeRegExp = escapeRegExp; if (!this.Slick) this.Slick = Slick; }.apply( /**/ typeof exports != "undefined" ? exports : /**/ this, )); /* --- name: Slick.Finder description: The new, superfast css selector engine. provides: Slick.Finder requires: Slick.Parser ... */ (function () { var local = {}, featuresCache = {}, toString = Object.prototype.toString; // Feature / Bug detection local.isNativeCode = function (fn) { return /\{\s*\[native code\]\s*\}/.test("" + fn); }; local.isXML = function (document) { return ( !!document.xmlVersion || !!document.xml || toString.call(document) == "[object XMLDocument]" || (document.nodeType == 9 && document.documentElement.nodeName != "HTML") ); }; local.setDocument = function (document) { // convert elements / window arguments to document. if document cannot be extrapolated, the function returns. var nodeType = document.nodeType; if (nodeType == 9); else if (nodeType) // document document = document.ownerDocument; // node else if (document.navigator) document = document.document; // window else return; // check if it's the old document if (this.document === document) return; this.document = document; // check if we have done feature detection on this document before var root = document.documentElement, rootUid = this.getUIDXML(root), features = featuresCache[rootUid], feature; if (features) { for (feature in features) { this[feature] = features[feature]; } return; } features = featuresCache[rootUid] = {}; features.root = root; features.isXMLDocument = this.isXML(document); features.brokenStarGEBTN = features.starSelectsClosedQSA = features.idGetsName = features.brokenMixedCaseQSA = features.brokenGEBCN = features.brokenCheckedQSA = features.brokenEmptyAttributeQSA = features.isHTMLDocument = features.nativeMatchesSelector = false; var starSelectsClosed, starSelectsComments, brokenSecondClassNameGEBCN, cachedGetElementsByClassName, brokenFormAttributeGetter; var selected, id = "slick_uniqueid"; var testNode = document.createElement("div"); var testRoot = document.body || document.getElementsByTagName("body")[0] || root; testRoot.appendChild(testNode); // on non-HTML documents innerHTML and getElementsById doesnt work properly try { testNode.innerHTML = ''; features.isHTMLDocument = !!document.getElementById(id); } catch (e) {} if (features.isHTMLDocument) { testNode.style.display = "none"; // IE returns comment nodes for getElementsByTagName('*') for some documents testNode.appendChild(document.createComment("")); starSelectsComments = testNode.getElementsByTagName("*").length > 1; // IE returns closed nodes (EG:"") for getElementsByTagName('*') for some documents try { testNode.innerHTML = "foo"; selected = testNode.getElementsByTagName("*"); starSelectsClosed = selected && !!selected.length && selected[0].nodeName.charAt(0) == "/"; } catch (e) {} features.brokenStarGEBTN = starSelectsComments || starSelectsClosed; // IE returns elements with the name instead of just id for getElementsById for some documents try { testNode.innerHTML = ''; features.idGetsName = document.getElementById(id) === testNode.firstChild; } catch (e) {} if (testNode.getElementsByClassName) { // Safari 3.2 getElementsByClassName caches results try { testNode.innerHTML = ''; testNode.getElementsByClassName("b").length; testNode.firstChild.className = "b"; cachedGetElementsByClassName = testNode.getElementsByClassName("b").length != 2; } catch (e) {} // Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one try { testNode.innerHTML = ''; brokenSecondClassNameGEBCN = testNode.getElementsByClassName("a").length != 2; } catch (e) {} features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN; } if (testNode.querySelectorAll) { // IE 8 returns closed nodes (EG:"") for querySelectorAll('*') for some documents try { testNode.innerHTML = "foo"; selected = testNode.querySelectorAll("*"); features.starSelectsClosedQSA = selected && !!selected.length && selected[0].nodeName.charAt(0) == "/"; } catch (e) {} // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode try { testNode.innerHTML = ''; features.brokenMixedCaseQSA = !testNode.querySelectorAll(".MiX").length; } catch (e) {} // Webkit and Opera dont return selected options on querySelectorAll try { testNode.innerHTML = ''; features.brokenCheckedQSA = testNode.querySelectorAll(":checked").length == 0; } catch (e) {} // IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll try { testNode.innerHTML = ''; features.brokenEmptyAttributeQSA = testNode.querySelectorAll('[class*=""]').length != 0; } catch (e) {} } // IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input try { testNode.innerHTML = '
'; brokenFormAttributeGetter = testNode.firstChild.getAttribute("action") != "s"; } catch (e) {} // native matchesSelector function features.nativeMatchesSelector = root.matchesSelector || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector; if (features.nativeMatchesSelector) try { // if matchesSelector trows errors on incorrect sintaxes we can use it features.nativeMatchesSelector.call(root, ":slick"); features.nativeMatchesSelector = null; } catch (e) {} } try { root.slick_expando = 1; delete root.slick_expando; features.getUID = this.getUIDHTML; } catch (e) { features.getUID = this.getUIDXML; } testRoot.removeChild(testNode); testNode = selected = testRoot = null; // getAttribute features.getAttribute = features.isHTMLDocument && brokenFormAttributeGetter ? function (node, name) { var method = this.attributeGetters[name]; if (method) return method.call(node); var attributeNode = node.getAttributeNode(name); return attributeNode ? attributeNode.nodeValue : null; } : function (node, name) { var method = this.attributeGetters[name]; return method ? method.call(node) : node.getAttribute(name); }; // hasAttribute features.hasAttribute = root && this.isNativeCode(root.hasAttribute) ? function (node, attribute) { return node.hasAttribute(attribute); } : function (node, attribute) { node = node.getAttributeNode(attribute); return !!(node && (node.specified || node.nodeValue)); }; // contains // FIXME: Add specs: local.contains should be different for xml and html documents? var nativeRootContains = root && this.isNativeCode(root.contains), nativeDocumentContains = document && this.isNativeCode(document.contains); features.contains = nativeRootContains && nativeDocumentContains ? function (context, node) { return context.contains(node); } : nativeRootContains && !nativeDocumentContains ? function (context, node) { // IE8 does not have .contains on document. return ( context === node || (context === document ? document.documentElement : context ).contains(node) ); } : root && root.compareDocumentPosition ? function (context, node) { return ( context === node || !!(context.compareDocumentPosition(node) & 16) ); } : function (context, node) { if (node) do { if (node === context) return true; } while ((node = node.parentNode)); return false; }; // document order sorting // credits to Sizzle (http://sizzlejs.com/) features.documentSorter = root.compareDocumentPosition ? function (a, b) { if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0; return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; } : "sourceIndex" in root ? function (a, b) { if (!a.sourceIndex || !b.sourceIndex) return 0; return a.sourceIndex - b.sourceIndex; } : document.createRange ? function (a, b) { if (!a.ownerDocument || !b.ownerDocument) return 0; var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); aRange.setStart(a, 0); aRange.setEnd(a, 0); bRange.setStart(b, 0); bRange.setEnd(b, 0); return aRange.compareBoundaryPoints(Range.START_TO_END, bRange); } : null; root = null; for (feature in features) { this[feature] = features[feature]; } }; // Main Method var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/, reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/, qsaFailExpCache = {}; local.search = function (context, expression, append, first) { var found = (this.found = first ? null : append || []); if (!context) return found; else if (context.navigator) context = context.document; // Convert the node from a window to a document else if (!context.nodeType) return found; // setup var parsed, i, uniques = (this.uniques = {}), hasOthers = !!(append && append.length), contextIsDocument = context.nodeType == 9; if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context); // avoid duplicating items already in the append array if (hasOthers) for (i = found.length; i--; ) uniques[this.getUID(found[i])] = true; // expression checks if (typeof expression == "string") { // expression is a string /**/ var simpleSelector = expression.match(reSimpleSelector); simpleSelectors: if (simpleSelector) { var symbol = simpleSelector[1], name = simpleSelector[2], node, nodes; if (!symbol) { if (name == "*" && this.brokenStarGEBTN) break simpleSelectors; nodes = context.getElementsByTagName(name); if (first) return nodes[0] || null; for (i = 0; (node = nodes[i++]); ) { if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); } } else if (symbol == "#") { if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors; node = context.getElementById(name); if (!node) return found; if (this.idGetsName && node.getAttributeNode("id").nodeValue != name) break simpleSelectors; if (first) return node || null; if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); } else if (symbol == ".") { if ( !this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll) ) break simpleSelectors; if (context.getElementsByClassName && !this.brokenGEBCN) { nodes = context.getElementsByClassName(name); if (first) return nodes[0] || null; for (i = 0; (node = nodes[i++]); ) { if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); } } else { var matchClass = new RegExp( "(^|\\s)" + Slick.escapeRegExp(name) + "(\\s|$)", ); nodes = context.getElementsByTagName("*"); for (i = 0; (node = nodes[i++]); ) { className = node.className; if (!(className && matchClass.test(className))) continue; if (first) return node; if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); } } } if (hasOthers) this.sort(found); return first ? null : found; } /**/ /**/ querySelector: if (context.querySelectorAll) { if ( !this.isHTMLDocument || qsaFailExpCache[expression] || //TODO: only skip when expression is actually mixed case this.brokenMixedCaseQSA || (this.brokenCheckedQSA && expression.indexOf(":checked") > -1) || (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression)) || (!contextIsDocument && //Abort when !contextIsDocument and... // there are multiple expressions in the selector // since we currently only fix non-document rooted QSA for single expression selectors expression.indexOf(",") > -1) || Slick.disableQSA ) break querySelector; var _expression = expression, _context = context; if (!contextIsDocument) { // non-document rooted QSA // credits to Andrew Dupont var currentId = _context.getAttribute("id"), slickid = "slickid__"; _context.setAttribute("id", slickid); _expression = "#" + slickid + " " + _expression; context = _context.parentNode; } try { if (first) return context.querySelector(_expression) || null; else nodes = context.querySelectorAll(_expression); } catch (e) { qsaFailExpCache[expression] = 1; break querySelector; } finally { if (!contextIsDocument) { if (currentId) _context.setAttribute("id", currentId); else _context.removeAttribute("id"); context = _context; } } if (this.starSelectsClosedQSA) for (i = 0; (node = nodes[i++]); ) { if ( node.nodeName > "@" && !(hasOthers && uniques[this.getUID(node)]) ) found.push(node); } else for (i = 0; (node = nodes[i++]); ) { if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); } if (hasOthers) this.sort(found); return found; } /**/ parsed = this.Slick.parse(expression); if (!parsed.length) return found; } else if (expression == null) { // there is no expression return found; } else if (expression.Slick) { // expression is a parsed Slick object parsed = expression; } else if (this.contains(context.documentElement || context, expression)) { // expression is a node found ? found.push(expression) : (found = expression); return found; } else { // other junk return found; } /**/ /**/ // cache elements for the nth selectors this.posNTH = {}; this.posNTHLast = {}; this.posNTHType = {}; this.posNTHTypeLast = {}; /**/ /**/ // if append is null and there is only a single selector with one expression use pushArray, else use pushUID this.push = !hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1)) ? this.pushArray : this.pushUID; if (found == null) found = []; // default engine var j, m, n; var combinator, tag, id, classList, classes, attributes, pseudos; var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions; search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++) { combinator = "combinator:" + currentBit.combinator; if (!this[combinator]) continue search; tag = this.isXMLDocument ? currentBit.tag : currentBit.tag.toUpperCase(); id = currentBit.id; classList = currentBit.classList; classes = currentBit.classes; attributes = currentBit.attributes; pseudos = currentBit.pseudos; lastBit = j === currentExpression.length - 1; this.bitUniques = {}; if (lastBit) { this.uniques = uniques; this.found = found; } else { this.uniques = {}; this.found = []; } if (j === 0) { this[combinator]( context, tag, id, classes, attributes, pseudos, classList, ); if (first && lastBit && found.length) break search; } else { if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++) { this[combinator]( currentItems[m], tag, id, classes, attributes, pseudos, classList, ); if (found.length) break search; } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator]( currentItems[m], tag, id, classes, attributes, pseudos, classList, ); } currentItems = this.found; } // should sort if there are nodes in append and if you pass multiple expressions. if (hasOthers || parsed.expressions.length > 1) this.sort(found); return first ? found[0] || null : found; }; // Utils local.uidx = 1; local.uidk = "slick-uniqueid"; local.getUIDXML = function (node) { var uid = node.getAttribute(this.uidk); if (!uid) { uid = this.uidx++; node.setAttribute(this.uidk, uid); } return uid; }; local.getUIDHTML = function (node) { return node.uniqueNumber || (node.uniqueNumber = this.uidx++); }; // sort based on the setDocument documentSorter method. local.sort = function (results) { if (!this.documentSorter) return results; results.sort(this.documentSorter); return results; }; /**/ /**/ local.cacheNTH = {}; local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/; local.parseNTHArgument = function (argument) { var parsed = argument.match(this.matchNTH); if (!parsed) return false; var special = parsed[2] || false; var a = parsed[1] || 1; if (a == "-") a = -1; var b = +parsed[3] || 0; parsed = special == "n" ? { a: a, b: b } : special == "odd" ? { a: 2, b: 1 } : special == "even" ? { a: 2, b: 0 } : { a: 0, b: a }; return (this.cacheNTH[argument] = parsed); }; local.createNTHPseudo = function (child, sibling, positions, ofType) { return function (node, argument) { var uid = this.getUID(node); if (!this[positions][uid]) { var parent = node.parentNode; if (!parent) return false; var el = parent[child], count = 1; if (ofType) { var nodeName = node.nodeName; do { if (el.nodeName != nodeName) continue; this[positions][this.getUID(el)] = count++; } while ((el = el[sibling])); } else { do { if (el.nodeType != 1) continue; this[positions][this.getUID(el)] = count++; } while ((el = el[sibling])); } } argument = argument || "n"; var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument); if (!parsed) return false; var a = parsed.a, b = parsed.b, pos = this[positions][uid]; if (a == 0) return b == pos; if (a > 0) { if (pos < b) return false; } else { if (b < pos) return false; } return (pos - b) % a == 0; }; }; /**/ /**/ local.pushArray = function (node, tag, id, classes, attributes, pseudos) { if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node); }; local.pushUID = function (node, tag, id, classes, attributes, pseudos) { var uid = this.getUID(node); if ( !this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos) ) { this.uniques[uid] = true; this.found.push(node); } }; local.matchNode = function (node, selector) { if (this.isHTMLDocument && this.nativeMatchesSelector) { try { return this.nativeMatchesSelector.call( node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'), ); } catch (matchError) {} } var parsed = this.Slick.parse(selector); if (!parsed) return true; // simple (single) selectors var expressions = parsed.expressions, simpleExpCounter = 0, i; for (i = 0; (currentExpression = expressions[i]); i++) { if (currentExpression.length == 1) { var exp = currentExpression[0]; if ( this.matchSelector( node, this.isXMLDocument ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos, ) ) return true; simpleExpCounter++; } } if (simpleExpCounter == parsed.length) return false; var nodes = this.search(this.document, parsed), item; for (i = 0; (item = nodes[i++]); ) { if (item === node) return true; } return false; }; local.matchPseudo = function (node, name, argument) { var pseudoName = "pseudo:" + name; if (this[pseudoName]) return this[pseudoName](node, argument); var attribute = this.getAttribute(node, name); return argument ? argument == attribute : !!attribute; }; local.matchSelector = function (node, tag, id, classes, attributes, pseudos) { if (tag) { var nodeName = this.isXMLDocument ? node.nodeName : node.nodeName.toUpperCase(); if (tag == "*") { if (nodeName < "@") return false; // Fix for comment nodes and closed nodes } else { if (nodeName != tag) return false; } } if (id && node.getAttribute("id") != id) return false; var i, part, cls; if (classes) for (i = classes.length; i--; ) { cls = this.getAttribute(node, "class"); if (!(cls && classes[i].regexp.test(cls))) return false; } if (attributes) for (i = attributes.length; i--; ) { part = attributes[i]; if ( part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key) ) return false; } if (pseudos) for (i = pseudos.length; i--; ) { part = pseudos[i]; if (!this.matchPseudo(node, part.key, part.value)) return false; } return true; }; var combinators = { " ": function (node, tag, id, classes, attributes, pseudos, classList) { // all child nodes, any level var i, item, children; if (this.isHTMLDocument) { getById: if (id) { item = this.document.getElementById(id); if ( (!item && node.all) || (this.idGetsName && item && item.getAttributeNode("id").nodeValue != id) ) { // all[id] returns all the elements with that name or id inside node // if theres just one it will return the element, else it will be a collection children = node.all[id]; if (!children) return; if (!children[0]) children = [children]; for (i = 0; (item = children[i++]); ) { var idNode = item.getAttributeNode("id"); if (idNode && idNode.nodeValue == id) { this.push(item, tag, null, classes, attributes, pseudos); break; } } return; } if (!item) { // if the context is in the dom we return, else we will try GEBTN, breaking the getById label if (this.contains(this.root, node)) return; else break getById; } else if (this.document !== node && !this.contains(node, item)) return; this.push(item, tag, null, classes, attributes, pseudos); return; } getByClass: if ( classes && node.getElementsByClassName && !this.brokenGEBCN ) { children = node.getElementsByClassName(classList.join(" ")); if (!(children && children.length)) break getByClass; for (i = 0; (item = children[i++]); ) this.push(item, tag, id, null, attributes, pseudos); return; } } getByTag: { children = node.getElementsByTagName(tag); if (!(children && children.length)) break getByTag; if (!this.brokenStarGEBTN) tag = null; for (i = 0; (item = children[i++]); ) this.push(item, tag, id, classes, attributes, pseudos); } }, ">": function (node, tag, id, classes, attributes, pseudos) { // direct children if ((node = node.firstChild)) do { if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); } while ((node = node.nextSibling)); }, "+": function (node, tag, id, classes, attributes, pseudos) { // next sibling while ((node = node.nextSibling)) if (node.nodeType == 1) { this.push(node, tag, id, classes, attributes, pseudos); break; } }, "^": function (node, tag, id, classes, attributes, pseudos) { // first child node = node.firstChild; if (node) { if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); else this["combinator:+"](node, tag, id, classes, attributes, pseudos); } }, "~": function (node, tag, id, classes, attributes, pseudos) { // next siblings while ((node = node.nextSibling)) { if (node.nodeType != 1) continue; var uid = this.getUID(node); if (this.bitUniques[uid]) break; this.bitUniques[uid] = true; this.push(node, tag, id, classes, attributes, pseudos); } }, "++": function (node, tag, id, classes, attributes, pseudos) { // next sibling and previous sibling this["combinator:+"](node, tag, id, classes, attributes, pseudos); this["combinator:!+"](node, tag, id, classes, attributes, pseudos); }, "~~": function (node, tag, id, classes, attributes, pseudos) { // next siblings and previous siblings this["combinator:~"](node, tag, id, classes, attributes, pseudos); this["combinator:!~"](node, tag, id, classes, attributes, pseudos); }, "!": function (node, tag, id, classes, attributes, pseudos) { // all parent nodes up to document while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos); }, "!>": function (node, tag, id, classes, attributes, pseudos) { // direct parent (one level) node = node.parentNode; if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos); }, "!+": function (node, tag, id, classes, attributes, pseudos) { // previous sibling while ((node = node.previousSibling)) if (node.nodeType == 1) { this.push(node, tag, id, classes, attributes, pseudos); break; } }, "!^": function (node, tag, id, classes, attributes, pseudos) { // last child node = node.lastChild; if (node) { if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); else this["combinator:!+"](node, tag, id, classes, attributes, pseudos); } }, "!~": function (node, tag, id, classes, attributes, pseudos) { // previous siblings while ((node = node.previousSibling)) { if (node.nodeType != 1) continue; var uid = this.getUID(node); if (this.bitUniques[uid]) break; this.bitUniques[uid] = true; this.push(node, tag, id, classes, attributes, pseudos); } }, }; for (var c in combinators) local["combinator:" + c] = combinators[c]; var pseudos = { /**/ empty: function (node) { var child = node.firstChild; return ( !(child && child.nodeType == 1) && !(node.innerText || node.textContent || "").length ); }, not: function (node, expression) { return !this.matchNode(node, expression); }, contains: function (node, text) { return (node.innerText || node.textContent || "").indexOf(text) > -1; }, "first-child": function (node) { while ((node = node.previousSibling)) if (node.nodeType == 1) return false; return true; }, "last-child": function (node) { while ((node = node.nextSibling)) if (node.nodeType == 1) return false; return true; }, "only-child": function (node) { var prev = node; while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false; var next = node; while ((next = next.nextSibling)) if (next.nodeType == 1) return false; return true; }, /**/ "nth-child": local.createNTHPseudo("firstChild", "nextSibling", "posNTH"), "nth-last-child": local.createNTHPseudo( "lastChild", "previousSibling", "posNTHLast", ), "nth-of-type": local.createNTHPseudo( "firstChild", "nextSibling", "posNTHType", true, ), "nth-last-of-type": local.createNTHPseudo( "lastChild", "previousSibling", "posNTHTypeLast", true, ), index: function (node, index) { return this["pseudo:nth-child"](node, "" + (index + 1)); }, even: function (node) { return this["pseudo:nth-child"](node, "2n"); }, odd: function (node) { return this["pseudo:nth-child"](node, "2n+1"); }, /**/ /**/ "first-of-type": function (node) { var nodeName = node.nodeName; while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false; return true; }, "last-of-type": function (node) { var nodeName = node.nodeName; while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false; return true; }, "only-of-type": function (node) { var prev = node, nodeName = node.nodeName; while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false; var next = node; while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false; return true; }, /**/ // custom pseudos enabled: function (node) { return !node.disabled; }, disabled: function (node) { return node.disabled; }, checked: function (node) { return node.checked || node.selected; }, focus: function (node) { return ( this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, "tabindex")) ); }, root: function (node) { return node === this.root; }, selected: function (node) { return node.selected; }, /**/ }; for (var p in pseudos) local["pseudo:" + p] = pseudos[p]; // attributes methods var attributeGetters = (local.attributeGetters = { for: function () { return "htmlFor" in this ? this.htmlFor : this.getAttribute("for"); }, href: function () { return "href" in this ? this.getAttribute("href", 2) : this.getAttribute("href"); }, style: function () { return this.style ? this.style.cssText : this.getAttribute("style"); }, tabindex: function () { var attributeNode = this.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? attributeNode.nodeValue : null; }, type: function () { return this.getAttribute("type"); }, maxlength: function () { var attributeNode = this.getAttributeNode("maxLength"); return attributeNode && attributeNode.specified ? attributeNode.nodeValue : null; }, }); attributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxlength; // Slick var Slick = (local.Slick = this.Slick || {}); Slick.version = "1.1.7"; // Slick finder Slick.search = function (context, expression, append) { return local.search(context, expression, append); }; Slick.find = function (context, expression) { return local.search(context, expression, null, true); }; // Slick containment checker Slick.contains = function (container, node) { local.setDocument(container); return local.contains(container, node); }; // Slick attribute getter Slick.getAttribute = function (node, name) { local.setDocument(node); return local.getAttribute(node, name); }; Slick.hasAttribute = function (node, name) { local.setDocument(node); return local.hasAttribute(node, name); }; // Slick matcher Slick.match = function (node, selector) { if (!(node && selector)) return false; if (!selector || selector === node) return true; local.setDocument(node); return local.matchNode(node, selector); }; // Slick attribute accessor Slick.defineAttributeGetter = function (name, fn) { local.attributeGetters[name] = fn; return this; }; Slick.lookupAttributeGetter = function (name) { return local.attributeGetters[name]; }; // Slick pseudo accessor Slick.definePseudo = function (name, fn) { local["pseudo:" + name] = function (node, argument) { return fn.call(node, argument); }; return this; }; Slick.lookupPseudo = function (name) { var pseudo = local["pseudo:" + name]; if (pseudo) return function (argument) { return pseudo.call(this, argument); }; return null; }; // Slick overrides accessor Slick.override = function (regexp, fn) { local.override(regexp, fn); return this; }; Slick.isXML = local.isXML; Slick.uidOf = function (node) { return local.getUIDHTML(node); }; if (!this.Slick) this.Slick = Slick; }.apply( /**/ typeof exports != "undefined" ? exports : /**/ this, )); /* --- name: Element description: 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. license: MIT-style license. requires: [Window, Document, Array, String, Function, Object, Number, Slick.Parser, Slick.Finder] provides: [Element, Elements, $, $$, Iframe, Selectors] ... */ var Element = function (tag, props) { var konstructor = Element.Constructors[tag]; if (konstructor) return konstructor(props); if (typeof tag != "string") return document.id(tag).set(props); if (!props) props = {}; if (!/^[\w-]+$/.test(tag)) { var parsed = Slick.parse(tag).expressions[0][0]; tag = parsed.tag == "*" ? "div" : parsed.tag; if (parsed.id && props.id == null) props.id = parsed.id; var attributes = parsed.attributes; if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++) { attr = attributes[i]; if (props[attr.key] != null) continue; if (attr.value != null && attr.operator == "=") props[attr.key] = attr.value; else if (!attr.value && !attr.operator) props[attr.key] = true; } if (parsed.classList && props["class"] == null) props["class"] = parsed.classList.join(" "); } return document.newElement(tag, props); }; if (Browser.Element) { Element.prototype = Browser.Element.prototype; // IE8 and IE9 require the wrapping. Element.prototype._fireEvent = (function (fireEvent) { return function (type, event) { return fireEvent.call(this, type, event); }; })(Element.prototype.fireEvent); } new Type("Element", Element).mirror(function (name) { if (Array.prototype[name]) return; var obj = {}; obj[name] = function () { var results = [], args = arguments, elements = true; for (var i = 0, l = this.length; i < l; i++) { var element = this[i], result = (results[i] = element[name].apply(element, args)); elements = elements && typeOf(result) == "element"; } return elements ? new Elements(results) : results; }; Elements.implement(obj); }); if (!Browser.Element) { Element.parent = Object; Element.Prototype = { $constructor: Element, $family: Function.from("element").hide(), }; Element.mirror(function (name, method) { Element.Prototype[name] = method; }); } Element.Constructors = {}; //<1.2compat> Element.Constructors = new Hash(); // var IFrame = new Type("IFrame", function () { var params = Array.link(arguments, { properties: Type.isObject, iframe: function (obj) { return obj != null; }, }); var props = params.properties || {}, iframe; if (params.iframe) iframe = document.id(params.iframe); var onload = props.onload || function () {}; delete props.onload; props.id = props.name = [ props.id, props.name, iframe ? iframe.id || iframe.name : "IFrame_" + String.uniqueID(), ].pick(); iframe = new Element(iframe || "iframe", props); var onLoad = function () { onload.call(iframe.contentWindow); }; if (window.frames[props.id]) onLoad(); else iframe.addListener("load", onLoad); return iframe; }); var Elements = (this.Elements = function (nodes) { if (nodes && nodes.length) { var uniques = {}, node; for (var i = 0; (node = nodes[i++]); ) { var uid = Slick.uidOf(node); if (!uniques[uid]) { uniques[uid] = true; this.push(node); } } } }); Elements.prototype = { length: 0 }; Elements.parent = Array; new Type("Elements", Elements).implement({ filter: function (filter, bind) { if (!filter) return this; return new Elements( Array.filter( this, typeOf(filter) == "string" ? function (item) { return item.match(filter); } : filter, bind, ), ); }.protect(), push: function () { var length = this.length; for (var i = 0, l = arguments.length; i < l; i++) { var item = document.id(arguments[i]); if (item) this[length++] = item; } return (this.length = length); }.protect(), unshift: function () { var items = []; for (var i = 0, l = arguments.length; i < l; i++) { var item = document.id(arguments[i]); if (item) items.push(item); } return Array.prototype.unshift.apply(this, items); }.protect(), concat: function () { var newElements = new Elements(this); for (var i = 0, l = arguments.length; i < l; i++) { var item = arguments[i]; if (Type.isEnumerable(item)) newElements.append(item); else newElements.push(item); } return newElements; }.protect(), append: function (collection) { for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]); return this; }.protect(), empty: function () { while (this.length) delete this[--this.length]; return this; }.protect(), }); //<1.2compat> Elements.alias("extend", "append"); // (function () { // FF, IE var splice = Array.prototype.splice, object = { 0: 0, 1: 1, length: 2 }; splice.call(object, 1, 1); if (object[1] == 1) Elements.implement( "splice", function () { var length = this.length; var result = splice.apply(this, arguments); while (length >= this.length) delete this[length--]; return result; }.protect(), ); Array.forEachMethod(function (method, name) { Elements.implement(name, method); }); Array.mirror(Elements); /**/ var createElementAcceptsHTML; try { createElementAcceptsHTML = document.createElement("").name == "x"; } catch (e) {} var escapeQuotes = function (html) { return ("" + html).replace(/&/g, "&").replace(/"/g, """); }; /**/ Document.implement({ newElement: function (tag, props) { if (props && props.checked != null) props.defaultChecked = props.checked; /**/ // Fix for readonly name and type properties in IE < 8 if (createElementAcceptsHTML && props) { tag = "<" + tag; if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"'; if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"'; tag += ">"; delete props.name; delete props.type; } /**/ return this.id(this.createElement(tag)).set(props); }, }); })(); (function () { Slick.uidOf(window); Slick.uidOf(document); Document.implement({ newTextNode: function (text) { return this.createTextNode(text); }, getDocument: function () { return this; }, getWindow: function () { return this.window; }, id: (function () { var types = { string: function (id, nocash, doc) { id = Slick.find(doc, "#" + id.replace(/(\W)/g, "\\$1")); return id ? types.element(id, nocash) : null; }, element: function (el, nocash) { Slick.uidOf(el); if ( !nocash && !el.$family && !/^(?:object|embed)$/i.test(el.tagName) ) { var fireEvent = el.fireEvent; // wrapping needed in IE7, or else crash el._fireEvent = function (type, event) { return fireEvent(type, event); }; Object.append(el, Element.Prototype); } return el; }, object: function (obj, nocash, doc) { if (obj.toElement) return types.element(obj.toElement(doc), nocash); return null; }, }; types.textnode = types.whitespace = types.window = types.document = function (zero) { return zero; }; return function (el, nocash, doc) { if (el && el.$family && el.uniqueNumber) return el; var type = typeOf(el); return types[type] ? types[type](el, nocash, doc || document) : null; }; })(), }); if (window.$ == null) Window.implement("$", function (el, nc) { return document.id(el, nc, this.document); }); Window.implement({ getDocument: function () { return this.document; }, getWindow: function () { return this; }, }); [Document, Element].invoke("implement", { getElements: function (expression) { return Slick.search(this, expression, new Elements()); }, getElement: function (expression) { return document.id(Slick.find(this, expression)); }, }); var contains = { contains: function (element) { return Slick.contains(this, element); }, }; if (!document.contains) Document.implement(contains); if (!document.createElement("div").contains) Element.implement(contains); //<1.2compat> Element.implement("hasChild", function (element) { return this !== element && this.contains(element); }); (function (search, find, match) { this.Selectors = {}; var pseudos = (this.Selectors.Pseudo = new Hash()); var addSlickPseudos = function () { for (var name in pseudos) if (pseudos.hasOwnProperty(name)) { Slick.definePseudo(name, pseudos[name]); delete pseudos[name]; } }; Slick.search = function (context, expression, append) { addSlickPseudos(); return search.call(this, context, expression, append); }; Slick.find = function (context, expression) { addSlickPseudos(); return find.call(this, context, expression); }; Slick.match = function (node, selector) { addSlickPseudos(); return match.call(this, node, selector); }; })(Slick.search, Slick.find, Slick.match); // // tree walking var injectCombinator = function (expression, combinator) { if (!expression) return combinator; expression = Object.clone(Slick.parse(expression)); var expressions = expression.expressions; for (var i = expressions.length; i--; ) expressions[i][0].combinator = combinator; return expression; }; Object.forEach( { getNext: "~", getPrevious: "!~", getParent: "!", }, function (combinator, method) { Element.implement(method, function (expression) { return this.getElement(injectCombinator(expression, combinator)); }); }, ); Object.forEach( { getAllNext: "~", getAllPrevious: "!~", getSiblings: "~~", getChildren: ">", getParents: "!", }, function (combinator, method) { Element.implement(method, function (expression) { return this.getElements(injectCombinator(expression, combinator)); }); }, ); Element.implement({ getFirst: function (expression) { return document.id( Slick.search(this, injectCombinator(expression, ">"))[0], ); }, getLast: function (expression) { return document.id( Slick.search(this, injectCombinator(expression, ">")).getLast(), ); }, getWindow: function () { return this.ownerDocument.window; }, getDocument: function () { return this.ownerDocument; }, getElementById: function (id) { return document.id( Slick.find(this, "#" + ("" + id).replace(/(\W)/g, "\\$1")), ); }, match: function (expression) { return !expression || Slick.match(this, expression); }, }); //<1.2compat> if (window.$$ == null) Window.implement("$$", function (selector) { var elements = new Elements(); if (arguments.length == 1 && typeof selector == "string") return Slick.search(this.document, selector, elements); var args = Array.flatten(arguments); for (var i = 0, l = args.length; i < l; i++) { var item = args[i]; switch (typeOf(item)) { case "element": elements.push(item); break; case "string": Slick.search(this.document, item, elements); } } return elements; }); // if (window.$$ == null) Window.implement("$$", function (selector) { if (arguments.length == 1) { if (typeof selector == "string") return Slick.search(this.document, selector, new Elements()); else if (Type.isEnumerable(selector)) return new Elements(selector); } return new Elements(arguments); }); // Inserters var inserters = { before: function (context, element) { var parent = element.parentNode; if (parent) parent.insertBefore(context, element); }, after: function (context, element) { var parent = element.parentNode; if (parent) parent.insertBefore(context, element.nextSibling); }, bottom: function (context, element) { element.appendChild(context); }, top: function (context, element) { element.insertBefore(context, element.firstChild); }, }; inserters.inside = inserters.bottom; //<1.2compat> Object.each(inserters, function (inserter, where) { where = where.capitalize(); var methods = {}; methods["inject" + where] = function (el) { inserter(this, document.id(el, true)); return this; }; methods["grab" + where] = function (el) { inserter(document.id(el, true), this); return this; }; Element.implement(methods); }); // // getProperty / setProperty var propertyGetters = {}, propertySetters = {}; // properties var properties = {}; Array.forEach( [ "type", "value", "defaultValue", "accessKey", "cellPadding", "cellSpacing", "colSpan", "frameBorder", "rowSpan", "tabIndex", "useMap", ], function (property) { properties[property.toLowerCase()] = property; }, ); properties.html = "innerHTML"; properties.text = document.createElement("div").textContent == null ? "innerText" : "textContent"; Object.forEach(properties, function (real, key) { propertySetters[key] = function (node, value) { node[real] = value; }; propertyGetters[key] = function (node) { return node[real]; }; }); // Booleans var bools = [ "compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readOnly", "multiple", "selected", "noresize", "defer", "defaultChecked", "autofocus", "controls", "autoplay", "loop", ]; var booleans = {}; Array.forEach(bools, function (bool) { var lower = bool.toLowerCase(); booleans[lower] = bool; propertySetters[lower] = function (node, value) { node[bool] = !!value; }; propertyGetters[lower] = function (node) { return !!node[bool]; }; }); // Special cases Object.append(propertySetters, { class: function (node, value) { "className" in node ? (node.className = value || "") : node.setAttribute("class", value); }, for: function (node, value) { "htmlFor" in node ? (node.htmlFor = value) : node.setAttribute("for", value); }, style: function (node, value) { node.style ? (node.style.cssText = value) : node.setAttribute("style", value); }, value: function (node, value) { node.value = value != null ? value : ""; }, }); propertyGetters["class"] = function (node) { return "className" in node ? node.className || null : node.getAttribute("class"); }; /* */ var el = document.createElement("button"); // IE sets type as readonly and throws try { el.type = "button"; } catch (e) {} if (el.type != "button") propertySetters.type = function (node, value) { node.setAttribute("type", value); }; el = null; /* */ /**/ var input = document.createElement("input"); input.value = "t"; input.type = "submit"; if (input.value != "t") propertySetters.type = function (node, type) { var value = node.value; node.type = type; node.value = value; }; input = null; /**/ /* getProperty, setProperty */ /* */ var pollutesGetAttribute = (function (div) { div.random = "attribute"; return div.getAttribute("random") == "attribute"; })(document.createElement("div")); /* */ Element.implement({ setProperty: function (name, value) { var setter = propertySetters[name.toLowerCase()]; if (setter) { setter(this, value); } else { /* */ if (pollutesGetAttribute) var attributeWhiteList = this.retrieve("$attributeWhiteList", {}); /* */ if (value == null) { this.removeAttribute(name); /* */ if (pollutesGetAttribute) delete attributeWhiteList[name]; /* */ } else { this.setAttribute(name, "" + value); /* */ if (pollutesGetAttribute) attributeWhiteList[name] = true; /* */ } } return this; }, setProperties: function (attributes) { for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]); return this; }, getProperty: function (name) { var getter = propertyGetters[name.toLowerCase()]; if (getter) return getter(this); /* */ if (pollutesGetAttribute) { var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve("$attributeWhiteList", {}); if (!attr) return null; if (attr.expando && !attributeWhiteList[name]) { var outer = this.outerHTML; // segment by the opening tag and find mention of attribute name if ( outer .substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)) .indexOf(name) < 0 ) return null; attributeWhiteList[name] = true; } } /* */ var result = Slick.getAttribute(this, name); return !result && !Slick.hasAttribute(this, name) ? null : result; }, getProperties: function () { var args = Array.from(arguments); return args.map(this.getProperty, this).associate(args); }, removeProperty: function (name) { return this.setProperty(name, null); }, removeProperties: function () { Array.each(arguments, this.removeProperty, this); return this; }, set: function (prop, value) { var property = Element.Properties[prop]; property && property.set ? property.set.call(this, value) : this.setProperty(prop, value); }.overloadSetter(), get: function (prop) { var property = Element.Properties[prop]; return property && property.get ? property.get.apply(this) : this.getProperty(prop); }.overloadGetter(), erase: function (prop) { var property = Element.Properties[prop]; property && property.erase ? property.erase.apply(this) : this.removeProperty(prop); return this; }, hasClass: function (className) { return this.className.clean().contains(className, " "); }, addClass: function (className) { if (!this.hasClass(className)) this.className = (this.className + " " + className).clean(); return this; }, removeClass: function (className) { this.className = this.className.replace( new RegExp("(^|\\s)" + className + "(?:\\s|$)"), "$1", ); return this; }, toggleClass: function (className, force) { if (force == null) force = !this.hasClass(className); return force ? this.addClass(className) : this.removeClass(className); }, adopt: function () { var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length; if (length > 1) parent = fragment = document.createDocumentFragment(); for (var i = 0; i < length; i++) { var element = document.id(elements[i], true); if (element) parent.appendChild(element); } if (fragment) this.appendChild(fragment); return this; }, appendText: function (text, where) { return this.grab(this.getDocument().newTextNode(text), where); }, grab: function (el, where) { inserters[where || "bottom"](document.id(el, true), this); return this; }, inject: function (el, where) { inserters[where || "bottom"](this, document.id(el, true)); return this; }, replaces: function (el) { el = document.id(el, true); el.parentNode.replaceChild(this, el); return this; }, wraps: function (el, where) { el = document.id(el, true); return this.replaces(el).grab(el, where); }, getSelected: function () { this.selectedIndex; // Safari 3.2.1 return new Elements( Array.from(this.options).filter(function (option) { return option.selected; }), ); }, toQueryString: function () { var queryString = []; this.getElements("input, select, textarea").each(function (el) { var type = el.type; if ( !el.name || el.disabled || type == "submit" || type == "reset" || type == "file" || type == "image" ) return; var value = el.get("tag") == "select" ? el.getSelected().map(function (opt) { // IE return document.id(opt).get("value"); }) : (type == "radio" || type == "checkbox") && !el.checked ? null : el.get("value"); Array.from(value).each(function (val) { if (typeof val != "undefined") queryString.push( encodeURIComponent(el.name) + "=" + encodeURIComponent(val), ); }); }); return queryString.join("&"); }, }); var collected = {}, storage = {}; var get = function (uid) { return storage[uid] || (storage[uid] = {}); }; var clean = function (item) { var uid = item.uniqueNumber; if (item.removeEvents) item.removeEvents(); if (item.clearAttributes) item.clearAttributes(); if (uid != null) { delete collected[uid]; delete storage[uid]; } return item; }; var formProps = { input: "checked", option: "selected", textarea: "value" }; Element.implement({ destroy: function () { var children = clean(this).getElementsByTagName("*"); Array.each(children, clean); Element.dispose(this); return null; }, empty: function () { Array.from(this.childNodes).each(Element.dispose); return this; }, dispose: function () { return this.parentNode ? this.parentNode.removeChild(this) : this; }, clone: function (contents, keepid) { contents = contents !== false; var clone = this.cloneNode(contents), ce = [clone], te = [this], i; if (contents) { ce.append(Array.from(clone.getElementsByTagName("*"))); te.append(Array.from(this.getElementsByTagName("*"))); } for (i = ce.length; i--; ) { var node = ce[i], element = te[i]; if (!keepid) node.removeAttribute("id"); /**/ if (node.clearAttributes) { node.clearAttributes(); node.mergeAttributes(element); node.removeAttribute("uniqueNumber"); if (node.options) { var no = node.options, eo = element.options; for (var j = no.length; j--; ) no[j].selected = eo[j].selected; } } /**/ var prop = formProps[element.tagName.toLowerCase()]; if (prop && element[prop]) node[prop] = element[prop]; } /**/ if (Browser.ie) { var co = clone.getElementsByTagName("object"), to = this.getElementsByTagName("object"); for (i = co.length; i--; ) co[i].outerHTML = to[i].outerHTML; } /**/ return document.id(clone); }, }); [Element, Window, Document].invoke("implement", { addListener: function (type, fn) { if (type == "unload") { var old = fn, self = this; fn = function () { self.removeListener("unload", fn); old(); }; } else { collected[Slick.uidOf(this)] = this; } if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]); else this.attachEvent("on" + type, fn); return this; }, removeListener: function (type, fn) { if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]); else this.detachEvent("on" + type, fn); return this; }, retrieve: function (property, dflt) { var storage = get(Slick.uidOf(this)), prop = storage[property]; if (dflt != null && prop == null) prop = storage[property] = dflt; return prop != null ? prop : null; }, store: function (property, value) { var storage = get(Slick.uidOf(this)); storage[property] = value; return this; }, eliminate: function (property) { var storage = get(Slick.uidOf(this)); delete storage[property]; return this; }, }); /**/ if (window.attachEvent && !window.addEventListener) window.addListener("unload", function () { Object.each(collected, clean); if (window.CollectGarbage) CollectGarbage(); }); /**/ Element.Properties = {}; //<1.2compat> Element.Properties = new Hash(); // Element.Properties.style = { set: function (style) { this.style.cssText = style; }, get: function () { return this.style.cssText; }, erase: function () { this.style.cssText = ""; }, }; Element.Properties.tag = { get: function () { return this.tagName.toLowerCase(); }, }; Element.Properties.html = { set: function (html) { if (html == null) html = ""; else if (typeOf(html) == "array") html = html.join(""); this.innerHTML = html; }, erase: function () { this.innerHTML = ""; }, }; /**/ // technique by jdbarlett - http://jdbartlett.com/innershiv/ var div = document.createElement("div"); div.innerHTML = ""; var supportsHTML5Elements = div.childNodes.length == 1; if (!supportsHTML5Elements) { var tags = "abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split( " ", ), fragment = document.createDocumentFragment(), l = tags.length; while (l--) fragment.createElement(tags[l]); } div = null; /**/ /**/ var supportsTableInnerHTML = Function.attempt(function () { var table = document.createElement("table"); table.innerHTML = ""; return true; }); /**/ var tr = document.createElement("tr"), html = ""; tr.innerHTML = html; var supportsTRInnerHTML = tr.innerHTML == html; tr = null; /**/ if ( !supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements ) { Element.Properties.html.set = (function (set) { var translations = { table: [1, "", "
"], select: [1, ""], tbody: [2, "", "
"], tr: [3, "", "
"], }; translations.thead = translations.tfoot = translations.tbody; return function (html) { var wrap = translations[this.get("tag")]; if (!wrap && !supportsHTML5Elements) wrap = [0, "", ""]; if (!wrap) return set.call(this, html); var level = wrap[0], wrapper = document.createElement("div"), target = wrapper; if (!supportsHTML5Elements) fragment.appendChild(wrapper); wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join(""); while (level--) target = target.firstChild; this.empty().adopt(target.childNodes); if (!supportsHTML5Elements) fragment.removeChild(wrapper); wrapper = null; }; })(Element.Properties.html.set); } /*
*/ /**/ var testForm = document.createElement("form"); testForm.innerHTML = ""; if (testForm.firstChild.value != "s") Element.Properties.value = { set: function (value) { var tag = this.get("tag"); if (tag != "select") return this.setProperty("value", value); var options = this.getElements("option"); for (var i = 0; i < options.length; i++) { var option = options[i], attr = option.getAttributeNode("value"), optionValue = attr && attr.specified ? option.value : option.get("text"); if (optionValue == value) return (option.selected = true); } }, get: function () { var option = this, tag = option.get("tag"); if (tag != "select" && tag != "option") return this.getProperty("value"); if (tag == "select" && !(option = option.getSelected()[0])) return ""; var attr = option.getAttributeNode("value"); return attr && attr.specified ? option.value : option.get("text"); }, }; testForm = null; /**/ /**/ if (document.createElement("div").getAttributeNode("id")) Element.Properties.id = { set: function (id) { this.id = this.getAttributeNode("id").value = id; }, get: function () { return this.id || null; }, erase: function () { this.id = this.getAttributeNode("id").value = ""; }, }; /**/ })(); /* --- name: Element.Style description: Contains methods for interacting with the styles of Elements in a fashionable way. license: MIT-style license. requires: Element provides: Element.Style ... */ (function () { var html = document.html; // // Check for oldIE, which does not remove styles when they're set to null var el = document.createElement("div"); el.style.color = "red"; el.style.color = null; var doesNotRemoveStyles = el.style.color == "red"; el = null; // Element.Properties.styles = { set: function (styles) { this.setStyles(styles); }, }; var hasOpacity = html.style.opacity != null, hasFilter = html.style.filter != null, reAlpha = /alpha\(opacity=([\d.]+)\)/i; var setVisibility = function (element, opacity) { element.store("$opacity", opacity); element.style.visibility = opacity > 0 || opacity == null ? "visible" : "hidden"; }; var setOpacity = hasOpacity ? function (element, opacity) { element.style.opacity = opacity; } : hasFilter ? function (element, opacity) { var style = element.style; if (!element.currentStyle || !element.currentStyle.hasLayout) style.zoom = 1; if (opacity == null || opacity == 1) opacity = ""; else opacity = "alpha(opacity=" + (opacity * 100).limit(0, 100).round() + ")"; var filter = style.filter || element.getComputedStyle("filter") || ""; style.filter = reAlpha.test(filter) ? filter.replace(reAlpha, opacity) : filter + opacity; if (!style.filter) style.removeAttribute("filter"); } : setVisibility; var getOpacity = hasOpacity ? function (element) { var opacity = element.style.opacity || element.getComputedStyle("opacity"); return opacity == "" ? 1 : opacity.toFloat(); } : hasFilter ? function (element) { var filter = element.style.filter || element.getComputedStyle("filter"), opacity; if (filter) opacity = filter.match(reAlpha); return opacity == null || filter == null ? 1 : opacity[1] / 100; } : function (element) { var opacity = element.retrieve("$opacity"); if (opacity == null) opacity = element.style.visibility == "hidden" ? 0 : 1; return opacity; }; var floatName = html.style.cssFloat == null ? "styleFloat" : "cssFloat"; Element.implement({ getComputedStyle: function (property) { if (this.currentStyle) return this.currentStyle[property.camelCase()]; var defaultView = Element.getDocument(this).defaultView, computed = defaultView ? defaultView.getComputedStyle(this, null) : null; return computed ? computed.getPropertyValue( property == floatName ? "float" : property.hyphenate(), ) : null; }, setStyle: function (property, value) { if (property == "opacity") { if (value != null) value = parseFloat(value); setOpacity(this, value); return this; } property = (property == "float" ? floatName : property).camelCase(); if (typeOf(value) != "string") { var map = (Element.Styles[property] || "@").split(" "); value = Array.from(value) .map(function (val, i) { if (!map[i]) return ""; return typeOf(val) == "number" ? map[i].replace("@", Math.round(val)) : val; }) .join(" "); } else if (value == String(Number(value))) { value = Math.round(value); } this.style[property] = value; // if ( (value == "" || value == null) && doesNotRemoveStyles && this.style.removeAttribute ) { this.style.removeAttribute(property); } // return this; }, getStyle: function (property) { if (property == "opacity") return getOpacity(this); property = (property == "float" ? floatName : property).camelCase(); var result = this.style[property]; if (!result || property == "zIndex") { result = []; for (var style in Element.ShortStyles) { if (property != style) continue; for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s)); return result.join(" "); } result = this.getComputedStyle(property); } if (result) { result = String(result); var color = result.match(/rgba?\([\d\s,]+\)/); if (color) result = result.replace(color[0], color[0].rgbToHex()); } if (Browser.opera || Browser.ie) { if (/^(height|width)$/.test(property) && !/px$/.test(result)) { var values = property == "width" ? ["left", "right"] : ["top", "bottom"], size = 0; values.each(function (value) { size += this.getStyle("border-" + value + "-width").toInt() + this.getStyle("padding-" + value).toInt(); }, this); return this["offset" + property.capitalize()] - size + "px"; } if ( Browser.ie && /^border(.+)Width|margin|padding/.test(property) && isNaN(parseFloat(result)) ) { return "0px"; } } return result; }, setStyles: function (styles) { for (var style in styles) this.setStyle(style, styles[style]); return this; }, getStyles: function () { var result = {}; Array.flatten(arguments).each(function (key) { result[key] = this.getStyle(key); }, this); return result; }, }); Element.Styles = { left: "@px", top: "@px", bottom: "@px", right: "@px", width: "@px", height: "@px", maxWidth: "@px", maxHeight: "@px", minWidth: "@px", minHeight: "@px", backgroundColor: "rgb(@, @, @)", backgroundPosition: "@px @px", color: "rgb(@, @, @)", fontSize: "@px", letterSpacing: "@px", lineHeight: "@px", clip: "rect(@px @px @px @px)", margin: "@px @px @px @px", padding: "@px @px @px @px", border: "@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)", borderWidth: "@px @px @px @px", borderStyle: "@ @ @ @", borderColor: "rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)", zIndex: "@", zoom: "@", fontWeight: "@", textIndent: "@px", opacity: "@", }; //<1.3compat> Element.implement({ setOpacity: function (value) { setOpacity(this, value); return this; }, getOpacity: function () { return getOpacity(this); }, }); Element.Properties.opacity = { set: function (opacity) { setOpacity(this, opacity); setVisibility(this, opacity); }, get: function () { return getOpacity(this); }, }; // //<1.2compat> Element.Styles = new Hash(Element.Styles); // Element.ShortStyles = { margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}, }; ["Top", "Right", "Bottom", "Left"].each(function (direction) { var Short = Element.ShortStyles; var All = Element.Styles; ["margin", "padding"].each(function (style) { var sd = style + direction; Short[style][sd] = All[sd] = "@px"; }); var bd = "border" + direction; Short.border[bd] = All[bd] = "@px @ rgb(@, @, @)"; var bdw = bd + "Width", bds = bd + "Style", bdc = bd + "Color"; Short[bd] = {}; Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = "@px"; Short.borderStyle[bds] = Short[bd][bds] = All[bds] = "@"; Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = "rgb(@, @, @)"; }); })(); /* --- name: Element.Event description: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events, if necessary. license: MIT-style license. requires: [Element, Event] provides: Element.Event ... */ (function () { Element.Properties.events = { set: function (events) { this.addEvents(events); }, }; [Element, Window, Document].invoke("implement", { addEvent: function (type, fn) { var events = this.retrieve("events", {}); if (!events[type]) events[type] = { keys: [], values: [] }; if (events[type].keys.contains(fn)) return this; events[type].keys.push(fn); var realType = type, custom = Element.Events[type], condition = fn, self = this; if (custom) { if (custom.onAdd) custom.onAdd.call(this, fn, type); if (custom.condition) { condition = function (event) { if (custom.condition.call(this, event, type)) return fn.call(this, event); return true; }; } if (custom.base) realType = Function.from(custom.base).call(this, type); } var defn = function () { return fn.call(self); }; var nativeEvent = Element.NativeEvents[realType]; if (nativeEvent) { if (nativeEvent == 2) { defn = function (event) { event = new DOMEvent(event, self.getWindow()); if (condition.call(self, event) === false) event.stop(); }; } this.addListener(realType, defn, arguments[2]); } events[type].values.push(defn); return this; }, removeEvent: function (type, fn) { var events = this.retrieve("events"); if (!events || !events[type]) return this; var list = events[type]; var index = list.keys.indexOf(fn); if (index == -1) return this; var value = list.values[index]; delete list.keys[index]; delete list.values[index]; var custom = Element.Events[type]; if (custom) { if (custom.onRemove) custom.onRemove.call(this, fn, type); if (custom.base) type = Function.from(custom.base).call(this, type); } return Element.NativeEvents[type] ? this.removeListener(type, value, arguments[2]) : this; }, addEvents: function (events) { for (var event in events) this.addEvent(event, events[event]); return this; }, removeEvents: function (events) { var type; if (typeOf(events) == "object") { for (type in events) this.removeEvent(type, events[type]); return this; } var attached = this.retrieve("events"); if (!attached) return this; if (!events) { for (type in attached) this.removeEvents(type); this.eliminate("events"); } else if (attached[events]) { attached[events].keys.each(function (fn) { this.removeEvent(events, fn); }, this); delete attached[events]; } return this; }, fireEvent: function (type, args, delay) { var events = this.retrieve("events"); if (!events || !events[type]) return this; args = Array.from(args); events[type].keys.each(function (fn) { if (delay) fn.delay(delay, this, args); else fn.apply(this, args); }, this); return this; }, cloneEvents: function (from, type) { from = document.id(from); var events = from.retrieve("events"); if (!events) return this; if (!type) { for (var eventType in events) this.cloneEvents(from, eventType); } else if (events[type]) { events[type].keys.each(function (fn) { this.addEvent(type, fn); }, this); } return this; }, }); Element.NativeEvents = { click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons mousewheel: 2, DOMMouseScroll: 2, //mouse wheel mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement keydown: 2, keypress: 2, keyup: 2, //keyboard orientationchange: 2, // mobile touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window error: 1, abort: 1, scroll: 1, //misc }; Element.Events = { mousewheel: { base: Browser.firefox ? "DOMMouseScroll" : "mousewheel", }, }; if ("onmouseenter" in document.documentElement) { Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2; } else { var check = function (event) { var related = event.relatedTarget; if (related == null) return true; if (!related) return false; return ( related != this && related.prefix != "xul" && typeOf(this) != "document" && !this.contains(related) ); }; Element.Events.mouseenter = { base: "mouseover", condition: check, }; Element.Events.mouseleave = { base: "mouseout", condition: check, }; } /**/ if (!window.addEventListener) { Element.NativeEvents.propertychange = 2; Element.Events.change = { base: function () { var type = this.type; return this.get("tag") == "input" && (type == "radio" || type == "checkbox") ? "propertychange" : "change"; }, condition: function (event) { return ( this.type != "radio" || (event.event.propertyName == "checked" && this.checked) ); }, }; } /**/ //<1.2compat> Element.Events = new Hash(Element.Events); // })(); /* --- name: Element.Delegation description: Extends the Element native object to include the delegate method for more efficient event management. license: MIT-style license. requires: [Element.Event] provides: [Element.Delegation] ... */ (function () { var eventListenerSupport = !!window.addEventListener; Element.NativeEvents.focusin = Element.NativeEvents.focusout = 2; var bubbleUp = function (self, match, fn, event, target) { while (target && target != self) { if (match(target, event)) return fn.call(target, event, target); target = document.id(target.parentNode); } }; var map = { mouseenter: { base: "mouseover", }, mouseleave: { base: "mouseout", }, focus: { base: "focus" + (eventListenerSupport ? "" : "in"), capture: true, }, blur: { base: eventListenerSupport ? "blur" : "focusout", capture: true, }, }; /**/ var _key = "$delegation:"; var formObserver = function (type) { return { base: "focusin", remove: function (self, uid) { var list = self.retrieve(_key + type + "listeners", {})[uid]; if (list && list.forms) for (var i = list.forms.length; i--; ) { list.forms[i].removeEvent(type, list.fns[i]); } }, listen: function (self, match, fn, event, target, uid) { var form = target.get("tag") == "form" ? target : event.target.getParent("form"); if (!form) return; var listeners = self.retrieve(_key + type + "listeners", {}), listener = listeners[uid] || { forms: [], fns: [] }, forms = listener.forms, fns = listener.fns; if (forms.indexOf(form) != -1) return; forms.push(form); var _fn = function (event) { bubbleUp(self, match, fn, event, target); }; form.addEvent(type, _fn); fns.push(_fn); listeners[uid] = listener; self.store(_key + type + "listeners", listeners); }, }; }; var inputObserver = function (type) { return { base: "focusin", listen: function (self, match, fn, event, target) { var events = { blur: function () { this.removeEvents(events); }, }; events[type] = function (event) { bubbleUp(self, match, fn, event, target); }; event.target.addEvents(events); }, }; }; if (!eventListenerSupport) Object.append(map, { submit: formObserver("submit"), reset: formObserver("reset"), change: inputObserver("change"), select: inputObserver("select"), }); /**/ var proto = Element.prototype, addEvent = proto.addEvent, removeEvent = proto.removeEvent; var relay = function (old, method) { return function (type, fn, useCapture) { if (type.indexOf(":relay") == -1) return old.call(this, type, fn, useCapture); var parsed = Slick.parse(type).expressions[0][0]; if (parsed.pseudos[0].key != "relay") return old.call(this, type, fn, useCapture); var newType = parsed.tag; parsed.pseudos.slice(1).each(function (pseudo) { newType += ":" + pseudo.key + (pseudo.value ? "(" + pseudo.value + ")" : ""); }); old.call(this, type, fn); return method.call(this, newType, parsed.pseudos[0].value, fn); }; }; var delegation = { addEvent: function (type, match, fn) { var storage = this.retrieve("$delegates", {}), stored = storage[type]; if (stored) for (var _uid in stored) { if (stored[_uid].fn == fn && stored[_uid].match == match) return this; } var _type = type, _match = match, _fn = fn, _map = map[type] || {}; type = _map.base || _type; match = function (target) { return Slick.match(target, _match); }; var elementEvent = Element.Events[_type]; if (elementEvent && elementEvent.condition) { var __match = match, condition = elementEvent.condition; match = function (target, event) { return __match(target, event) && condition.call(target, event, type); }; } var self = this, uid = String.uniqueID(); var delegator = _map.listen ? function (event, target) { if (!target && event && event.target) target = event.target; if (target) _map.listen(self, match, fn, event, target, uid); } : function (event, target) { if (!target && event && event.target) target = event.target; if (target) bubbleUp(self, match, fn, event, target); }; if (!stored) stored = {}; stored[uid] = { match: _match, fn: _fn, delegator: delegator, }; storage[_type] = stored; return addEvent.call(this, type, delegator, _map.capture); }, removeEvent: function (type, match, fn, _uid) { var storage = this.retrieve("$delegates", {}), stored = storage[type]; if (!stored) return this; if (_uid) { var _type = type, delegator = stored[_uid].delegator, _map = map[type] || {}; type = _map.base || _type; if (_map.remove) _map.remove(this, _uid); delete stored[_uid]; storage[_type] = stored; return removeEvent.call(this, type, delegator); } var __uid, s; if (fn) for (__uid in stored) { s = stored[__uid]; if (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid); } else for (__uid in stored) { s = stored[__uid]; if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid); } return this; }, }; [Element, Window, Document].invoke("implement", { addEvent: relay(addEvent, delegation.addEvent), removeEvent: relay(removeEvent, delegation.removeEvent), }); })(); /* --- name: Element.Dimensions description: Contains methods to work with size, scroll, or positioning of Elements and the window object. license: MIT-style license. credits: - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html). - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html). requires: [Element, Element.Style] provides: [Element.Dimensions] ... */ (function () { var element = document.createElement("div"), child = document.createElement("div"); element.style.height = "0"; element.appendChild(child); var brokenOffsetParent = child.offsetParent === element; element = child = null; var isOffset = function (el) { return styleString(el, "position") != "static" || isBody(el); }; var isOffsetStatic = function (el) { return isOffset(el) || /^(?:table|td|th)$/i.test(el.tagName); }; Element.implement({ scrollTo: function (x, y) { if (isBody(this)) { this.getWindow().scrollTo(x, y); } else { this.scrollLeft = x; this.scrollTop = y; } return this; }, getSize: function () { if (isBody(this)) return this.getWindow().getSize(); return { x: this.offsetWidth, y: this.offsetHeight }; }, getScrollSize: function () { if (isBody(this)) return this.getWindow().getScrollSize(); return { x: this.scrollWidth, y: this.scrollHeight }; }, getScroll: function () { if (isBody(this)) return this.getWindow().getScroll(); return { x: this.scrollLeft, y: this.scrollTop }; }, getScrolls: function () { var element = this.parentNode, position = { x: 0, y: 0 }; while (element && !isBody(element)) { position.x += element.scrollLeft; position.y += element.scrollTop; element = element.parentNode; } return position; }, getOffsetParent: brokenOffsetParent ? function () { var element = this; if (isBody(element) || styleString(element, "position") == "fixed") return null; var isOffsetCheck = styleString(element, "position") == "static" ? isOffsetStatic : isOffset; while ((element = element.parentNode)) { if (isOffsetCheck(element)) return element; } return null; } : function () { var element = this; if (isBody(element) || styleString(element, "position") == "fixed") return null; try { return element.offsetParent; } catch (e) {} return null; }, getOffsets: function () { if (this.getBoundingClientRect && !Browser.Platform.ios) { var bound = this.getBoundingClientRect(), html = document.id(this.getDocument().documentElement), htmlScroll = html.getScroll(), elemScrolls = this.getScrolls(), isFixed = styleString(this, "position") == "fixed"; return { x: bound.left.toInt() + elemScrolls.x + (isFixed ? 0 : htmlScroll.x) - html.clientLeft, y: bound.top.toInt() + elemScrolls.y + (isFixed ? 0 : htmlScroll.y) - html.clientTop, }; } var element = this, position = { x: 0, y: 0 }; if (isBody(this)) return position; while (element && !isBody(element)) { position.x += element.offsetLeft; position.y += element.offsetTop; if (Browser.firefox) { if (!borderBox(element)) { position.x += leftBorder(element); position.y += topBorder(element); } var parent = element.parentNode; if (parent && styleString(parent, "overflow") != "visible") { position.x += leftBorder(parent); position.y += topBorder(parent); } } else if (element != this && Browser.safari) { position.x += leftBorder(element); position.y += topBorder(element); } element = element.offsetParent; } if (Browser.firefox && !borderBox(this)) { position.x -= leftBorder(this); position.y -= topBorder(this); } return position; }, getPosition: function (relative) { var offset = this.getOffsets(), scroll = this.getScrolls(); var position = { x: offset.x - scroll.x, y: offset.y - scroll.y, }; if (relative && (relative = document.id(relative))) { var relativePosition = relative.getPosition(); return { x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative), }; } return position; }, getCoordinates: function (element) { if (isBody(this)) return this.getWindow().getCoordinates(); var position = this.getPosition(element), size = this.getSize(); var obj = { left: position.x, top: position.y, width: size.x, height: size.y, }; obj.right = obj.left + obj.width; obj.bottom = obj.top + obj.height; return obj; }, computePosition: function (obj) { return { left: obj.x - styleNumber(this, "margin-left"), top: obj.y - styleNumber(this, "margin-top"), }; }, setPosition: function (obj) { return this.setStyles(this.computePosition(obj)); }, }); [Document, Window].invoke("implement", { getSize: function () { var doc = getCompatElement(this); return { x: doc.clientWidth, y: doc.clientHeight }; }, getScroll: function () { var win = this.getWindow(), doc = getCompatElement(this); return { x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop, }; }, getScrollSize: function () { var doc = getCompatElement(this), min = this.getSize(), body = this.getDocument().body; return { x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y), }; }, getPosition: function () { return { x: 0, y: 0 }; }, getCoordinates: function () { var size = this.getSize(); return { top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x, }; }, }); // private methods var styleString = Element.getComputedStyle; function styleNumber(element, style) { return styleString(element, style).toInt() || 0; } function borderBox(element) { return styleString(element, "-moz-box-sizing") == "border-box"; } function topBorder(element) { return styleNumber(element, "border-top-width"); } function leftBorder(element) { return styleNumber(element, "border-left-width"); } function isBody(element) { return /^(?:body|html)$/i.test(element.tagName); } function getCompatElement(element) { var doc = element.getDocument(); return !doc.compatMode || doc.compatMode == "CSS1Compat" ? doc.html : doc.body; } })(); //aliases Element.alias({ position: "setPosition" }); //compatability [Window, Document, Element].invoke("implement", { getHeight: function () { return this.getSize().y; }, getWidth: function () { return this.getSize().x; }, getScrollTop: function () { return this.getScroll().y; }, getScrollLeft: function () { return this.getScroll().x; }, getScrollHeight: function () { return this.getScrollSize().y; }, getScrollWidth: function () { return this.getScrollSize().x; }, getTop: function () { return this.getPosition().y; }, getLeft: function () { return this.getPosition().x; }, }); /* --- name: Fx description: Contains the basic animation logic to be extended by all other Fx Classes. license: MIT-style license. requires: [Chain, Events, Options] provides: Fx ... */ (function () { var Fx = (this.Fx = new Class({ Implements: [Chain, Events, Options], options: { /* onStart: nil, onCancel: nil, onComplete: nil, */ fps: 60, unit: false, duration: 500, frames: null, frameSkip: true, link: "ignore", }, initialize: function (options) { this.subject = this.subject || this; this.setOptions(options); }, getTransition: function () { return function (p) { return -(Math.cos(Math.PI * p) - 1) / 2; }; }, step: function (now) { if (this.options.frameSkip) { var diff = this.time != null ? now - this.time : 0, frames = diff / this.frameInterval; this.time = now; this.frame += frames; } else { this.frame++; } if (this.frame < this.frames) { var delta = this.transition(this.frame / this.frames); this.set(this.compute(this.from, this.to, delta)); } else { this.frame = this.frames; this.set(this.compute(this.from, this.to, 1)); this.stop(); } }, set: function (now) { return now; }, compute: function (from, to, delta) { return Fx.compute(from, to, delta); }, check: function () { if (!this.isRunning()) return true; switch (this.options.link) { case "cancel": this.cancel(); return true; case "chain": this.chain(this.caller.pass(arguments, this)); return false; } return false; }, start: function (from, to) { if (!this.check(from, to)) return this; this.from = from; this.to = to; this.frame = this.options.frameSkip ? 0 : -1; this.time = null; this.transition = this.getTransition(); var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration; this.duration = Fx.Durations[duration] || duration.toInt(); this.frameInterval = 1000 / fps; this.frames = frames || Math.round(this.duration / this.frameInterval); this.fireEvent("start", this.subject); pushInstance.call(this, fps); return this; }, stop: function () { if (this.isRunning()) { this.time = null; pullInstance.call(this, this.options.fps); if (this.frames == this.frame) { this.fireEvent("complete", this.subject); if (!this.callChain()) this.fireEvent("chainComplete", this.subject); } else { this.fireEvent("stop", this.subject); } } return this; }, cancel: function () { if (this.isRunning()) { this.time = null; pullInstance.call(this, this.options.fps); this.frame = this.frames; this.fireEvent("cancel", this.subject).clearChain(); } return this; }, pause: function () { if (this.isRunning()) { this.time = null; pullInstance.call(this, this.options.fps); } return this; }, resume: function () { if (this.frame < this.frames && !this.isRunning()) pushInstance.call(this, this.options.fps); return this; }, isRunning: function () { var list = instances[this.options.fps]; return list && list.contains(this); }, })); Fx.compute = function (from, to, delta) { return (to - from) * delta + from; }; Fx.Durations = { short: 250, normal: 500, long: 1000 }; // global timers var instances = {}, timers = {}; var loop = function () { var now = Date.now(); for (var i = this.length; i--; ) { var instance = this[i]; if (instance) instance.step(now); } }; var pushInstance = function (fps) { var list = instances[fps] || (instances[fps] = []); list.push(this); if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list); }; var pullInstance = function (fps) { var list = instances[fps]; if (list) { list.erase(this); if (!list.length && timers[fps]) { delete instances[fps]; timers[fps] = clearInterval(timers[fps]); } } }; })(); /* --- name: Fx.CSS description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements. license: MIT-style license. requires: [Fx, Element.Style] provides: Fx.CSS ... */ Fx.CSS = new Class({ Extends: Fx, //prepares the base from/to object prepare: function (element, property, values) { values = Array.from(values); var from = values[0], to = values[1]; if (to == null) { to = from; from = element.getStyle(property); var unit = this.options.unit; // adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299 if (unit && from.slice(-unit.length) != unit && parseFloat(from) != 0) { element.setStyle(property, to + unit); var value = element.getComputedStyle(property); // IE and Opera support pixelLeft or pixelWidth if (!/px$/.test(value)) { value = element.style[("pixel-" + property).camelCase()]; if (value == null) { // adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 var left = element.style.left; element.style.left = to + unit; value = element.style.pixelLeft; element.style.left = left; } } from = ((to || 1) / (parseFloat(value) || 1)) * (parseFloat(from) || 0); element.setStyle(property, from + unit); } } return { from: this.parse(from), to: this.parse(to) }; }, //parses a value into an array parse: function (value) { value = Function.from(value)(); value = typeof value == "string" ? value.split(" ") : Array.from(value); return value.map(function (val) { val = String(val); var found = false; Object.each(Fx.CSS.Parsers, function (parser, key) { if (found) return; var parsed = parser.parse(val); if (parsed || parsed === 0) found = { value: parsed, parser: parser }; }); found = found || { value: val, parser: Fx.CSS.Parsers.String }; return found; }); }, //computes by a from and to prepared objects, using their parsers. compute: function (from, to, delta) { var computed = []; Math.min(from.length, to.length).times(function (i) { computed.push({ value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser, }); }); computed.$family = Function.from("fx:css:value"); return computed; }, //serves the value as settable serve: function (value, unit) { if (typeOf(value) != "fx:css:value") value = this.parse(value); var returned = []; value.each(function (bit) { returned = returned.concat(bit.parser.serve(bit.value, unit)); }); return returned; }, //renders the change to an element render: function (element, property, value, unit) { element.setStyle(property, this.serve(value, unit)); }, //searches inside the page css to find the values for a selector search: function (selector) { if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector]; var to = {}, selectorTest = new RegExp("^" + selector.escapeRegExp() + "$"); Array.each(document.styleSheets, function (sheet, j) { var href = sheet.href; if (href && href.contains("://") && !href.contains(document.domain)) return; var rules = sheet.rules || sheet.cssRules; Array.each(rules, function (rule, i) { if (!rule.style) return; var selectorText = rule.selectorText ? rule.selectorText.replace(/^\w+/, function (m) { return m.toLowerCase(); }) : null; if (!selectorText || !selectorTest.test(selectorText)) return; Object.each(Element.Styles, function (value, style) { if (!rule.style[style] || Element.ShortStyles[style]) return; value = String(rule.style[style]); to[style] = /^rgb/.test(value) ? value.rgbToHex() : value; }); }); }); return (Fx.CSS.Cache[selector] = to); }, }); Fx.CSS.Cache = {}; Fx.CSS.Parsers = { Color: { parse: function (value) { if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true); return (value = value.match(/(\d+),\s*(\d+),\s*(\d+)/)) ? [value[1], value[2], value[3]] : false; }, compute: function (from, to, delta) { return from.map(function (value, i) { return Math.round(Fx.compute(from[i], to[i], delta)); }); }, serve: function (value) { return value.map(Number); }, }, Number: { parse: parseFloat, compute: Fx.compute, serve: function (value, unit) { return unit ? value + unit : value; }, }, String: { parse: Function.from(false), compute: function (zero, one) { return one; }, serve: function (zero) { return zero; }, }, }; //<1.2compat> Fx.CSS.Parsers = new Hash(Fx.CSS.Parsers); // /* --- name: Fx.Tween description: Formerly Fx.Style, effect to transition any CSS property for an element. license: MIT-style license. requires: Fx.CSS provides: [Fx.Tween, Element.fade, Element.highlight] ... */ Fx.Tween = new Class({ Extends: Fx.CSS, initialize: function (element, options) { this.element = this.subject = document.id(element); this.parent(options); }, set: function (property, now) { if (arguments.length == 1) { now = property; property = this.property || this.options.property; } this.render(this.element, property, now, this.options.unit); return this; }, start: function (property, from, to) { if (!this.check(property, from, to)) return this; var args = Array.flatten(arguments); this.property = this.options.property || args.shift(); var parsed = this.prepare(this.element, this.property, args); return this.parent(parsed.from, parsed.to); }, }); Element.Properties.tween = { set: function (options) { this.get("tween").cancel().setOptions(options); return this; }, get: function () { var tween = this.retrieve("tween"); if (!tween) { tween = new Fx.Tween(this, { link: "cancel" }); this.store("tween", tween); } return tween; }, }; Element.implement({ tween: function (property, from, to) { this.get("tween").start(property, from, to); return this; }, fade: function (how) { var fade = this.get("tween"), method, args = ["opacity"].append(arguments), toggle; if (args[1] == null) args[1] = "toggle"; switch (args[1]) { case "in": method = "start"; args[1] = 1; break; case "out": method = "start"; args[1] = 0; break; case "show": method = "set"; args[1] = 1; break; case "hide": method = "set"; args[1] = 0; break; case "toggle": var flag = this.retrieve("fade:flag", this.getStyle("opacity") == 1); method = "start"; args[1] = flag ? 0 : 1; this.store("fade:flag", !flag); toggle = true; break; default: method = "start"; } if (!toggle) this.eliminate("fade:flag"); fade[method].apply(fade, args); var to = args[args.length - 1]; if (method == "set" || to != 0) this.setStyle("visibility", to == 0 ? "hidden" : "visible"); else fade.chain(function () { this.element.setStyle("visibility", "hidden"); this.callChain(); }); return this; }, highlight: function (start, end) { if (!end) { end = this.retrieve( "highlight:original", this.getStyle("background-color"), ); end = end == "transparent" ? "#fff" : end; } var tween = this.get("tween"); tween.start("background-color", start || "#ffff88", end).chain( function () { this.setStyle("background-color", this.retrieve("highlight:original")); tween.callChain(); }.bind(this), ); return this; }, }); /* --- name: Fx.Morph description: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules. license: MIT-style license. requires: Fx.CSS provides: Fx.Morph ... */ Fx.Morph = new Class({ Extends: Fx.CSS, initialize: function (element, options) { this.element = this.subject = document.id(element); this.parent(options); }, set: function (now) { if (typeof now == "string") now = this.search(now); for (var p in now) this.render(this.element, p, now[p], this.options.unit); return this; }, compute: function (from, to, delta) { var now = {}; for (var p in from) now[p] = this.parent(from[p], to[p], delta); return now; }, start: function (properties) { if (!this.check(properties)) return this; if (typeof properties == "string") properties = this.search(properties); var from = {}, to = {}; for (var p in properties) { var parsed = this.prepare(this.element, p, properties[p]); from[p] = parsed.from; to[p] = parsed.to; } return this.parent(from, to); }, }); Element.Properties.morph = { set: function (options) { this.get("morph").cancel().setOptions(options); return this; }, get: function () { var morph = this.retrieve("morph"); if (!morph) { morph = new Fx.Morph(this, { link: "cancel" }); this.store("morph", morph); } return morph; }, }; Element.implement({ morph: function (props) { this.get("morph").start(props); return this; }, }); /* --- name: Fx.Transitions description: Contains a set of advanced transitions to be used with any of the Fx Classes. license: MIT-style license. credits: - Easing Equations by Robert Penner, , modified and optimized to be used with MooTools. requires: Fx provides: Fx.Transitions ... */ Fx.implement({ getTransition: function () { var trans = this.options.transition || Fx.Transitions.Sine.easeInOut; if (typeof trans == "string") { var data = trans.split(":"); trans = Fx.Transitions; trans = trans[data[0]] || trans[data[0].capitalize()]; if (data[1]) trans = trans[ "ease" + data[1].capitalize() + (data[2] ? data[2].capitalize() : "") ]; } return trans; }, }); Fx.Transition = function (transition, params) { params = Array.from(params); var easeIn = function (pos) { return transition(pos, params); }; return Object.append(easeIn, { easeIn: easeIn, easeOut: function (pos) { return 1 - transition(1 - pos, params); }, easeInOut: function (pos) { return ( (pos <= 0.5 ? transition(2 * pos, params) : 2 - transition(2 * (1 - pos), params)) / 2 ); }, }); }; Fx.Transitions = { linear: function (zero) { return zero; }, }; //<1.2compat> Fx.Transitions = new Hash(Fx.Transitions); // Fx.Transitions.extend = function (transitions) { for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]); }; Fx.Transitions.extend({ Pow: function (p, x) { return Math.pow(p, (x && x[0]) || 6); }, Expo: function (p) { return Math.pow(2, 8 * (p - 1)); }, Circ: function (p) { return 1 - Math.sin(Math.acos(p)); }, Sine: function (p) { return 1 - Math.cos((p * Math.PI) / 2); }, Back: function (p, x) { x = (x && x[0]) || 1.618; return Math.pow(p, 2) * ((x + 1) * p - x); }, Bounce: function (p) { var value; for (var a = 0, b = 1; 1; a += b, b /= 2) { if (p >= (7 - 4 * a) / 11) { value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); break; } } return value; }, Elastic: function (p, x) { return ( Math.pow(2, 10 * --p) * Math.cos((20 * p * Math.PI * ((x && x[0]) || 1)) / 3) ); }, }); ["Quad", "Cubic", "Quart", "Quint"].each(function (transition, i) { Fx.Transitions[transition] = new Fx.Transition(function (p) { return Math.pow(p, i + 2); }); }); /* --- name: Request description: Powerful all purpose Request Class. Uses XMLHTTPRequest. license: MIT-style license. requires: [Object, Element, Chain, Events, Options, Browser] provides: Request ... */ (function () { var empty = function () {}, progressSupport = "onprogress" in new Browser.Request(); var Request = (this.Request = new Class({ Implements: [Chain, Events, Options], options: { /* onRequest: function(){}, onLoadstart: function(event, xhr){}, onProgress: function(event, xhr){}, onComplete: function(){}, onCancel: function(){}, onSuccess: function(responseText, responseXML){}, onFailure: function(xhr){}, onException: function(headerName, value){}, onTimeout: function(){}, user: '', password: '',*/ url: "", data: "", headers: { "X-Requested-With": "XMLHttpRequest", Accept: "text/javascript, text/html, application/xml, text/xml, */*", }, async: true, format: false, method: "post", link: "ignore", isSuccess: null, emulation: true, urlEncoded: true, encoding: "utf-8", evalScripts: false, evalResponse: false, timeout: 0, noCache: false, }, initialize: function (options) { this.xhr = new Browser.Request(); this.setOptions(options); this.headers = this.options.headers; }, onStateChange: function () { var xhr = this.xhr; if (xhr.readyState != 4 || !this.running) return; this.running = false; this.status = 0; Function.attempt( function () { var status = xhr.status; this.status = status == 1223 ? 204 : status; }.bind(this), ); xhr.onreadystatechange = empty; if (progressSupport) xhr.onprogress = xhr.onloadstart = empty; clearTimeout(this.timer); this.response = { text: this.xhr.responseText || "", xml: this.xhr.responseXML, }; if (this.options.isSuccess.call(this, this.status)) this.success(this.response.text, this.response.xml); else this.failure(); }, isSuccess: function () { var status = this.status; return status >= 200 && status < 300; }, isRunning: function () { return !!this.running; }, processScripts: function (text) { if ( this.options.evalResponse || /(ecma|java)script/.test(this.getHeader("Content-type")) ) return Browser.exec(text); return text.stripScripts(this.options.evalScripts); }, success: function (text, xml) { this.onSuccess(this.processScripts(text), xml); }, onSuccess: function () { this.fireEvent("complete", arguments) .fireEvent("success", arguments) .callChain(); }, failure: function () { this.onFailure(); }, onFailure: function () { this.fireEvent("complete").fireEvent("failure", this.xhr); }, loadstart: function (event) { this.fireEvent("loadstart", [event, this.xhr]); }, progress: function (event) { this.fireEvent("progress", [event, this.xhr]); }, timeout: function () { this.fireEvent("timeout", this.xhr); }, setHeader: function (name, value) { this.headers[name] = value; return this; }, getHeader: function (name) { return Function.attempt( function () { return this.xhr.getResponseHeader(name); }.bind(this), ); }, check: function () { if (!this.running) return true; switch (this.options.link) { case "cancel": this.cancel(); return true; case "chain": this.chain(this.caller.pass(arguments, this)); return false; } return false; }, send: function (options) { if (!this.check(options)) return this; this.options.isSuccess = this.options.isSuccess || this.isSuccess; this.running = true; var type = typeOf(options); if (type == "string" || type == "element") options = { data: options }; var old = this.options; options = Object.append( { data: old.data, url: old.url, method: old.method }, options, ); var data = options.data, url = String(options.url), method = options.method.toLowerCase(); switch (typeOf(data)) { case "element": data = document.id(data).toQueryString(); break; case "object": case "hash": data = Object.toQueryString(data); } if (this.options.format) { var format = "format=" + this.options.format; data = data ? format + "&" + data : format; } if (this.options.emulation && !["get", "post"].contains(method)) { var _method = "_method=" + method; data = data ? _method + "&" + data : _method; method = "post"; } if (this.options.urlEncoded && ["post", "put"].contains(method)) { var encoding = this.options.encoding ? "; charset=" + this.options.encoding : ""; this.headers["Content-type"] = "application/x-www-form-urlencoded" + encoding; } if (!url) url = document.location.pathname; var trimPosition = url.lastIndexOf("/"); if (trimPosition > -1 && (trimPosition = url.indexOf("#")) > -1) url = url.substr(0, trimPosition); if (this.options.noCache) url += (url.contains("?") ? "&" : "?") + String.uniqueID(); if (data && method == "get") { url += (url.contains("?") ? "&" : "?") + data; data = null; } var xhr = this.xhr; if (progressSupport) { xhr.onloadstart = this.loadstart.bind(this); xhr.onprogress = this.progress.bind(this); } xhr.open( method.toUpperCase(), url, this.options.async, this.options.user, this.options.password, ); if (this.options.user && "withCredentials" in xhr) xhr.withCredentials = true; xhr.onreadystatechange = this.onStateChange.bind(this); Object.each( this.headers, function (value, key) { try { xhr.setRequestHeader(key, value); } catch (e) { this.fireEvent("exception", [key, value]); } }, this, ); this.fireEvent("request"); xhr.send(data); if (!this.options.async) this.onStateChange(); else if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this); return this; }, cancel: function () { if (!this.running) return this; this.running = false; var xhr = this.xhr; xhr.abort(); clearTimeout(this.timer); xhr.onreadystatechange = empty; if (progressSupport) xhr.onprogress = xhr.onloadstart = empty; this.xhr = new Browser.Request(); this.fireEvent("cancel"); return this; }, })); var methods = {}; ["get", "post", "put", "delete", "GET", "POST", "PUT", "DELETE"].each( function (method) { methods[method] = function (data) { var object = { method: method, }; if (data != null) object.data = data; return this.send(object); }; }, ); Request.implement(methods); Element.Properties.send = { set: function (options) { var send = this.get("send").cancel(); send.setOptions(options); return this; }, get: function () { var send = this.retrieve("send"); if (!send) { send = new Request({ data: this, link: "cancel", method: this.get("method") || "post", url: this.get("action"), }); this.store("send", send); } return send; }, }; Element.implement({ send: function (url) { var sender = this.get("send"); sender.send({ data: this, url: url || sender.options.url }); return this; }, }); })(); /* --- name: Request.HTML description: Extends the basic Request Class with additional methods for interacting with HTML responses. license: MIT-style license. requires: [Element, Request] provides: Request.HTML ... */ Request.HTML = new Class({ Extends: Request, options: { update: false, append: false, evalScripts: true, filter: false, headers: { Accept: "text/html, application/xml, text/xml, */*", }, }, success: function (text) { var options = this.options, response = this.response; response.html = text.stripScripts(function (script) { response.javascript = script; }); var match = response.html.match(/]*>([\s\S]*?)<\/body>/i); if (match) response.html = match[1]; var temp = new Element("div").set("html", response.html); response.tree = temp.childNodes; response.elements = temp.getElements(options.filter || "*"); if (options.filter) response.tree = response.elements; if (options.update) { var update = document.id(options.update).empty(); if (options.filter) update.adopt(response.elements); else update.set("html", response.html); } else if (options.append) { var append = document.id(options.append); if (options.filter) response.elements.reverse().inject(append); else append.adopt(temp.getChildren()); } if (options.evalScripts) Browser.exec(response.javascript); this.onSuccess( response.tree, response.elements, response.html, response.javascript, ); }, }); Element.Properties.load = { set: function (options) { var load = this.get("load").cancel(); load.setOptions(options); return this; }, get: function () { var load = this.retrieve("load"); if (!load) { load = new Request.HTML({ data: this, link: "cancel", update: this, method: "get", }); this.store("load", load); } return load; }, }; Element.implement({ load: function () { this.get("load").send( Array.link(arguments, { data: Type.isObject, url: Type.isString }), ); return this; }, }); /* --- name: JSON description: JSON encoder and decoder. license: MIT-style license. SeeAlso: requires: [Array, String, Number, Function] provides: JSON ... */ if (typeof JSON == "undefined") this.JSON = {}; //<1.2compat> JSON = new Hash({ stringify: JSON.stringify, parse: JSON.parse, }); // (function () { var special = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\", }; var escape = function (chr) { return ( special[chr] || "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).slice(-4) ); }; JSON.validate = function (string) { string = string .replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") .replace( /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]", ) .replace(/(?:^|:|,)(?:\s*\[)+/g, ""); return /^[\],:{}\s]*$/.test(string); }; JSON.encode = JSON.stringify ? function (obj) { return JSON.stringify(obj); } : function (obj) { if (obj && obj.toJSON) obj = obj.toJSON(); switch (typeOf(obj)) { case "string": return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"'; case "array": return "[" + obj.map(JSON.encode).clean() + "]"; case "object": case "hash": var string = []; Object.each(obj, function (value, key) { var json = JSON.encode(value); if (json) string.push(JSON.encode(key) + ":" + json); }); return "{" + string + "}"; case "number": case "boolean": return "" + obj; case "null": return "null"; } return null; }; JSON.decode = function (string, secure) { if (!string || typeOf(string) != "string") return null; if (secure || JSON.secure) { if (JSON.parse) return JSON.parse(string); if (!JSON.validate(string)) throw new Error( "JSON could not decode the input; security is enabled and the value is not secure.", ); } return eval("(" + string + ")"); }; })(); /* --- name: Request.JSON description: Extends the basic Request Class with additional methods for sending and receiving JSON data. license: MIT-style license. requires: [Request, JSON] provides: Request.JSON ... */ Request.JSON = new Class({ Extends: Request, options: { /*onError: function(text, error){},*/ secure: true, }, initialize: function (options) { this.parent(options); Object.append(this.headers, { Accept: "application/json", "X-Request": "JSON", }); }, success: function (text) { var json; try { json = this.response.json = JSON.decode(text, this.options.secure); } catch (error) { this.fireEvent("error", [text, error]); return; } if (json == null) this.onFailure(); else this.onSuccess(json, text); }, }); /* --- name: Cookie description: Class for creating, reading, and deleting browser Cookies. license: MIT-style license. credits: - Based on the functions by Peter-Paul Koch (http://quirksmode.org). requires: [Options, Browser] provides: Cookie ... */ var Cookie = new Class({ Implements: Options, options: { path: "/", domain: false, duration: false, secure: false, document: document, encode: true, }, initialize: function (key, options) { this.key = key; this.setOptions(options); }, write: function (value) { if (this.options.encode) value = encodeURIComponent(value); if (this.options.domain) value += "; domain=" + this.options.domain; if (this.options.path) value += "; path=" + this.options.path; if (this.options.duration) { var date = new Date(); date.setTime( date.getTime() + this.options.duration * 24 * 60 * 60 * 1000, ); value += "; expires=" + date.toGMTString(); } if (this.options.secure) value += "; secure"; this.options.document.cookie = this.key + "=" + value; return this; }, read: function () { var value = this.options.document.cookie.match( "(?:^|;)\\s*" + this.key.escapeRegExp() + "=([^;]*)", ); return value ? decodeURIComponent(value[1]) : null; }, dispose: function () { new Cookie( this.key, Object.merge({}, this.options, { duration: -1 }), ).write(""); return this; }, }); Cookie.write = function (key, value, options) { return new Cookie(key, options).write(value); }; Cookie.read = function (key) { return new Cookie(key).read(); }; Cookie.dispose = function (key, options) { return new Cookie(key, options).dispose(); }; /* --- name: DOMReady description: Contains the custom event domready. license: MIT-style license. requires: [Browser, Element, Element.Event] provides: [DOMReady, DomReady] ... */ (function (window, document) { var ready, loaded, checks = [], shouldPoll, timer, testElement = document.createElement("div"); var domready = function () { clearTimeout(timer); if (ready) return; Browser.loaded = ready = true; document .removeListener("DOMContentLoaded", domready) .removeListener("readystatechange", check); document.fireEvent("domready"); window.fireEvent("domready"); }; var check = function () { for (var i = checks.length; i--; ) if (checks[i]()) { domready(); return true; } return false; }; var poll = function () { clearTimeout(timer); if (!check()) timer = setTimeout(poll, 10); }; document.addListener("DOMContentLoaded", domready); /**/ // doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/ // testElement.doScroll() throws when the DOM is not ready, only in the top window var doScrollWorks = function () { try { testElement.doScroll(); return true; } catch (e) {} return false; }; // If doScroll works already, it can't be used to determine domready // e.g. in an iframe if (testElement.doScroll && !doScrollWorks()) { checks.push(doScrollWorks); shouldPoll = true; } /**/ if (document.readyState) checks.push(function () { var state = document.readyState; return state == "loaded" || state == "complete"; }); if ("onreadystatechange" in document) document.addListener("readystatechange", check); else shouldPoll = true; if (shouldPoll) poll(); Element.Events.domready = { onAdd: function (fn) { if (ready) fn.call(this); }, }; // Make sure that domready fires before load Element.Events.load = { base: "load", onAdd: function (fn) { if (loaded && this == window) fn.call(this); }, condition: function () { if (this == window) { domready(); delete Element.Events.load; } return true; }, }; // This is based on the custom load event window.addEvent("load", function () { loaded = true; }); })(window, document); /* --- name: Swiff description: Wrapper for embedding SWF movies. Supports External Interface Communication. license: MIT-style license. credits: - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject. requires: [Options, Object, Element] provides: Swiff ... */ (function () { var Swiff = (this.Swiff = new Class({ Implements: Options, options: { id: null, height: 1, width: 1, container: null, properties: {}, params: { quality: "high", allowScriptAccess: "always", wMode: "window", swLiveConnect: true, }, callBacks: {}, vars: {}, }, toElement: function () { return this.object; }, initialize: function (path, options) { this.instance = "Swiff_" + String.uniqueID(); this.setOptions(options); options = this.options; var id = (this.id = options.id || this.instance); var container = document.id(options.container); Swiff.CallBacks[this.instance] = {}; var params = options.params, vars = options.vars, callBacks = options.callBacks; var properties = Object.append( { height: options.height, width: options.width }, options.properties, ); var self = this; for (var callBack in callBacks) { Swiff.CallBacks[this.instance][callBack] = (function (option) { return function () { return option.apply(self.object, arguments); }; })(callBacks[callBack]); vars[callBack] = "Swiff.CallBacks." + this.instance + "." + callBack; } params.flashVars = Object.toQueryString(vars); if (Browser.ie) { properties.classid = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"; params.movie = path; } else { properties.type = "application/x-shockwave-flash"; } properties.data = path; var build = ''; } build += ""; this.object = (container ? container.empty() : new Element("div")).set( "html", build, ).firstChild; }, replaces: function (element) { element = document.id(element, true); element.parentNode.replaceChild(this.toElement(), element); return this; }, inject: function (element) { document.id(element, true).appendChild(this.toElement()); return this; }, remote: function () { return Swiff.remote.apply(Swiff, [this.toElement()].append(arguments)); }, })); Swiff.CallBacks = {}; Swiff.remote = function (obj, fn) { var rs = obj.CallFunction( '' + __flash__argumentsToXML(arguments, 2) + "", ); return eval(rs); }; })();