You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

9028 lines
342 KiB

(function() {
this.MooTools = {
version: "1.5.1",
build: "0542c135fdeb7feed7d9917e01447a408f22c876"
};
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 ("callee" in item) 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;
};
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();
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 + "";
};
Function.implement({
hide: function() {
this.$hidden = true;
return this;
},
protect: function() {
this.$protected = true;
return this;
}
});
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();
}
}
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);
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", "contains", "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);
Number.prototype.$family = function() {
return isFinite(this) ? "number" : "null";
}.hide();
Number.extend("random", function(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
});
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;
}
});
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", "WhiteSpace", "TextNode", "Collection", "Arguments" ].each(function(name) {
new Type(name);
});
var UID = Date.now();
String.extend("uniqueID", function() {
return (UID++).toString(36);
});
})();
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 parseInt(value, 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("");
}
});
String.implement({
contains: function(string, index) {
return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
},
test: function(regex, params) {
return (typeOf(regex) == "regexp" ? regex : new RegExp("" + regex, params)).test(this);
},
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] : "";
});
}
});
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);
}
});
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" ]);
(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);
}
};
})();
(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);
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;
}
});
})();
(function() {
var document = this.document;
var window = document.window = this;
var parse = function(ua, platform) {
ua = ua.toLowerCase();
platform = platform ? platform.toLowerCase() : "";
var UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [ null, "unknown", 0 ];
if (UA[1] == "trident") {
UA[1] = "ie";
if (UA[4]) UA[2] = UA[4];
} else if (UA[1] == "crios") {
UA[1] = "chrome";
}
platform = ua.match(/ip(?:ad|od|hone)/) ? "ios" : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || [ "other" ])[0];
if (platform == "win") platform = "windows";
return {
extend: Function.prototype.extend,
name: UA[1] == "version" ? UA[3] : UA[1],
version: parseFloat(UA[1] == "opera" && UA[4] ? UA[4] : UA[2]),
platform: platform
};
};
var Browser = this.Browser = parse(navigator.userAgent, navigator.platform);
if (Browser.name == "ie") {
Browser.version = document.documentMode;
}
Browser.extend({
Features: {
xpath: !!document.evaluate,
air: !!window.runtime,
query: !!document.querySelector,
json: !!window.JSON
},
parseUA: parse
});
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;
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(/<script[^>]*>([\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;
});
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;
window = this.Window = document = null;
};
this.attachEvent("onunload", unloadEvent);
}
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));
};
});
}
})();
(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("&");
}
});
})();
(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) {
return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match) {
return "\\" + match;
});
};
var regexp = new RegExp("^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)".replace(/<combinator>/, "[" + escapeRegExp(">+~`!@$%^&={}\\;</") + "]").replace(/<unicode>/g, "(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])").replace(/<unicode1>/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 "";
}
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);
(function() {
var local = {}, featuresCache = {}, toString = Object.prototype.toString;
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) {
var nodeType = document.nodeType;
if (nodeType == 9) ; else if (nodeType) document = document.ownerDocument; else if (document.navigator) document = document.document; else return;
if (this.document === document) return;
this.document = document;
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);
try {
testNode.innerHTML = '<a id="' + id + '"></a>';
features.isHTMLDocument = !!document.getElementById(id);
} catch (e) {}
if (features.isHTMLDocument) {
testNode.style.display = "none";
testNode.appendChild(document.createComment(""));
starSelectsComments = testNode.getElementsByTagName("*").length > 1;
try {
testNode.innerHTML = "foo</foo>";
selected = testNode.getElementsByTagName("*");
starSelectsClosed = selected && !!selected.length && selected[0].nodeName.charAt(0) == "/";
} catch (e) {}
features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
try {
testNode.innerHTML = '<a name="' + id + '"></a><b id="' + id + '"></b>';
features.idGetsName = document.getElementById(id) === testNode.firstChild;
} catch (e) {}
if (testNode.getElementsByClassName) {
try {
testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
testNode.getElementsByClassName("b").length;
testNode.firstChild.className = "b";
cachedGetElementsByClassName = testNode.getElementsByClassName("b").length != 2;
} catch (e) {}
try {
testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
brokenSecondClassNameGEBCN = testNode.getElementsByClassName("a").length != 2;
} catch (e) {}
features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
}
if (testNode.querySelectorAll) {
try {
testNode.innerHTML = "foo</foo>";
selected = testNode.querySelectorAll("*");
features.starSelectsClosedQSA = selected && !!selected.length && selected[0].nodeName.charAt(0) == "/";
} catch (e) {}
try {
testNode.innerHTML = '<a class="MiX"></a>';
features.brokenMixedCaseQSA = !testNode.querySelectorAll(".MiX").length;
} catch (e) {}
try {
testNode.innerHTML = '<select><option selected="selected">a</option></select>';
features.brokenCheckedQSA = testNode.querySelectorAll(":checked").length == 0;
} catch (e) {}
try {
testNode.innerHTML = '<a class=""></a>';
features.brokenEmptyAttributeQSA = testNode.querySelectorAll('[class*=""]').length != 0;
} catch (e) {}
}
try {
testNode.innerHTML = '<form action="s"><input id="action"/></form>';
brokenFormAttributeGetter = testNode.firstChild.getAttribute("action") != "s";
} catch (e) {}
features.nativeMatchesSelector = root.matches || root.mozMatchesSelector || root.webkitMatchesSelector;
if (features.nativeMatchesSelector) try {
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;
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);
};
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));
};
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) {
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;
};
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];
}
};
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; else if (!context.nodeType) return found;
var parsed, i, uniques = this.uniques = {}, hasOthers = !!(append && append.length), contextIsDocument = context.nodeType == 9;
if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);
if (hasOthers) for (i = found.length; i--; ) uniques[this.getUID(found[i])] = true;
if (typeof expression == "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] || this.brokenMixedCaseQSA || this.brokenCheckedQSA && expression.indexOf(":checked") > -1 || this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression) || !contextIsDocument && expression.indexOf(",") > -1 || Slick.disableQSA) break querySelector;
var _expression = expression, _context = context;
if (!contextIsDocument) {
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) {
return found;
} else if (expression.Slick) {
parsed = expression;
} else if (this.contains(context.documentElement || context, expression)) {
found ? found.push(expression) : found = expression;
return found;
} else {
return found;
}
this.posNTH = {};
this.posNTHLast = {};
this.posNTHType = {};
this.posNTHTypeLast = {};
this.push = !hasOthers && (first || parsed.length == 1 && parsed.expressions[0].length == 1) ? this.pushArray : this.pushUID;
if (found == null) found = [];
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;
}
if (hasOthers || parsed.expressions.length > 1) this.sort(found);
return first ? found[0] || null : found;
};
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++);
};
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;
var expressions = parsed.expressions, simpleExpCounter = 0, i, currentExpression;
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;
} 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) {
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) {
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 (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) {
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) {
while (node = node.nextSibling) if (node.nodeType == 1) {
this.push(node, tag, id, classes, attributes, pseudos);
break;
}
},
"^": function(node, tag, id, classes, attributes, pseudos) {
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) {
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) {
this["combinator:+"](node, tag, id, classes, attributes, pseudos);
this["combinator:!+"](node, tag, id, classes, attributes, pseudos);
},
"~~": function(node, tag, id, classes, attributes, pseudos) {
this["combinator:~"](node, tag, id, classes, attributes, pseudos);
this["combinator:!~"](node, tag, id, classes, attributes, pseudos);
},
"!": function(node, tag, id, classes, attributes, pseudos) {
while (node = node.parentNode) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
},
"!>": function(node, tag, id, classes, attributes, pseudos) {
node = node.parentNode;
if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
},
"!+": function(node, tag, id, classes, attributes, pseudos) {
while (node = node.previousSibling) if (node.nodeType == 1) {
this.push(node, tag, id, classes, attributes, pseudos);
break;
}
},
"!^": function(node, tag, id, classes, attributes, pseudos) {
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) {
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;
},
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];
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;
var Slick = local.Slick = this.Slick || {};
Slick.version = "1.1.7";
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.contains = function(container, node) {
local.setDocument(container);
return local.contains(container, node);
};
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.match = function(node, selector) {
if (!(node && selector)) return false;
if (!selector || selector === node) return true;
local.setDocument(node);
return local.matchNode(node, selector);
};
Slick.defineAttributeGetter = function(name, fn) {
local.attributeGetters[name] = fn;
return this;
};
Slick.lookupAttributeGetter = function(name) {
return local.attributeGetters[name];
};
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.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);
var Element = this.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;
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 = {};
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()
});
(function() {
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("<input name=x>").name == "x";
} catch (e) {}
var escapeQuotes = function(html) {
return ("" + html).replace(/&/g, "&amp;").replace(/"/g, "&quot;");
};
var canChangeStyleHTML = function() {
var div = document.createElement("style"), flag = false;
try {
div.innerHTML = "#justTesing{margin: 0px;}";
flag = !!div.innerHTML;
} catch (e) {}
return flag;
}();
Document.implement({
newElement: function(tag, props) {
if (props) {
if (props.checked != null) props.defaultChecked = props.checked;
if ((props.type == "checkbox" || props.type == "radio") && props.value == null) props.value = "on";
if (!canChangeStyleHTML && tag == "style") {
var styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
if (props.type) delete props.type;
return this.id(styleElement).set(props);
}
if (createElementAcceptsHTML) {
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;
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);
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);
}
});
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);
});
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;
var propertyGetters = {}, propertySetters = {};
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];
};
});
propertySetters.text = function(setter) {
return function(node, value) {
if (node.get("tag") == "style") node.set("html", value); else node[properties.text] = value;
};
}(propertySetters.text);
propertyGetters.text = function(getter) {
return function(node) {
return node.get("tag") == "style" ? node.innerHTML : getter(node);
};
}(propertyGetters.text);
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];
};
});
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");
try {
el.type = "button";
} catch (e) {}
if (el.type != "button") propertySetters.type = function(node, value) {
node.setAttribute("type", value);
};
el = null;
var canChangeStyleHTML = function() {
var div = document.createElement("style"), flag = false;
try {
div.innerHTML = "#justTesing{margin: 0px;}";
flag = !!div.innerHTML;
} catch (e) {}
return flag;
}();
var input = document.createElement("input"), volatileInputValue, html5InputSupport;
input.value = "t";
input.type = "submit";
volatileInputValue = input.value != "t";
try {
input.type = "email";
html5InputSupport = input.type == "email";
} catch (e) {}
input = null;
if (volatileInputValue || !html5InputSupport) propertySetters.type = function(node, type) {
try {
var value = node.value;
node.type = type;
node.value = value;
} catch (e) {}
};
var pollutesGetAttribute = function(div) {
div.random = "attribute";
return div.getAttribute("random") == "attribute";
}(document.createElement("div"));
var hasCloneBug = function(test) {
test.innerHTML = '<object><param name="should_fix" value="the unknown" /></object>';
return test.cloneNode(true).firstChild.childNodes.length != 1;
}(document.createElement("div"));
var hasClassList = !!document.createElement("div").classList;
var classes = function(className) {
var classNames = (className || "").clean().split(" "), uniques = {};
return classNames.filter(function(className) {
if (className !== "" && !uniques[className]) return uniques[className] = className;
});
};
var addToClassList = function(name) {
this.classList.add(name);
};
var removeFromClassList = function(name) {
this.classList.remove(name);
};
Element.implement({
setProperty: function(name, value) {
var setter = propertySetters[name.toLowerCase()];
if (setter) {
setter(this, value);
} else {
var attributeWhiteList;
if (pollutesGetAttribute) 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;
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: hasClassList ? function(className) {
return this.classList.contains(className);
} : function(className) {
return classes(this.className).contains(className);
},
addClass: hasClassList ? function(className) {
classes(className).forEach(addToClassList, this);
return this;
} : function(className) {
this.className = classes(className + " " + this.className).join(" ");
return this;
},
removeClass: hasClassList ? function(className) {
classes(className).forEach(removeFromClassList, this);
return this;
} : function(className) {
var classNames = classes(this.className);
classes(className).forEach(classNames.erase, classNames);
this.className = classNames.join(" ");
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;
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) {
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 appendInserters = {
before: "beforeBegin",
after: "afterEnd",
bottom: "beforeEnd",
top: "afterBegin",
inside: "beforeEnd"
};
Element.implement("appendHTML", "insertAdjacentHTML" in document.createElement("div") ? function(html, where) {
this.insertAdjacentHTML(appendInserters[where || "bottom"], html);
return this;
} : function(html, where) {
var temp = new Element("div", {
html: html
}), children = temp.childNodes, fragment = temp.firstChild;
if (!fragment) return this;
if (children.length > 1) {
fragment = document.createDocumentFragment();
for (var i = 0, l = children.length; i < l; i++) {
fragment.appendChild(children[i]);
}
}
inserters[where || "bottom"](fragment, this);
return this;
});
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 (hasCloneBug) {
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 (window.attachEvent && !window.addEventListener) {
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) {
var gc = function() {
Object.each(collected, clean);
if (window.CollectGarbage) CollectGarbage();
window.removeListener("unload", gc);
};
window.addListener("unload", gc);
}
Element.Properties = {};
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("");
if (this.styleSheet && !canChangeStyleHTML) this.styleSheet.cssText = html; else this.innerHTML = html;
},
erase: function() {
this.set("html", "");
}
};
var supportsHTML5Elements = true, supportsTableInnerHTML = true, supportsTRInnerHTML = true;
var div = document.createElement("div");
div.innerHTML = "<nav></nav>";
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;
supportsTableInnerHTML = Function.attempt(function() {
var table = document.createElement("table");
table.innerHTML = "<tr><td></td></tr>";
return true;
});
var tr = document.createElement("tr"), html = "<td></td>";
tr.innerHTML = html;
supportsTRInnerHTML = tr.innerHTML == html;
tr = null;
if (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements) {
Element.Properties.html.set = function(set) {
var translations = {
table: [ 1, "<table>", "</table>" ],
select: [ 1, "<select>", "</select>" ],
tbody: [ 2, "<table><tbody>", "</tbody></table>" ],
tr: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ]
};
translations.thead = translations.tfoot = translations.tbody;
return function(html) {
if (this.styleSheet) return set.call(this, 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 = "<select><option>s</option></select>";
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");
value = String(value);
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 = "";
}
};
})();
(function() {
var _keys = {};
var normalizeWheelSpeed = function(event) {
var normalized;
if (event.wheelDelta) {
normalized = event.wheelDelta % 120 == 0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
} else {
var rawAmount = event.deltaY || event.detail || 0;
normalized = -(rawAmount % 3 == 0 ? rawAmount / 3 : rawAmount * 10);
}
return normalized;
};
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];
if (type == "keydown" || type == "keyup") {
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 == "wheel" || 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 == "wheel" || type == "mousewheel") this.wheel = normalizeWheelSpeed(event);
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"
});
})();
(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,
wheel: 2,
mousewheel: 2,
DOMMouseScroll: 2,
mouseover: 2,
mouseout: 2,
mousemove: 2,
selectstart: 2,
selectend: 2,
keydown: 2,
keypress: 2,
keyup: 2,
orientationchange: 2,
touchstart: 2,
touchmove: 2,
touchend: 2,
touchcancel: 2,
gesturestart: 2,
gesturechange: 2,
gestureend: 2,
focus: 2,
blur: 2,
change: 2,
reset: 2,
select: 2,
submit: 2,
paste: 2,
input: 2,
load: 2,
unload: 1,
beforeunload: 2,
resize: 1,
move: 1,
DOMContentLoaded: 1,
readystatechange: 1,
hashchange: 1,
popstate: 2,
error: 1,
abort: 1,
scroll: 1,
message: 2
};
Element.Events = {
mousewheel: {
base: "onwheel" in document ? "wheel" : "onmousewheel" in document ? "mousewheel" : "DOMMouseScroll"
}
};
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);
};
if ("onmouseenter" in document.documentElement) {
Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;
Element.MouseenterCheck = check;
} else {
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 event.type != "propertychange" || event.event.propertyName == "checked";
}
};
}
})();
(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",
condition: Element.MouseenterCheck
},
mouseleave: {
base: "mouseout",
condition: Element.MouseenterCheck
},
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--; ) {
if (list.forms[i].removeEvent) 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 (_map.condition || elementEvent && elementEvent.condition) {
var __match = match, condition = _map.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, _map.capture);
}
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)
});
})();
(function() {
var html = document.html, el;
el = document.createElement("div");
el.style.color = "red";
el.style.color = null;
var doesNotRemoveStyles = el.style.color == "red";
var border = "1px solid #123abc";
el.style.border = border;
var returnsBordersInWrongOrder = el.style.border != border;
el = null;
var hasGetComputedStyle = !!window.getComputedStyle, supportBorderRadius = document.createElement("div").style.borderRadius != 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 setFilter = function(element, regexp, value) {
var style = element.style, filter = style.filter || element.getComputedStyle("filter") || "";
style.filter = (regexp.test(filter) ? filter.replace(regexp, value) : filter + " " + value).trim();
if (!style.filter) style.removeAttribute("filter");
};
var setOpacity = hasOpacity ? function(element, opacity) {
element.style.opacity = opacity;
} : hasFilter ? function(element, opacity) {
if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
if (opacity == null || opacity == 1) {
setFilter(element, reAlpha, "");
if (opacity == 1 && getOpacity(element) != 1) setFilter(element, reAlpha, "alpha(opacity=100)");
} else {
setFilter(element, reAlpha, "alpha(opacity=" + (opacity * 100).limit(0, 100).round() + ")");
}
} : 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", namedPositions = {
left: "0%",
top: "0%",
center: "50%",
right: "100%",
bottom: "100%"
}, hasBackgroundPositionXY = html.style.backgroundPositionX != null;
var removeStyle = function(style, property) {
if (property == "backgroundPosition") {
style.removeAttribute(property + "X");
property += "Y";
}
style.removeAttribute(property);
};
Element.implement({
getComputedStyle: function(property) {
if (!hasGetComputedStyle && 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()) : "";
},
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) {
removeStyle(this.style, property);
}
return this;
},
getStyle: function(property) {
if (property == "opacity") return getOpacity(this);
property = (property == "float" ? floatName : property).camelCase();
if (supportBorderRadius && property.indexOf("borderRadius") != -1) {
return [ "borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius" ].map(function(corner) {
return this.style[corner] || "0px";
}, this).join(" ");
}
var result = this.style[property];
if (!result || property == "zIndex") {
if (Element.ShortStyles.hasOwnProperty(property)) {
result = [];
for (var s in Element.ShortStyles[property]) result.push(this.getStyle(s));
return result.join(" ");
}
result = this.getComputedStyle(property);
}
if (hasBackgroundPositionXY && /^backgroundPosition[XY]?$/.test(property)) {
return result.replace(/(top|right|bottom|left)/g, function(position) {
return namedPositions[position];
}) || "0px";
}
if (!result && property == "backgroundPosition") return "0px 0px";
if (result) {
result = String(result);
var color = result.match(/rgba?\([\d\s,]+\)/);
if (color) result = result.replace(color[0], color[0].rgbToHex());
}
if (!hasGetComputedStyle && !this.style[property]) {
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 (/^border(.+)Width|margin|padding/.test(property) && isNaN(parseFloat(result))) {
return "0px";
}
}
if (returnsBordersInWrongOrder && /^border(Top|Right|Bottom|Left)?$/.test(property) && /^#/.test(result)) {
return result.replace(/^(.+)\s(.+)\s(.+)$/, "$2 $3 $1");
}
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(@, @, @)",
backgroundSize: "@px",
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: "@",
borderRadius: "@px @px @px @px"
};
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(@, @, @)";
});
if (hasBackgroundPositionXY) Element.ShortStyles.backgroundPosition = {
backgroundPositionX: "@",
backgroundPositionY: "@"
};
})();
(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 heightComponents = [ "height", "paddingTop", "paddingBottom", "borderTopWidth", "borderBottomWidth" ], widthComponents = [ "width", "paddingLeft", "paddingRight", "borderLeftWidth", "borderRightWidth" ];
var svgCalculateSize = function(el) {
var gCS = window.getComputedStyle(el), bounds = {
x: 0,
y: 0
};
heightComponents.each(function(css) {
bounds.y += parseFloat(gCS[css]);
});
widthComponents.each(function(css) {
bounds.x += parseFloat(gCS[css]);
});
return bounds;
};
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();
if (!window.getComputedStyle) return {
x: this.offsetWidth,
y: this.offsetHeight
};
if (this.get("tag") == "svg") return svgCalculateSize(this);
var bounds = this.getBoundingClientRect();
return {
x: bounds.width,
y: bounds.height
};
},
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() {
var hasGetBoundingClientRect = this.getBoundingClientRect;
if (hasGetBoundingClientRect) {
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;
element = element.offsetParent;
}
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
};
}
});
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;
}
})();
Element.alias({
position: "setPosition"
});
[ 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;
}
});
(function() {
var Fx = this.Fx = new Class({
Implements: [ Chain, Events, Options ],
options: {
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 = 1e3 / 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.isPaused()) pushInstance.call(this, this.options.fps);
return this;
},
isRunning: function() {
var list = instances[this.options.fps];
return list && list.contains(this);
},
isPaused: function() {
return this.frame < this.frames && !this.isRunning();
}
});
Fx.compute = function(from, to, delta) {
return (to - from) * delta + from;
};
Fx.Durations = {
short: 250,
normal: 500,
long: 1e3
};
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(1e3 / 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]);
}
}
};
})();
Fx.CSS = new Class({
Extends: Fx,
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;
if (unit && from && typeof from == "string" && from.slice(-unit.length) != unit && parseFloat(from) != 0) {
element.setStyle(property, to + unit);
var value = element.getComputedStyle(property);
if (!/px$/.test(value)) {
value = element.style[("pixel-" + property).camelCase()];
if (value == null) {
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)
};
},
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;
});
},
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;
},
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;
},
render: function(element, property, value, unit) {
element.setStyle(property, this.serve(value, unit));
},
search: function(selector) {
if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
var to = {}, selectorTest = new RegExp("^" + selector.escapeRegExp() + "$");
var searchStyles = function(rules) {
Array.each(rules, function(rule, i) {
if (rule.media) {
searchStyles(rule.rules || rule.cssRules);
return;
}
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;
});
});
};
Array.each(document.styleSheets, function(sheet, j) {
var href = sheet.href;
if (href && href.indexOf("://") > -1 && href.indexOf(document.domain) == -1) return;
var rules = sheet.rules || sheet.cssRules;
searchStyles(rules);
});
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;
}
}
};
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;
}
});
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 <= .5 ? transition(2 * pos, params) : 2 - transition(2 * (1 - pos), params)) / 2;
}
});
};
Fx.Transitions = {
linear: function(zero) {
return zero;
}
};
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);
});
});
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;
}
});
(function() {
var empty = function() {}, progressSupport = "onprogress" in new Browser.Request();
var Request = this.Request = new Class({
Implements: [ Chain, Events, Options ],
options: {
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;
if (this.timer) {
clearTimeout(this.timer);
delete 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.indexOf("?") > -1 ? "&" : "?") + String.uniqueID();
if (data && (method == "get" || method == "delete")) {
url += (url.indexOf("?") > -1 ? "&" : "?") + 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.withCredentials && "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();
if (this.timer) {
clearTimeout(this.timer);
delete 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", "patch", "head", "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD" ].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;
}
});
})();
if (typeof JSON == "undefined") this.JSON = {};
(function() {
var special = {
"\b": "\\b",
" ": "\\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.secure = true;
JSON.decode = function(string, secure) {
if (!string || typeOf(string) != "string") return null;
if (secure == null) secure = JSON.secure;
if (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 + ")");
};
})();
Request.JSON = new Class({
Extends: Request,
options: {
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);
}
});
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 * 1e3);
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();
};
(function(window, document) {
var ready, loaded, checks = [], shouldPoll, timer, testElement = document.createElement("div");
var domready = function() {
clearTimeout(timer);
if (!ready) {
Browser.loaded = ready = true;
document.removeListener("DOMContentLoaded", domready).removeListener("readystatechange", check);
document.fireEvent("domready");
window.fireEvent("domready");
}
document = window = testElement = null;
};
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);
var doScrollWorks = function() {
try {
testElement.doScroll();
return true;
} catch (e) {}
return false;
};
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);
}
};
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;
}
};
window.addEvent("load", function() {
loaded = true;
});
})(window, document);
MooTools.More = {
version: "1.5.1",
build: "2dd695ba957196ae4b0275a690765d6636a61ccd"
};
(function() {
Events.Pseudos = function(pseudos, addEvent, removeEvent) {
var storeKey = "_monitorEvents:";
var storageOf = function(object) {
return {
store: object.store ? function(key, value) {
object.store(storeKey + key, value);
} : function(key, value) {
(object._monitorEvents || (object._monitorEvents = {}))[key] = value;
},
retrieve: object.retrieve ? function(key, dflt) {
return object.retrieve(storeKey + key, dflt);
} : function(key, dflt) {
if (!object._monitorEvents) return dflt;
return object._monitorEvents[key] || dflt;
}
};
};
var splitType = function(type) {
if (type.indexOf(":") == -1 || !pseudos) return null;
var parsed = Slick.parse(type).expressions[0][0], parsedPseudos = parsed.pseudos, l = parsedPseudos.length, splits = [];
while (l--) {
var pseudo = parsedPseudos[l].key, listener = pseudos[pseudo];
if (listener != null) splits.push({
event: parsed.tag,
value: parsedPseudos[l].value,
pseudo: pseudo,
original: type,
listener: listener
});
}
return splits.length ? splits : null;
};
return {
addEvent: function(type, fn, internal) {
var split = splitType(type);
if (!split) return addEvent.call(this, type, fn, internal);
var storage = storageOf(this), events = storage.retrieve(type, []), eventType = split[0].event, args = Array.slice(arguments, 2), stack = fn, self = this;
split.each(function(item) {
var listener = item.listener, stackFn = stack;
if (listener == false) eventType += ":" + item.pseudo + "(" + item.value + ")"; else stack = function() {
listener.call(self, item, stackFn, arguments, stack);
};
});
events.include({
type: eventType,
event: fn,
monitor: stack
});
storage.store(type, events);
if (type != eventType) addEvent.apply(this, [ type, fn ].concat(args));
return addEvent.apply(this, [ eventType, stack ].concat(args));
},
removeEvent: function(type, fn) {
var split = splitType(type);
if (!split) return removeEvent.call(this, type, fn);
var storage = storageOf(this), events = storage.retrieve(type);
if (!events) return this;
var args = Array.slice(arguments, 2);
removeEvent.apply(this, [ type, fn ].concat(args));
events.each(function(monitor, i) {
if (!fn || monitor.event == fn) removeEvent.apply(this, [ monitor.type, monitor.monitor ].concat(args));
delete events[i];
}, this);
storage.store(type, events);
return this;
}
};
};
var pseudos = {
once: function(split, fn, args, monitor) {
fn.apply(this, args);
this.removeEvent(split.event, monitor).removeEvent(split.original, fn);
},
throttle: function(split, fn, args) {
if (!fn._throttled) {
fn.apply(this, args);
fn._throttled = setTimeout(function() {
fn._throttled = false;
}, split.value || 250);
}
},
pause: function(split, fn, args) {
clearTimeout(fn._pause);
fn._pause = fn.delay(split.value || 250, this, args);
}
};
Events.definePseudo = function(key, listener) {
pseudos[key] = listener;
return this;
};
Events.lookupPseudo = function(key) {
return pseudos[key];
};
var proto = Events.prototype;
Events.implement(Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));
[ "Request", "Fx" ].each(function(klass) {
if (this[klass]) this[klass].implement(Events.prototype);
});
})();
var Drag = new Class({
Implements: [ Events, Options ],
options: {
snap: 6,
unit: "px",
grid: false,
style: true,
limit: false,
handle: false,
invert: false,
preventDefault: false,
stopPropagation: false,
compensateScroll: false,
modifiers: {
x: "left",
y: "top"
}
},
initialize: function() {
var params = Array.link(arguments, {
options: Type.isObject,
element: function(obj) {
return obj != null;
}
});
this.element = document.id(params.element);
this.document = this.element.getDocument();
this.setOptions(params.options || {});
var htype = typeOf(this.options.handle);
this.handles = (htype == "array" || htype == "collection" ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
this.mouse = {
now: {},
pos: {}
};
this.value = {
start: {},
now: {}
};
this.offsetParent = function(el) {
var offsetParent = el.getOffsetParent();
var isBody = !offsetParent || /^(?:body|html)$/i.test(offsetParent.tagName);
return isBody ? window : document.id(offsetParent);
}(this.element);
this.selection = "selectstart" in document ? "selectstart" : "mousedown";
this.compensateScroll = {
start: {},
diff: {},
last: {}
};
if ("ondragstart" in document && !("FileReader" in window) && !Drag.ondragstartFixed) {
document.ondragstart = Function.from(false);
Drag.ondragstartFixed = true;
}
this.bound = {
start: this.start.bind(this),
check: this.check.bind(this),
drag: this.drag.bind(this),
stop: this.stop.bind(this),
cancel: this.cancel.bind(this),
eventStop: Function.from(false),
scrollListener: this.scrollListener.bind(this)
};
this.attach();
},
attach: function() {
this.handles.addEvent("mousedown", this.bound.start);
if (this.options.compensateScroll) this.offsetParent.addEvent("scroll", this.bound.scrollListener);
return this;
},
detach: function() {
this.handles.removeEvent("mousedown", this.bound.start);
if (this.options.compensateScroll) this.offsetParent.removeEvent("scroll", this.bound.scrollListener);
return this;
},
scrollListener: function() {
if (!this.mouse.start) return;
var newScrollValue = this.offsetParent.getScroll();
if (this.element.getStyle("position") == "absolute") {
var scrollDiff = this.sumValues(newScrollValue, this.compensateScroll.last, -1);
this.mouse.now = this.sumValues(this.mouse.now, scrollDiff, 1);
} else {
this.compensateScroll.diff = this.sumValues(newScrollValue, this.compensateScroll.start, -1);
}
if (this.offsetParent != window) this.compensateScroll.diff = this.sumValues(this.compensateScroll.start, newScrollValue, -1);
this.compensateScroll.last = newScrollValue;
this.render(this.options);
},
sumValues: function(alpha, beta, op) {
var sum = {}, options = this.options;
for (z in options.modifiers) {
if (!options.modifiers[z]) continue;
sum[z] = alpha[z] + beta[z] * op;
}
return sum;
},
start: function(event) {
var options = this.options;
if (event.rightClick) return;
if (options.preventDefault) event.preventDefault();
if (options.stopPropagation) event.stopPropagation();
this.compensateScroll.start = this.compensateScroll.last = this.offsetParent.getScroll();
this.compensateScroll.diff = {
x: 0,
y: 0
};
this.mouse.start = event.page;
this.fireEvent("beforeStart", this.element);
var limit = options.limit;
this.limit = {
x: [],
y: []
};
var z, coordinates, offsetParent = this.offsetParent == window ? null : this.offsetParent;
for (z in options.modifiers) {
if (!options.modifiers[z]) continue;
var style = this.element.getStyle(options.modifiers[z]);
if (style && !style.match(/px$/)) {
if (!coordinates) coordinates = this.element.getCoordinates(offsetParent);
style = coordinates[options.modifiers[z]];
}
if (options.style) this.value.now[z] = (style || 0).toInt(); else this.value.now[z] = this.element[options.modifiers[z]];
if (options.invert) this.value.now[z] *= -1;
this.mouse.pos[z] = event.page[z] - this.value.now[z];
if (limit && limit[z]) {
var i = 2;
while (i--) {
var limitZI = limit[z][i];
if (limitZI || limitZI === 0) this.limit[z][i] = typeof limitZI == "function" ? limitZI() : limitZI;
}
}
}
if (typeOf(this.options.grid) == "number") this.options.grid = {
x: this.options.grid,
y: this.options.grid
};
var events = {
mousemove: this.bound.check,
mouseup: this.bound.cancel
};
events[this.selection] = this.bound.eventStop;
this.document.addEvents(events);
},
check: function(event) {
if (this.options.preventDefault) event.preventDefault();
var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
if (distance > this.options.snap) {
this.cancel();
this.document.addEvents({
mousemove: this.bound.drag,
mouseup: this.bound.stop
});
this.fireEvent("start", [ this.element, event ]).fireEvent("snap", this.element);
}
},
drag: function(event) {
var options = this.options;
if (options.preventDefault) event.preventDefault();
this.mouse.now = this.sumValues(event.page, this.compensateScroll.diff, -1);
this.render(options);
this.fireEvent("drag", [ this.element, event ]);
},
render: function(options) {
for (var z in options.modifiers) {
if (!options.modifiers[z]) continue;
this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
if (options.invert) this.value.now[z] *= -1;
if (options.limit && this.limit[z]) {
if ((this.limit[z][1] || this.limit[z][1] === 0) && this.value.now[z] > this.limit[z][1]) {
this.value.now[z] = this.limit[z][1];
} else if ((this.limit[z][0] || this.limit[z][0] === 0) && this.value.now[z] < this.limit[z][0]) {
this.value.now[z] = this.limit[z][0];
}
}
if (options.grid[z]) this.value.now[z] -= (this.value.now[z] - (this.limit[z][0] || 0)) % options.grid[z];
if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit); else this.element[options.modifiers[z]] = this.value.now[z];
}
},
cancel: function(event) {
this.document.removeEvents({
mousemove: this.bound.check,
mouseup: this.bound.cancel
});
if (event) {
this.document.removeEvent(this.selection, this.bound.eventStop);
this.fireEvent("cancel", this.element);
}
},
stop: function(event) {
var events = {
mousemove: this.bound.drag,
mouseup: this.bound.stop
};
events[this.selection] = this.bound.eventStop;
this.document.removeEvents(events);
this.mouse.start = null;
if (event) this.fireEvent("complete", [ this.element, event ]);
}
});
Element.implement({
makeResizable: function(options) {
var drag = new Drag(this, Object.merge({
modifiers: {
x: "width",
y: "height"
}
}, options));
this.store("resizer", drag);
return drag.addEvent("drag", function() {
this.fireEvent("resize", drag);
}.bind(this));
}
});
Drag.Move = new Class({
Extends: Drag,
options: {
droppables: [],
container: false,
precalculate: false,
includeMargins: true,
checkDroppables: true
},
initialize: function(element, options) {
this.parent(element, options);
element = this.element;
this.droppables = $$(this.options.droppables);
this.setContainer(this.options.container);
if (this.options.style) {
if (this.options.modifiers.x == "left" && this.options.modifiers.y == "top") {
var parent = element.getOffsetParent(), styles = element.getStyles("left", "top");
if (parent && (styles.left == "auto" || styles.top == "auto")) {
element.setPosition(element.getPosition(parent));
}
}
if (element.getStyle("position") == "static") element.setStyle("position", "absolute");
}
this.addEvent("start", this.checkDroppables, true);
this.overed = null;
},
setContainer: function(container) {
this.container = document.id(container);
if (this.container && typeOf(this.container) != "element") {
this.container = document.id(this.container.getDocument().body);
}
},
start: function(event) {
if (this.container) this.options.limit = this.calculateLimit();
if (this.options.precalculate) {
this.positions = this.droppables.map(function(el) {
return el.getCoordinates();
});
}
this.parent(event);
},
calculateLimit: function() {
var element = this.element, container = this.container, offsetParent = document.id(element.getOffsetParent()) || document.body, containerCoordinates = container.getCoordinates(offsetParent), elementMargin = {}, elementBorder = {}, containerMargin = {}, containerBorder = {}, offsetParentPadding = {}, offsetScroll = offsetParent.getScroll();
[ "top", "right", "bottom", "left" ].each(function(pad) {
elementMargin[pad] = element.getStyle("margin-" + pad).toInt();
elementBorder[pad] = element.getStyle("border-" + pad).toInt();
containerMargin[pad] = container.getStyle("margin-" + pad).toInt();
containerBorder[pad] = container.getStyle("border-" + pad).toInt();
offsetParentPadding[pad] = offsetParent.getStyle("padding-" + pad).toInt();
}, this);
var width = element.offsetWidth + elementMargin.left + elementMargin.right, height = element.offsetHeight + elementMargin.top + elementMargin.bottom, left = 0 + offsetScroll.x, top = 0 + offsetScroll.y, right = containerCoordinates.right - containerBorder.right - width + offsetScroll.x, bottom = containerCoordinates.bottom - containerBorder.bottom - height + offsetScroll.y;
if (this.options.includeMargins) {
left += elementMargin.left;
top += elementMargin.top;
} else {
right += elementMargin.right;
bottom += elementMargin.bottom;
}
if (element.getStyle("position") == "relative") {
var coords = element.getCoordinates(offsetParent);
coords.left -= element.getStyle("left").toInt();
coords.top -= element.getStyle("top").toInt();
left -= coords.left;
top -= coords.top;
if (container.getStyle("position") != "relative") {
left += containerBorder.left;
top += containerBorder.top;
}
right += elementMargin.left - coords.left;
bottom += elementMargin.top - coords.top;
if (container != offsetParent) {
left += containerMargin.left + offsetParentPadding.left;
if (!offsetParentPadding.left && left < 0) left = 0;
top += offsetParent == document.body ? 0 : containerMargin.top + offsetParentPadding.top;
if (!offsetParentPadding.top && top < 0) top = 0;
}
} else {
left -= elementMargin.left;
top -= elementMargin.top;
if (container != offsetParent) {
left += containerCoordinates.left + containerBorder.left;
top += containerCoordinates.top + containerBorder.top;
}
}
return {
x: [ left, right ],
y: [ top, bottom ]
};
},
getDroppableCoordinates: function(element) {
var position = element.getCoordinates();
if (element.getStyle("position") == "fixed") {
var scroll = window.getScroll();
position.left += scroll.x;
position.right += scroll.x;
position.top += scroll.y;
position.bottom += scroll.y;
}
return position;
},
checkDroppables: function() {
var overed = this.droppables.filter(function(el, i) {
el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);
var now = this.mouse.now;
return now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top;
}, this).getLast();
if (this.overed != overed) {
if (this.overed) this.fireEvent("leave", [ this.element, this.overed ]);
if (overed) this.fireEvent("enter", [ this.element, overed ]);
this.overed = overed;
}
},
drag: function(event) {
this.parent(event);
if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
},
stop: function(event) {
this.checkDroppables();
this.fireEvent("drop", [ this.element, this.overed, event ]);
this.overed = null;
return this.parent(event);
}
});
Element.implement({
makeDraggable: function(options) {
var drag = new Drag.Move(this, options);
this.store("dragger", drag);
return drag;
}
});
var Sortables = new Class({
Implements: [ Events, Options ],
options: {
opacity: 1,
clone: false,
revert: false,
handle: false,
dragOptions: {},
unDraggableTags: [ "button", "input", "a", "textarea", "select", "option" ]
},
initialize: function(lists, options) {
this.setOptions(options);
this.elements = [];
this.lists = [];
this.idle = true;
this.addLists($$(document.id(lists) || lists));
if (!this.options.clone) this.options.revert = false;
if (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({
duration: 250,
link: "cancel"
}, this.options.revert));
},
attach: function() {
this.addLists(this.lists);
return this;
},
detach: function() {
this.lists = this.removeLists(this.lists);
return this;
},
addItems: function() {
Array.flatten(arguments).each(function(element) {
this.elements.push(element);
var start = element.retrieve("sortables:start", function(event) {
this.start.call(this, event, element);
}.bind(this));
(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent("mousedown", start);
}, this);
return this;
},
addLists: function() {
Array.flatten(arguments).each(function(list) {
this.lists.include(list);
this.addItems(list.getChildren());
}, this);
return this;
},
removeItems: function() {
return $$(Array.flatten(arguments).map(function(element) {
this.elements.erase(element);
var start = element.retrieve("sortables:start");
(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent("mousedown", start);
return element;
}, this));
},
removeLists: function() {
return $$(Array.flatten(arguments).map(function(list) {
this.lists.erase(list);
this.removeItems(list.getChildren());
return list;
}, this));
},
getDroppableCoordinates: function(element) {
var offsetParent = element.getOffsetParent();
var position = element.getPosition(offsetParent);
var scroll = {
w: window.getScroll(),
offsetParent: offsetParent.getScroll()
};
position.x += scroll.offsetParent.x;
position.y += scroll.offsetParent.y;
if (offsetParent.getStyle("position") == "fixed") {
position.x -= scroll.w.x;
position.y -= scroll.w.y;
}
return position;
},
getClone: function(event, element) {
if (!this.options.clone) return new Element(element.tagName).inject(document.body);
if (typeOf(this.options.clone) == "function") return this.options.clone.call(this, event, element, this.list);
var clone = element.clone(true).setStyles({
margin: 0,
position: "absolute",
visibility: "hidden",
width: element.getStyle("width")
}).addEvent("mousedown", function(event) {
element.fireEvent("mousedown", event);
});
if (clone.get("html").test("radio")) {
clone.getElements("input[type=radio]").each(function(input, i) {
input.set("name", "clone_" + i);
if (input.get("checked")) element.getElements("input[type=radio]")[i].set("checked", true);
});
}
return clone.inject(this.list).setPosition(this.getDroppableCoordinates(this.element));
},
getDroppables: function() {
var droppables = this.list.getChildren().erase(this.clone).erase(this.element);
if (!this.options.constrain) droppables.append(this.lists).erase(this.list);
return droppables;
},
insert: function(dragging, element) {
var where = "inside";
if (this.lists.contains(element)) {
this.list = element;
this.drag.droppables = this.getDroppables();
} else {
where = this.element.getAllPrevious().contains(element) ? "before" : "after";
}
this.element.inject(element, where);
this.fireEvent("sort", [ this.element, this.clone ]);
},
start: function(event, element) {
if (!this.idle || event.rightClick || !this.options.handle && this.options.unDraggableTags.contains(event.target.get("tag"))) return;
this.idle = false;
this.element = element;
this.opacity = element.getStyle("opacity");
this.list = element.getParent();
this.clone = this.getClone(event, element);
this.drag = new Drag.Move(this.clone, Object.merge({
droppables: this.getDroppables()
}, this.options.dragOptions)).addEvents({
onSnap: function() {
event.stop();
this.clone.setStyle("visibility", "visible");
this.element.setStyle("opacity", this.options.opacity || 0);
this.fireEvent("start", [ this.element, this.clone ]);
}.bind(this),
onEnter: this.insert.bind(this),
onCancel: this.end.bind(this),
onComplete: this.end.bind(this)
});
this.clone.inject(this.element, "before");
this.drag.start(event);
},
end: function() {
this.drag.detach();
this.element.setStyle("opacity", this.opacity);
var self = this;
if (this.effect) {
var dim = this.element.getStyles("width", "height"), clone = this.clone, pos = clone.computePosition(this.getDroppableCoordinates(clone));
var destroy = function() {
this.removeEvent("cancel", destroy);
clone.destroy();
self.reset();
};
this.effect.element = clone;
this.effect.start({
top: pos.top,
left: pos.left,
width: dim.width,
height: dim.height,
opacity: .25
}).addEvent("cancel", destroy).chain(destroy);
} else {
this.clone.destroy();
self.reset();
}
},
reset: function() {
this.idle = true;
this.fireEvent("complete", this.element);
},
serialize: function() {
var params = Array.link(arguments, {
modifier: Type.isFunction,
index: function(obj) {
return obj != null;
}
});
var serial = this.lists.map(function(list) {
return list.getChildren().map(params.modifier || function(element) {
return element.get("id");
}, this);
}, this);
var index = params.index;
if (this.lists.length == 1) index = 0;
return (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;
}
});
(function() {
var special = {
a: /[àáâãäåăą]/g,
A: /[ÀÁÂÃÄÅĂĄ]/g,
c: /[ćčç]/g,
C: /[ĆČÇ]/g,
d: /[ďđ]/g,
D: /[ĎÐ]/g,
e: /[èéêëěę]/g,
E: /[ÈÉÊËĚĘ]/g,
g: /[ğ]/g,
G: /[Ğ]/g,
i: /[ìíîï]/g,
I: /[ÌÍÎÏ]/g,
l: /[ĺľł]/g,
L: /[ĹĽŁ]/g,
n: /[ñňń]/g,
N: /[ÑŇŃ]/g,
o: /[òóôõöøő]/g,
O: /[ÒÓÔÕÖØ]/g,
r: /[řŕ]/g,
R: /[ŘŔ]/g,
s: /[ššş]/g,
S: /[ŠŞŚ]/g,
t: /[ťţ]/g,
T: /[ŤŢ]/g,
u: /[ùúûůüµ]/g,
U: /[ÙÚÛŮÜ]/g,
y: /[ÿý]/g,
Y: /[ŸÝ]/g,
z: /[žźż]/g,
Z: /[ŽŹŻ]/g,
th: /[þ]/g,
TH: /[Þ]/g,
dh: /[ð]/g,
DH: /[Ð]/g,
ss: /[ß]/g,
oe: /[œ]/g,
OE: /[Œ]/g,
ae: /[æ]/g,
AE: /[Æ]/g
}, tidy = {
" ": /[\xa0\u2002\u2003\u2009]/g,
"*": /[\xb7]/g,
"'": /[\u2018\u2019]/g,
'"': /[\u201c\u201d]/g,
"...": /[\u2026]/g,
"-": /[\u2013]/g,
"&raquo;": /[\uFFFD]/g
}, conversions = {
ms: 1,
s: 1e3,
m: 6e4,
h: 36e5
}, findUnits = /(\d*.?\d+)([msh]+)/;
var walk = function(string, replacements) {
var result = string, key;
for (key in replacements) result = result.replace(replacements[key], key);
return result;
};
var getRegexForTag = function(tag, contents) {
tag = tag || "";
var regstr = contents ? "<" + tag + "(?!\\w)[^>]*>([\\s\\S]*?)</" + tag + "(?!\\w)>" : "</?" + tag + "([^>]+)?>", reg = new RegExp(regstr, "gi");
return reg;
};
String.implement({
standardize: function() {
return walk(this, special);
},
repeat: function(times) {
return new Array(times + 1).join(this);
},
pad: function(length, str, direction) {
if (this.length >= length) return this;
var pad = (str == null ? " " : "" + str).repeat(length - this.length).substr(0, length - this.length);
if (!direction || direction == "right") return this + pad;
if (direction == "left") return pad + this;
return pad.substr(0, (pad.length / 2).floor()) + this + pad.substr(0, (pad.length / 2).ceil());
},
getTags: function(tag, contents) {
return this.match(getRegexForTag(tag, contents)) || [];
},
stripTags: function(tag, contents) {
return this.replace(getRegexForTag(tag, contents), "");
},
tidy: function() {
return walk(this, tidy);
},
truncate: function(max, trail, atChar) {
var string = this;
if (trail == null && arguments.length == 1) trail = "…";
if (string.length > max) {
string = string.substring(0, max);
if (atChar) {
var index = string.lastIndexOf(atChar);
if (index != -1) string = string.substr(0, index);
}
if (trail) string += trail;
}
return string;
},
ms: function() {
var units = findUnits.exec(this);
if (units == null) return Number(this);
return Number(units[1]) * conversions[units[2]];
}
});
})();
Element.implement({
tidy: function() {
this.set("value", this.get("value").tidy());
},
getTextInRange: function(start, end) {
return this.get("value").substring(start, end);
},
getSelectedText: function() {
if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());
return document.selection.createRange().text;
},
getSelectedRange: function() {
if (this.selectionStart != null) {
return {
start: this.selectionStart,
end: this.selectionEnd
};
}
var pos = {
start: 0,
end: 0
};
var range = this.getDocument().selection.createRange();
if (!range || range.parentElement() != this) return pos;
var duplicate = range.duplicate();
if (this.type == "text") {
pos.start = 0 - duplicate.moveStart("character", -1e5);
pos.end = pos.start + range.text.length;
} else {
var value = this.get("value");
var offset = value.length;
duplicate.moveToElementText(this);
duplicate.setEndPoint("StartToEnd", range);
if (duplicate.text.length) offset -= value.match(/[\n\r]*$/)[0].length;
pos.end = offset - duplicate.text.length;
duplicate.setEndPoint("StartToStart", range);
pos.start = offset - duplicate.text.length;
}
return pos;
},
getSelectionStart: function() {
return this.getSelectedRange().start;
},
getSelectionEnd: function() {
return this.getSelectedRange().end;
},
setCaretPosition: function(pos) {
if (pos == "end") pos = this.get("value").length;
this.selectRange(pos, pos);
return this;
},
getCaretPosition: function() {
return this.getSelectedRange().start;
},
selectRange: function(start, end) {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else {
var value = this.get("value");
var diff = value.substr(start, end - start).replace(/\r/g, "").length;
start = value.substr(0, start).replace(/\r/g, "").length;
var range = this.createTextRange();
range.collapse(true);
range.moveEnd("character", start + diff);
range.moveStart("character", start);
range.select();
}
return this;
},
insertAtCursor: function(value, select) {
var pos = this.getSelectedRange();
var text = this.get("value");
this.set("value", text.substring(0, pos.start) + value + text.substring(pos.end, text.length));
if (select !== false) this.selectRange(pos.start, pos.start + value.length); else this.setCaretPosition(pos.start + value.length);
return this;
},
insertAroundCursor: function(options, select) {
options = Object.append({
before: "",
defaultMiddle: "",
after: ""
}, options);
var value = this.getSelectedText() || options.defaultMiddle;
var pos = this.getSelectedRange();
var text = this.get("value");
if (pos.start == pos.end) {
this.set("value", text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length));
this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);
} else {
var current = text.substring(pos.start, pos.end);
this.set("value", text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length));
var selStart = pos.start + options.before.length;
if (select !== false) this.selectRange(selStart, selStart + current.length); else this.setCaretPosition(selStart + text.length);
}
return this;
}
});
(function() {
var getStylesList = function(styles, planes) {
var list = [];
Object.each(planes, function(directions) {
Object.each(directions, function(edge) {
styles.each(function(style) {
list.push(style + "-" + edge + (style == "border" ? "-width" : ""));
});
});
});
return list;
};
var calculateEdgeSize = function(edge, styles) {
var total = 0;
Object.each(styles, function(value, style) {
if (style.test(edge)) total = total + value.toInt();
});
return total;
};
var isVisible = function(el) {
return !!(!el || el.offsetHeight || el.offsetWidth);
};
Element.implement({
measure: function(fn) {
if (isVisible(this)) return fn.call(this);
var parent = this.getParent(), toMeasure = [];
while (!isVisible(parent) && parent != document.body) {
toMeasure.push(parent.expose());
parent = parent.getParent();
}
var restore = this.expose(), result = fn.call(this);
restore();
toMeasure.each(function(restore) {
restore();
});
return result;
},
expose: function() {
if (this.getStyle("display") != "none") return function() {};
var before = this.style.cssText;
this.setStyles({
display: "block",
position: "absolute",
visibility: "hidden"
});
return function() {
this.style.cssText = before;
}.bind(this);
},
getDimensions: function(options) {
options = Object.merge({
computeSize: false
}, options);
var dim = {
x: 0,
y: 0
};
var getSize = function(el, options) {
return options.computeSize ? el.getComputedSize(options) : el.getSize();
};
var parent = this.getParent("body");
if (parent && this.getStyle("display") == "none") {
dim = this.measure(function() {
return getSize(this, options);
});
} else if (parent) {
try {
dim = getSize(this, options);
} catch (e) {}
}
return Object.append(dim, dim.x || dim.x === 0 ? {
width: dim.x,
height: dim.y
} : {
x: dim.width,
y: dim.height
});
},
getComputedSize: function(options) {
options = Object.merge({
styles: [ "padding", "border" ],
planes: {
height: [ "top", "bottom" ],
width: [ "left", "right" ]
},
mode: "both"
}, options);
var styles = {}, size = {
width: 0,
height: 0
}, dimensions;
if (options.mode == "vertical") {
delete size.width;
delete options.planes.width;
} else if (options.mode == "horizontal") {
delete size.height;
delete options.planes.height;
}
getStylesList(options.styles, options.planes).each(function(style) {
styles[style] = this.getStyle(style).toInt();
}, this);
Object.each(options.planes, function(edges, plane) {
var capitalized = plane.capitalize(), style = this.getStyle(plane);
if (style == "auto" && !dimensions) dimensions = this.getDimensions();
style = styles[plane] = style == "auto" ? dimensions[plane] : style.toInt();
size["total" + capitalized] = style;
edges.each(function(edge) {
var edgesize = calculateEdgeSize(edge, styles);
size["computed" + edge.capitalize()] = edgesize;
size["total" + capitalized] += edgesize;
});
}, this);
return Object.append(size, styles);
}
});
})();
(function(original) {
var local = Element.Position = {
options: {
relativeTo: document.body,
position: {
x: "center",
y: "center"
},
offset: {
x: 0,
y: 0
}
},
getOptions: function(element, options) {
options = Object.merge({}, local.options, options);
local.setPositionOption(options);
local.setEdgeOption(options);
local.setOffsetOption(element, options);
local.setDimensionsOption(element, options);
return options;
},
setPositionOption: function(options) {
options.position = local.getCoordinateFromValue(options.position);
},
setEdgeOption: function(options) {
var edgeOption = local.getCoordinateFromValue(options.edge);
options.edge = edgeOption ? edgeOption : options.position.x == "center" && options.position.y == "center" ? {
x: "center",
y: "center"
} : {
x: "left",
y: "top"
};
},
setOffsetOption: function(element, options) {
var parentOffset = {
x: 0,
y: 0
};
var parentScroll = {
x: 0,
y: 0
};
var offsetParent = element.measure(function() {
return document.id(this.getOffsetParent());
});
if (!offsetParent || offsetParent == element.getDocument().body) return;
parentScroll = offsetParent.getScroll();
parentOffset = offsetParent.measure(function() {
var position = this.getPosition();
if (this.getStyle("position") == "fixed") {
var scroll = window.getScroll();
position.x += scroll.x;
position.y += scroll.y;
}
return position;
});
options.offset = {
parentPositioned: offsetParent != document.id(options.relativeTo),
x: options.offset.x - parentOffset.x + parentScroll.x,
y: options.offset.y - parentOffset.y + parentScroll.y
};
},
setDimensionsOption: function(element, options) {
options.dimensions = element.getDimensions({
computeSize: true,
styles: [ "padding", "border", "margin" ]
});
},
getPosition: function(element, options) {
var position = {};
options = local.getOptions(element, options);
var relativeTo = document.id(options.relativeTo) || document.body;
local.setPositionCoordinates(options, position, relativeTo);
if (options.edge) local.toEdge(position, options);
var offset = options.offset;
position.left = (position.x >= 0 || offset.parentPositioned || options.allowNegative ? position.x : 0).toInt();
position.top = (position.y >= 0 || offset.parentPositioned || options.allowNegative ? position.y : 0).toInt();
local.toMinMax(position, options);
if (options.relFixedPosition || relativeTo.getStyle("position") == "fixed") local.toRelFixedPosition(relativeTo, position);
if (options.ignoreScroll) local.toIgnoreScroll(relativeTo, position);
if (options.ignoreMargins) local.toIgnoreMargins(position, options);
position.left = Math.ceil(position.left);
position.top = Math.ceil(position.top);
delete position.x;
delete position.y;
return position;
},
setPositionCoordinates: function(options, position, relativeTo) {
var offsetY = options.offset.y, offsetX = options.offset.x, calc = relativeTo == document.body ? window.getScroll() : relativeTo.getPosition(), top = calc.y, left = calc.x, winSize = window.getSize();
switch (options.position.x) {
case "left":
position.x = left + offsetX;
break;
case "right":
position.x = left + offsetX + relativeTo.offsetWidth;
break;
default:
position.x = left + (relativeTo == document.body ? winSize.x : relativeTo.offsetWidth) / 2 + offsetX;
break;
}
switch (options.position.y) {
case "top":
position.y = top + offsetY;
break;
case "bottom":
position.y = top + offsetY + relativeTo.offsetHeight;
break;
default:
position.y = top + (relativeTo == document.body ? winSize.y : relativeTo.offsetHeight) / 2 + offsetY;
break;
}
},
toMinMax: function(position, options) {
var xy = {
left: "x",
top: "y"
}, value;
[ "minimum", "maximum" ].each(function(minmax) {
[ "left", "top" ].each(function(lr) {
value = options[minmax] ? options[minmax][xy[lr]] : null;
if (value != null && (minmax == "minimum" ? position[lr] < value : position[lr] > value)) position[lr] = value;
});
});
},
toRelFixedPosition: function(relativeTo, position) {
var winScroll = window.getScroll();
position.top += winScroll.y;
position.left += winScroll.x;
},
toIgnoreScroll: function(relativeTo, position) {
var relScroll = relativeTo.getScroll();
position.top -= relScroll.y;
position.left -= relScroll.x;
},
toIgnoreMargins: function(position, options) {
position.left += options.edge.x == "right" ? options.dimensions["margin-right"] : options.edge.x != "center" ? -options.dimensions["margin-left"] : -options.dimensions["margin-left"] + (options.dimensions["margin-right"] + options.dimensions["margin-left"]) / 2;
position.top += options.edge.y == "bottom" ? options.dimensions["margin-bottom"] : options.edge.y != "center" ? -options.dimensions["margin-top"] : -options.dimensions["margin-top"] + (options.dimensions["margin-bottom"] + options.dimensions["margin-top"]) / 2;
},
toEdge: function(position, options) {
var edgeOffset = {}, dimensions = options.dimensions, edge = options.edge;
switch (edge.x) {
case "left":
edgeOffset.x = 0;
break;
case "right":
edgeOffset.x = -dimensions.x - dimensions.computedRight - dimensions.computedLeft;
break;
default:
edgeOffset.x = -Math.round(dimensions.totalWidth / 2);
break;
}
switch (edge.y) {
case "top":
edgeOffset.y = 0;
break;
case "bottom":
edgeOffset.y = -dimensions.y - dimensions.computedTop - dimensions.computedBottom;
break;
default:
edgeOffset.y = -Math.round(dimensions.totalHeight / 2);
break;
}
position.x += edgeOffset.x;
position.y += edgeOffset.y;
},
getCoordinateFromValue: function(option) {
if (typeOf(option) != "string") return option;
option = option.toLowerCase();
return {
x: option.test("left") ? "left" : option.test("right") ? "right" : "center",
y: option.test(/upper|top/) ? "top" : option.test("bottom") ? "bottom" : "center"
};
}
};
Element.implement({
position: function(options) {
if (options && (options.x != null || options.y != null)) {
return original ? original.apply(this, arguments) : this;
}
var position = this.setStyle("position", "absolute").calculatePosition(options);
return options && options.returnPos ? position : this.setStyles(position);
},
calculatePosition: function(options) {
return local.getPosition(this, options);
}
});
})(Element.prototype.position);
Element.implement({
isDisplayed: function() {
return this.getStyle("display") != "none";
},
isVisible: function() {
var w = this.offsetWidth, h = this.offsetHeight;
return w == 0 && h == 0 ? false : w > 0 && h > 0 ? true : this.style.display != "none";
},
toggle: function() {
return this[this.isDisplayed() ? "hide" : "show"]();
},
hide: function() {
var d;
try {
d = this.getStyle("display");
} catch (e) {}
if (d == "none") return this;
return this.store("element:_originalDisplay", d || "").setStyle("display", "none");
},
show: function(display) {
if (!display && this.isDisplayed()) return this;
display = display || this.retrieve("element:_originalDisplay") || "block";
return this.setStyle("display", display == "none" ? "block" : display);
},
swapClass: function(remove, add) {
return this.removeClass(remove).addClass(add);
}
});
Document.implement({
clearSelection: function() {
if (window.getSelection) {
var selection = window.getSelection();
if (selection && selection.removeAllRanges) selection.removeAllRanges();
} else if (document.selection && document.selection.empty) {
try {
document.selection.empty();
} catch (e) {}
}
}
});
(function() {
var defined = function(value) {
return value != null;
};
var hasOwnProperty = Object.prototype.hasOwnProperty;
Object.extend({
getFromPath: function(source, parts) {
if (typeof parts == "string") parts = parts.split(".");
for (var i = 0, l = parts.length; i < l; i++) {
if (hasOwnProperty.call(source, parts[i])) source = source[parts[i]]; else return null;
}
return source;
},
cleanValues: function(object, method) {
method = method || defined;
for (var key in object) if (!method(object[key])) {
delete object[key];
}
return object;
},
erase: function(object, key) {
if (hasOwnProperty.call(object, key)) delete object[key];
return object;
},
run: function(object) {
var args = Array.slice(arguments, 1);
for (var key in object) if (object[key].apply) {
object[key].apply(object, args);
}
return object;
}
});
})();
(function() {
var current = null, locales = {}, inherits = {};
var getSet = function(set) {
if (instanceOf(set, Locale.Set)) return set; else return locales[set];
};
var Locale = this.Locale = {
define: function(locale, set, key, value) {
var name;
if (instanceOf(locale, Locale.Set)) {
name = locale.name;
if (name) locales[name] = locale;
} else {
name = locale;
if (!locales[name]) locales[name] = new Locale.Set(name);
locale = locales[name];
}
if (set) locale.define(set, key, value);
if (!current) current = locale;
return locale;
},
use: function(locale) {
locale = getSet(locale);
if (locale) {
current = locale;
this.fireEvent("change", locale);
}
return this;
},
getCurrent: function() {
return current;
},
get: function(key, args) {
return current ? current.get(key, args) : "";
},
inherit: function(locale, inherits, set) {
locale = getSet(locale);
if (locale) locale.inherit(inherits, set);
return this;
},
list: function() {
return Object.keys(locales);
}
};
Object.append(Locale, new Events());
Locale.Set = new Class({
sets: {},
inherits: {
locales: [],
sets: {}
},
initialize: function(name) {
this.name = name || "";
},
define: function(set, key, value) {
var defineData = this.sets[set];
if (!defineData) defineData = {};
if (key) {
if (typeOf(key) == "object") defineData = Object.merge(defineData, key); else defineData[key] = value;
}
this.sets[set] = defineData;
return this;
},
get: function(key, args, _base) {
var value = Object.getFromPath(this.sets, key);
if (value != null) {
var type = typeOf(value);
if (type == "function") value = value.apply(null, Array.from(args)); else if (type == "object") value = Object.clone(value);
return value;
}
var index = key.indexOf("."), set = index < 0 ? key : key.substr(0, index), names = (this.inherits.sets[set] || []).combine(this.inherits.locales).include("en-US");
if (!_base) _base = [];
for (var i = 0, l = names.length; i < l; i++) {
if (_base.contains(names[i])) continue;
_base.include(names[i]);
var locale = locales[names[i]];
if (!locale) continue;
value = locale.get(key, args, _base);
if (value != null) return value;
}
return "";
},
inherit: function(names, set) {
names = Array.from(names);
if (set && !this.inherits.sets[set]) this.inherits.sets[set] = [];
var l = names.length;
while (l--) (set ? this.inherits.sets[set] : this.inherits.locales).unshift(names[l]);
return this;
}
});
})();
Locale.define("en-US", "Date", {
months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
months_abbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
days_abbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
dateOrder: [ "month", "date", "year" ],
shortDate: "%m/%d/%Y",
shortTime: "%I:%M%p",
AM: "AM",
PM: "PM",
firstDayOfWeek: 0,
ordinal: function(dayOfMonth) {
return dayOfMonth > 3 && dayOfMonth < 21 ? "th" : [ "th", "st", "nd", "rd", "th" ][Math.min(dayOfMonth % 10, 4)];
},
lessThanMinuteAgo: "less than a minute ago",
minuteAgo: "about a minute ago",
minutesAgo: "{delta} minutes ago",
hourAgo: "about an hour ago",
hoursAgo: "about {delta} hours ago",
dayAgo: "1 day ago",
daysAgo: "{delta} days ago",
weekAgo: "1 week ago",
weeksAgo: "{delta} weeks ago",
monthAgo: "1 month ago",
monthsAgo: "{delta} months ago",
yearAgo: "1 year ago",
yearsAgo: "{delta} years ago",
lessThanMinuteUntil: "less than a minute from now",
minuteUntil: "about a minute from now",
minutesUntil: "{delta} minutes from now",
hourUntil: "about an hour from now",
hoursUntil: "about {delta} hours from now",
dayUntil: "1 day from now",
daysUntil: "{delta} days from now",
weekUntil: "1 week from now",
weeksUntil: "{delta} weeks from now",
monthUntil: "1 month from now",
monthsUntil: "{delta} months from now",
yearUntil: "1 year from now",
yearsUntil: "{delta} years from now"
});
(function() {
var Date = this.Date;
var DateMethods = Date.Methods = {
ms: "Milliseconds",
year: "FullYear",
min: "Minutes",
mo: "Month",
sec: "Seconds",
hr: "Hours"
};
[ "Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds", "Time", "TimezoneOffset", "Week", "Timezone", "GMTOffset", "DayOfYear", "LastMonth", "LastDayOfMonth", "UTCDate", "UTCDay", "UTCFullYear", "AMPM", "Ordinal", "UTCHours", "UTCMilliseconds", "UTCMinutes", "UTCMonth", "UTCSeconds", "UTCMilliseconds" ].each(function(method) {
Date.Methods[method.toLowerCase()] = method;
});
var pad = function(n, digits, string) {
if (digits == 1) return n;
return n < Math.pow(10, digits - 1) ? (string || "0") + pad(n, digits - 1, string) : n;
};
Date.implement({
set: function(prop, value) {
prop = prop.toLowerCase();
var method = DateMethods[prop] && "set" + DateMethods[prop];
if (method && this[method]) this[method](value);
return this;
}.overloadSetter(),
get: function(prop) {
prop = prop.toLowerCase();
var method = DateMethods[prop] && "get" + DateMethods[prop];
if (method && this[method]) return this[method]();
return null;
}.overloadGetter(),
clone: function() {
return new Date(this.get("time"));
},
increment: function(interval, times) {
interval = interval || "day";
times = times != null ? times : 1;
switch (interval) {
case "year":
return this.increment("month", times * 12);
case "month":
var d = this.get("date");
this.set("date", 1).set("mo", this.get("mo") + times);
return this.set("date", d.min(this.get("lastdayofmonth")));
case "week":
return this.increment("day", times * 7);
case "day":
return this.set("date", this.get("date") + times);
}
if (!Date.units[interval]) throw new Error(interval + " is not a supported interval");
return this.set("time", this.get("time") + times * Date.units[interval]());
},
decrement: function(interval, times) {
return this.increment(interval, -1 * (times != null ? times : 1));
},
isLeapYear: function() {
return Date.isLeapYear(this.get("year"));
},
clearTime: function() {
return this.set({
hr: 0,
min: 0,
sec: 0,
ms: 0
});
},
diff: function(date, resolution) {
if (typeOf(date) == "string") date = Date.parse(date);
return ((date - this) / Date.units[resolution || "day"](3, 3)).round();
},
getLastDayOfMonth: function() {
return Date.daysInMonth(this.get("mo"), this.get("year"));
},
getDayOfYear: function() {
return (Date.UTC(this.get("year"), this.get("mo"), this.get("date") + 1) - Date.UTC(this.get("year"), 0, 1)) / Date.units.day();
},
setDay: function(day, firstDayOfWeek) {
if (firstDayOfWeek == null) {
firstDayOfWeek = Date.getMsg("firstDayOfWeek");
if (firstDayOfWeek === "") firstDayOfWeek = 1;
}
day = (7 + Date.parseDay(day, true) - firstDayOfWeek) % 7;
var currentDay = (7 + this.get("day") - firstDayOfWeek) % 7;
return this.increment("day", day - currentDay);
},
getWeek: function(firstDayOfWeek) {
if (firstDayOfWeek == null) {
firstDayOfWeek = Date.getMsg("firstDayOfWeek");
if (firstDayOfWeek === "") firstDayOfWeek = 1;
}
var date = this, dayOfWeek = (7 + date.get("day") - firstDayOfWeek) % 7, dividend = 0, firstDayOfYear;
if (firstDayOfWeek == 1) {
var month = date.get("month"), startOfWeek = date.get("date") - dayOfWeek;
if (month == 11 && startOfWeek > 28) return 1;
if (month == 0 && startOfWeek < -2) {
date = new Date(date).decrement("day", dayOfWeek);
dayOfWeek = 0;
}
firstDayOfYear = new Date(date.get("year"), 0, 1).get("day") || 7;
if (firstDayOfYear > 4) dividend = -7;
} else {
firstDayOfYear = new Date(date.get("year"), 0, 1).get("day");
}
dividend += date.get("dayofyear");
dividend += 6 - dayOfWeek;
dividend += (7 + firstDayOfYear - firstDayOfWeek) % 7;
return dividend / 7;
},
getOrdinal: function(day) {
return Date.getMsg("ordinal", day || this.get("date"));
},
getTimezone: function() {
return this.toString().replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, "$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
},
getGMTOffset: function() {
var off = this.get("timezoneOffset");
return (off > 0 ? "-" : "+") + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2);
},
setAMPM: function(ampm) {
ampm = ampm.toUpperCase();
var hr = this.get("hr");
if (hr > 11 && ampm == "AM") return this.decrement("hour", 12); else if (hr < 12 && ampm == "PM") return this.increment("hour", 12);
return this;
},
getAMPM: function() {
return this.get("hr") < 12 ? "AM" : "PM";
},
parse: function(str) {
this.set("time", Date.parse(str));
return this;
},
isValid: function(date) {
if (!date) date = this;
return typeOf(date) == "date" && !isNaN(date.valueOf());
},
format: function(format) {
if (!this.isValid()) return "invalid date";
if (!format) format = "%x %X";
if (typeof format == "string") format = formats[format.toLowerCase()] || format;
if (typeof format == "function") return format(this);
var d = this;
return format.replace(/%([a-z%])/gi, function($0, $1) {
switch ($1) {
case "a":
return Date.getMsg("days_abbr")[d.get("day")];
case "A":
return Date.getMsg("days")[d.get("day")];
case "b":
return Date.getMsg("months_abbr")[d.get("month")];
case "B":
return Date.getMsg("months")[d.get("month")];
case "c":
return d.format("%a %b %d %H:%M:%S %Y");
case "d":
return pad(d.get("date"), 2);
case "e":
return pad(d.get("date"), 2, " ");
case "H":
return pad(d.get("hr"), 2);
case "I":
return pad(d.get("hr") % 12 || 12, 2);
case "j":
return pad(d.get("dayofyear"), 3);
case "k":
return pad(d.get("hr"), 2, " ");
case "l":
return pad(d.get("hr") % 12 || 12, 2, " ");
case "L":
return pad(d.get("ms"), 3);
case "m":
return pad(d.get("mo") + 1, 2);
case "M":
return pad(d.get("min"), 2);
case "o":
return d.get("ordinal");
case "p":
return Date.getMsg(d.get("ampm"));
case "s":
return Math.round(d / 1e3);
case "S":
return pad(d.get("seconds"), 2);
case "T":
return d.format("%H:%M:%S");
case "U":
return pad(d.get("week"), 2);
case "w":
return d.get("day");
case "x":
return d.format(Date.getMsg("shortDate"));
case "X":
return d.format(Date.getMsg("shortTime"));
case "y":
return d.get("year").toString().substr(2);
case "Y":
return d.get("year");
case "z":
return d.get("GMTOffset");
case "Z":
return d.get("Timezone");
}
return $1;
});
},
toISOString: function() {
return this.format("iso8601");
}
}).alias({
toJSON: "toISOString",
compare: "diff",
strftime: "format"
});
var rfcDayAbbr = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], rfcMonthAbbr = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
var formats = {
db: "%Y-%m-%d %H:%M:%S",
compact: "%Y%m%dT%H%M%S",
short: "%d %b %H:%M",
long: "%B %d, %Y %H:%M",
rfc822: function(date) {
return rfcDayAbbr[date.get("day")] + date.format(", %d ") + rfcMonthAbbr[date.get("month")] + date.format(" %Y %H:%M:%S %Z");
},
rfc2822: function(date) {
return rfcDayAbbr[date.get("day")] + date.format(", %d ") + rfcMonthAbbr[date.get("month")] + date.format(" %Y %H:%M:%S %z");
},
iso8601: function(date) {
return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1, 2) + "-" + pad(date.getUTCDate(), 2) + "T" + pad(date.getUTCHours(), 2) + ":" + pad(date.getUTCMinutes(), 2) + ":" + pad(date.getUTCSeconds(), 2) + "." + pad(date.getUTCMilliseconds(), 3) + "Z";
}
};
var parsePatterns = [], nativeParse = Date.parse;
var parseWord = function(type, word, num) {
var ret = -1, translated = Date.getMsg(type + "s");
switch (typeOf(word)) {
case "object":
ret = translated[word.get(type)];
break;
case "number":
ret = translated[word];
if (!ret) throw new Error("Invalid " + type + " index: " + word);
break;
case "string":
var match = translated.filter(function(name) {
return this.test(name);
}, new RegExp("^" + word, "i"));
if (!match.length) throw new Error("Invalid " + type + " string");
if (match.length > 1) throw new Error("Ambiguous " + type);
ret = match[0];
}
return num ? translated.indexOf(ret) : ret;
};
var startCentury = 1900, startYear = 70;
Date.extend({
getMsg: function(key, args) {
return Locale.get("Date." + key, args);
},
units: {
ms: Function.from(1),
second: Function.from(1e3),
minute: Function.from(6e4),
hour: Function.from(36e5),
day: Function.from(864e5),
week: Function.from(6084e5),
month: function(month, year) {
var d = new Date();
return Date.daysInMonth(month != null ? month : d.get("mo"), year != null ? year : d.get("year")) * 864e5;
},
year: function(year) {
year = year || new Date().get("year");
return Date.isLeapYear(year) ? 316224e5 : 31536e6;
}
},
daysInMonth: function(month, year) {
return [ 31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ][month];
},
isLeapYear: function(year) {
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
},
parse: function(from) {
var t = typeOf(from);
if (t == "number") return new Date(from);
if (t != "string") return from;
from = from.clean();
if (!from.length) return null;
var parsed;
parsePatterns.some(function(pattern) {
var bits = pattern.re.exec(from);
return bits ? parsed = pattern.handler(bits) : false;
});
if (!(parsed && parsed.isValid())) {
parsed = new Date(nativeParse(from));
if (!(parsed && parsed.isValid())) parsed = new Date(from.toInt());
}
return parsed;
},
parseDay: function(day, num) {
return parseWord("day", day, num);
},
parseMonth: function(month, num) {
return parseWord("month", month, num);
},
parseUTC: function(value) {
var localDate = new Date(value);
var utcSeconds = Date.UTC(localDate.get("year"), localDate.get("mo"), localDate.get("date"), localDate.get("hr"), localDate.get("min"), localDate.get("sec"), localDate.get("ms"));
return new Date(utcSeconds);
},
orderIndex: function(unit) {
return Date.getMsg("dateOrder").indexOf(unit) + 1;
},
defineFormat: function(name, format) {
formats[name] = format;
return this;
},
defineParser: function(pattern) {
parsePatterns.push(pattern.re && pattern.handler ? pattern : build(pattern));
return this;
},
defineParsers: function() {
Array.flatten(arguments).each(Date.defineParser);
return this;
},
define2DigitYearStart: function(year) {
startYear = year % 100;
startCentury = year - startYear;
return this;
}
}).extend({
defineFormats: Date.defineFormat.overloadSetter()
});
var regexOf = function(type) {
return new RegExp("(?:" + Date.getMsg(type).map(function(name) {
return name.substr(0, 3);
}).join("|") + ")[a-z]*");
};
var replacers = function(key) {
switch (key) {
case "T":
return "%H:%M:%S";
case "x":
return (Date.orderIndex("month") == 1 ? "%m[-./]%d" : "%d[-./]%m") + "([-./]%y)?";
case "X":
return "%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%z?";
}
return null;
};
var keys = {
d: /[0-2]?[0-9]|3[01]/,
H: /[01]?[0-9]|2[0-3]/,
I: /0?[1-9]|1[0-2]/,
M: /[0-5]?\d/,
s: /\d+/,
o: /[a-z]*/,
p: /[ap]\.?m\.?/,
y: /\d{2}|\d{4}/,
Y: /\d{4}/,
z: /Z|[+-]\d{2}(?::?\d{2})?/
};
keys.m = keys.I;
keys.S = keys.M;
var currentLanguage;
var recompile = function(language) {
currentLanguage = language;
keys.a = keys.A = regexOf("days");
keys.b = keys.B = regexOf("months");
parsePatterns.each(function(pattern, i) {
if (pattern.format) parsePatterns[i] = build(pattern.format);
});
};
var build = function(format) {
if (!currentLanguage) return {
format: format
};
var parsed = [];
var re = (format.source || format).replace(/%([a-z])/gi, function($0, $1) {
return replacers($1) || $0;
}).replace(/\((?!\?)/g, "(?:").replace(/ (?!\?|\*)/g, ",? ").replace(/%([a-z%])/gi, function($0, $1) {
var p = keys[$1];
if (!p) return $1;
parsed.push($1);
return "(" + p.source + ")";
}).replace(/\[a-z\]/gi, "[a-z\\u00c0-\\uffff;&]");
return {
format: format,
re: new RegExp("^" + re + "$", "i"),
handler: function(bits) {
bits = bits.slice(1).associate(parsed);
var date = new Date().clearTime(), year = bits.y || bits.Y;
if (year != null) handle.call(date, "y", year);
if ("d" in bits) handle.call(date, "d", 1);
if ("m" in bits || bits.b || bits.B) handle.call(date, "m", 1);
for (var key in bits) handle.call(date, key, bits[key]);
return date;
}
};
};
var handle = function(key, value) {
if (!value) return this;
switch (key) {
case "a":
case "A":
return this.set("day", Date.parseDay(value, true));
case "b":
case "B":
return this.set("mo", Date.parseMonth(value, true));
case "d":
return this.set("date", value);
case "H":
case "I":
return this.set("hr", value);
case "m":
return this.set("mo", value - 1);
case "M":
return this.set("min", value);
case "p":
return this.set("ampm", value.replace(/\./g, ""));
case "S":
return this.set("sec", value);
case "s":
return this.set("ms", ("0." + value) * 1e3);
case "w":
return this.set("day", value);
case "Y":
return this.set("year", value);
case "y":
value = +value;
if (value < 100) value += startCentury + (value < startYear ? 100 : 0);
return this.set("year", value);
case "z":
if (value == "Z") value = "+00";
var offset = value.match(/([+-])(\d{2}):?(\d{2})?/);
offset = (offset[1] + "1") * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset();
return this.set("time", this - offset * 6e4);
}
return this;
};
Date.defineParsers("%Y([-./]%m([-./]%d((T| )%X)?)?)?", "%Y%m%d(T%H(%M%S?)?)?", "%x( %X)?", "%d%o( %b( %Y)?)?( %X)?", "%b( %d%o)?( %Y)?( %X)?", "%Y %b( %d%o( %X)?)?", "%o %b %d %X %z %Y", "%T", "%H:%M( ?%p)?");
Locale.addEvent("change", function(language) {
if (Locale.get("Date")) recompile(language);
}).fireEvent("change", Locale.getCurrent());
})();
(function() {
Fx.Scroll = new Class({
Extends: Fx,
options: {
offset: {
x: 0,
y: 0
},
wheelStops: true
},
initialize: function(element, options) {
this.element = this.subject = document.id(element);
this.parent(options);
if (typeOf(this.element) != "element") this.element = document.id(this.element.getDocument().body);
if (this.options.wheelStops) {
var stopper = this.element, cancel = this.cancel.pass(false, this);
this.addEvent("start", function() {
stopper.addEvent("mousewheel", cancel);
}, true);
this.addEvent("complete", function() {
stopper.removeEvent("mousewheel", cancel);
}, true);
}
},
set: function() {
var now = Array.flatten(arguments);
this.element.scrollTo(now[0], now[1]);
return this;
},
compute: function(from, to, delta) {
return [ 0, 1 ].map(function(i) {
return Fx.compute(from[i], to[i], delta);
});
},
start: function(x, y) {
if (!this.check(x, y)) return this;
var scroll = this.element.getScroll();
return this.parent([ scroll.x, scroll.y ], [ x, y ]);
},
calculateScroll: function(x, y) {
var element = this.element, scrollSize = element.getScrollSize(), scroll = element.getScroll(), size = element.getSize(), offset = this.options.offset, values = {
x: x,
y: y
};
for (var z in values) {
if (!values[z] && values[z] !== 0) values[z] = scroll[z];
if (typeOf(values[z]) != "number") values[z] = scrollSize[z] - size[z];
values[z] += offset[z];
}
return [ values.x, values.y ];
},
toTop: function() {
return this.start.apply(this, this.calculateScroll(false, 0));
},
toLeft: function() {
return this.start.apply(this, this.calculateScroll(0, false));
},
toRight: function() {
return this.start.apply(this, this.calculateScroll("right", false));
},
toBottom: function() {
return this.start.apply(this, this.calculateScroll(false, "bottom"));
},
toElement: function(el, axes) {
axes = axes ? Array.from(axes) : [ "x", "y" ];
var scroll = isBody(this.element) ? {
x: 0,
y: 0
} : this.element.getScroll();
var position = Object.map(document.id(el).getPosition(this.element), function(value, axis) {
return axes.contains(axis) ? value + scroll[axis] : false;
});
return this.start.apply(this, this.calculateScroll(position.x, position.y));
},
toElementEdge: function(el, axes, offset) {
axes = axes ? Array.from(axes) : [ "x", "y" ];
el = document.id(el);
var to = {}, position = el.getPosition(this.element), size = el.getSize(), scroll = this.element.getScroll(), containerSize = this.element.getSize(), edge = {
x: position.x + size.x,
y: position.y + size.y
};
[ "x", "y" ].each(function(axis) {
if (axes.contains(axis)) {
if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];
if (position[axis] < scroll[axis]) to[axis] = position[axis];
}
if (to[axis] == null) to[axis] = scroll[axis];
if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
}, this);
if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
return this;
},
toElementCenter: function(el, axes, offset) {
axes = axes ? Array.from(axes) : [ "x", "y" ];
el = document.id(el);
var to = {}, position = el.getPosition(this.element), size = el.getSize(), scroll = this.element.getScroll(), containerSize = this.element.getSize();
[ "x", "y" ].each(function(axis) {
if (axes.contains(axis)) {
to[axis] = position[axis] - (containerSize[axis] - size[axis]) / 2;
}
if (to[axis] == null) to[axis] = scroll[axis];
if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
}, this);
if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
return this;
}
});
function isBody(element) {
return /^(?:body|html)$/i.test(element.tagName);
}
})();
Fx.Slide = new Class({
Extends: Fx,
options: {
mode: "vertical",
wrapper: false,
hideOverflow: true,
resetHeight: false
},
initialize: function(element, options) {
element = this.element = this.subject = document.id(element);
this.parent(options);
options = this.options;
var wrapper = element.retrieve("wrapper"), styles = element.getStyles("margin", "position", "overflow");
if (options.hideOverflow) styles = Object.append(styles, {
overflow: "hidden"
});
if (options.wrapper) wrapper = document.id(options.wrapper).setStyles(styles);
if (!wrapper) wrapper = new Element("div", {
styles: styles
}).wraps(element);
element.store("wrapper", wrapper).setStyle("margin", 0);
if (element.getStyle("overflow") == "visible") element.setStyle("overflow", "hidden");
this.now = [];
this.open = true;
this.wrapper = wrapper;
this.addEvent("complete", function() {
this.open = wrapper["offset" + this.layout.capitalize()] != 0;
if (this.open && this.options.resetHeight) wrapper.setStyle("height", "");
}, true);
},
vertical: function() {
this.margin = "margin-top";
this.layout = "height";
this.offset = this.element.offsetHeight;
},
horizontal: function() {
this.margin = "margin-left";
this.layout = "width";
this.offset = this.element.offsetWidth;
},
set: function(now) {
this.element.setStyle(this.margin, now[0]);
this.wrapper.setStyle(this.layout, now[1]);
return this;
},
compute: function(from, to, delta) {
return [ 0, 1 ].map(function(i) {
return Fx.compute(from[i], to[i], delta);
});
},
start: function(how, mode) {
if (!this.check(how, mode)) return this;
this[mode || this.options.mode]();
var margin = this.element.getStyle(this.margin).toInt(), layout = this.wrapper.getStyle(this.layout).toInt(), caseIn = [ [ margin, layout ], [ 0, this.offset ] ], caseOut = [ [ margin, layout ], [ -this.offset, 0 ] ], start;
switch (how) {
case "in":
start = caseIn;
break;
case "out":
start = caseOut;
break;
case "toggle":
start = layout == 0 ? caseIn : caseOut;
}
return this.parent(start[0], start[1]);
},
slideIn: function(mode) {
return this.start("in", mode);
},
slideOut: function(mode) {
return this.start("out", mode);
},
hide: function(mode) {
this[mode || this.options.mode]();
this.open = false;
return this.set([ -this.offset, 0 ]);
},
show: function(mode) {
this[mode || this.options.mode]();
this.open = true;
return this.set([ 0, this.offset ]);
},
toggle: function(mode) {
return this.start("toggle", mode);
}
});
Element.Properties.slide = {
set: function(options) {
this.get("slide").cancel().setOptions(options);
return this;
},
get: function() {
var slide = this.retrieve("slide");
if (!slide) {
slide = new Fx.Slide(this, {
link: "cancel"
});
this.store("slide", slide);
}
return slide;
}
};
Element.implement({
slide: function(how, mode) {
how = how || "toggle";
var slide = this.get("slide"), toggle;
switch (how) {
case "hide":
slide.hide(mode);
break;
case "show":
slide.show(mode);
break;
case "toggle":
var flag = this.retrieve("slide:flag", slide.open);
slide[flag ? "slideOut" : "slideIn"](mode);
this.store("slide:flag", !flag);
toggle = true;
break;
default:
slide.start(how, mode);
}
if (!toggle) this.eliminate("slide:flag");
return this;
}
});
Request.JSONP = new Class({
Implements: [ Chain, Events, Options ],
options: {
onRequest: function(src) {
if (this.options.log && window.console && console.log) {
console.log("JSONP retrieving script with url:" + src);
}
},
onError: function(src) {
if (this.options.log && window.console && console.warn) {
console.warn("JSONP " + src + " will fail in Internet Explorer, which enforces a 2083 bytes length limit on URIs");
}
},
url: "",
callbackKey: "callback",
injectScript: document.head,
data: "",
link: "ignore",
timeout: 0,
log: false
},
initialize: function(options) {
this.setOptions(options);
},
send: function(options) {
if (!Request.prototype.check.call(this, options)) return this;
this.running = true;
var type = typeOf(options);
if (type == "string" || type == "element") options = {
data: options
};
options = Object.merge(this.options, options || {});
var data = options.data;
switch (typeOf(data)) {
case "element":
data = document.id(data).toQueryString();
break;
case "object":
case "hash":
data = Object.toQueryString(data);
}
var index = this.index = Request.JSONP.counter++;
var src = options.url + (options.url.test("\\?") ? "&" : "?") + options.callbackKey + "=Request.JSONP.request_map.request_" + index + (data ? "&" + data : "");
if (src.length > 2083) this.fireEvent("error", src);
Request.JSONP.request_map["request_" + index] = function() {
this.success(arguments, index);
}.bind(this);
var script = this.getScript(src).inject(options.injectScript);
this.fireEvent("request", [ src, script ]);
if (options.timeout) this.timeout.delay(options.timeout, this);
return this;
},
getScript: function(src) {
if (!this.script) this.script = new Element("script", {
type: "text/javascript",
async: true,
src: src
});
return this.script;
},
success: function(args, index) {
if (!this.running) return;
this.clear().fireEvent("complete", args).fireEvent("success", args).callChain();
},
cancel: function() {
if (this.running) this.clear().fireEvent("cancel");
return this;
},
isRunning: function() {
return !!this.running;
},
clear: function() {
this.running = false;
if (this.script) {
this.script.destroy();
this.script = null;
}
return this;
},
timeout: function() {
if (this.running) {
this.running = false;
this.fireEvent("timeout", [ this.script.get("src"), this.script ]).fireEvent("failure").cancel();
}
return this;
}
});
Request.JSONP.counter = 0;
Request.JSONP.request_map = {};
Request.implement({
options: {
initialDelay: 5e3,
delay: 5e3,
limit: 6e4
},
startTimer: function(data) {
var fn = function() {
if (!this.running) this.send({
data: data
});
};
this.lastDelay = this.options.initialDelay;
this.timer = fn.delay(this.lastDelay, this);
this.completeCheck = function(response) {
clearTimeout(this.timer);
this.lastDelay = response ? this.options.delay : (this.lastDelay + this.options.delay).min(this.options.limit);
this.timer = fn.delay(this.lastDelay, this);
};
return this.addEvent("complete", this.completeCheck);
},
stopTimer: function() {
clearTimeout(this.timer);
return this.removeEvent("complete", this.completeCheck);
}
});
Date.implement({
timeDiffInWords: function(to) {
return Date.distanceOfTimeInWords(this, to || new Date());
},
timeDiff: function(to, separator) {
if (to == null) to = new Date();
var delta = ((to - this) / 1e3).floor().abs();
var vals = [], durations = [ 60, 60, 24, 365, 0 ], names = [ "s", "m", "h", "d", "y" ], value, duration;
for (var item = 0; item < durations.length; item++) {
if (item && !delta) break;
value = delta;
if (duration = durations[item]) {
value = delta % duration;
delta = (delta / duration).floor();
}
vals.unshift(value + (names[item] || ""));
}
return vals.join(separator || ":");
}
}).extend({
distanceOfTimeInWords: function(from, to) {
return Date.getTimePhrase(((to - from) / 1e3).toInt());
},
getTimePhrase: function(delta) {
var suffix = delta < 0 ? "Until" : "Ago";
if (delta < 0) delta *= -1;
var units = {
minute: 60,
hour: 60,
day: 24,
week: 7,
month: 52 / 12,
year: 12,
eon: Infinity
};
var msg = "lessThanMinute";
for (var unit in units) {
var interval = units[unit];
if (delta < 1.5 * interval) {
if (delta > .75 * interval) msg = unit;
break;
}
delta /= interval;
msg = unit + "s";
}
delta = delta.round();
return Date.getMsg(msg + suffix, delta).substitute({
delta: delta
});
}
}).defineParsers({
re: /^(?:tod|tom|yes)/i,
handler: function(bits) {
var d = new Date().clearTime();
switch (bits[0]) {
case "tom":
return d.increment();
case "yes":
return d.decrement();
default:
return d;
}
}
}, {
re: /^(next|last) ([a-z]+)$/i,
handler: function(bits) {
var d = new Date().clearTime();
var day = d.getDay();
var newDay = Date.parseDay(bits[2], true);
var addDays = newDay - day;
if (newDay <= day) addDays += 7;
if (bits[1] == "last") addDays -= 7;
return d.set("date", d.getDate() + addDays);
}
}).alias("timeAgoInWords", "timeDiffInWords");
(function() {
var defaultSortFunction = function(a, b) {
return a > b ? 1 : a < b ? -1 : 0;
};
Array.implement({
stableSort: function(compare) {
return Browser.chrome || Browser.firefox2 || Browser.opera9 ? this.mergeSort(compare) : this.sort(compare);
},
mergeSort: function(compare, token) {
compare = compare || defaultSortFunction;
if (this.length > 1) {
var right = this.splice(Math.floor(this.length / 2)).mergeSort(compare);
var left = this.splice(0).mergeSort(compare);
while (left.length > 0 || right.length > 0) {
this.push(right.length === 0 ? left.shift() : left.length === 0 ? right.shift() : compare(left[0], right[0]) > 0 ? right.shift() : left.shift());
}
}
return this;
}
});
})();
Class.Binds = new Class({
$bound: {},
bound: function(name) {
return this.$bound[name] ? this.$bound[name] : this.$bound[name] = this[name].bind(this);
}
});
(function() {
var events = Element.NativeEvents, location = window.location, base = location.pathname, history = window.history, hasPushState = "pushState" in history, event = hasPushState ? "popstate" : "hashchange";
this.History = new new Class({
Implements: [ Class.Binds, Events ],
initialize: hasPushState ? function() {
events[event] = 2;
window.addEvent(event, this.bound("pop"));
} : function() {
events[event] = 1;
window.addEvent(event, this.bound("pop"));
this.hash = location.hash;
var hashchange = "onhashchange" in window;
if (!(hashchange && (document.documentMode === undefined || document.documentMode > 7))) this.timer = this.check.periodical(200, this);
},
push: hasPushState ? function(url, title, state) {
if (base && base != url) base = null;
history.pushState(state || null, title || null, url);
this.onChange(url, state);
} : function(url) {
location.hash = url;
},
replace: hasPushState ? function(url, title, state) {
history.replaceState(state || null, title || null, url);
} : function(url) {
this.hash = "#" + url;
this.push(url);
},
pop: hasPushState ? function(event) {
var url = location.pathname;
if (url == base) {
base = null;
return;
}
this.onChange(url, event.event.state);
} : function() {
var hash = location.hash;
if (this.hash == hash) return;
this.hash = hash;
this.onChange(hash.substr(1));
},
onChange: function(url, state) {
this.fireEvent("change", [ url, state || {} ]);
},
back: function() {
history.back();
},
forward: function() {
history.forward();
},
getPath: function() {
return hasPushState ? location.pathname : location.hash.substr(1);
},
hasPushState: function() {
return hasPushState;
},
check: function() {
if (this.hash != location.hash) this.pop();
}
})();
})();
History.handleInitialState = function(base) {
if (!base) base = "";
var location = window.location, pathname = location.pathname.substr(base.length), hash = location.hash, hasPushState = History.hasPushState();
if (!hasPushState && pathname.length > 1) {
window.location = (base || "/") + "#" + pathname;
return true;
}
if (!hash || hash.length <= 1) return false;
if (hasPushState) {
(function() {
History.push(hash.substr(1));
}).delay(1);
return false;
}
if (!pathname || pathname == "/") return false;
window.location = (base || "/") + hash;
return true;
};
(function() {
var Color, DecomposedMatrix, DecomposedMatrix2D, InterpolableArray, InterpolableColor, InterpolableObject, InterpolableWithUnit, Matrix, Matrix2D, Set, Vector, addTimeout, animationTick, animations, animationsTimeouts, applyDefaults, applyFrame, applyProperties, baseSVG, cacheFn, cancelTimeout, clone, createInterpolable, defaultValueForKey, degProperties, dynamics, getCurrentProperties, interpolate, isDocumentVisible, isSVGElement, lastTime, leftDelayForTimeout, makeArrayFn, observeVisibilityChange, parseProperties, prefixFor, propertyWithPrefix, pxProperties, rAF, roundf, runLoopPaused, runLoopRunning, runLoopTick, setRealTimeout, slow, slowRatio, startAnimation, startRunLoop, svgProperties, timeBeforeVisibilityChange, timeoutLastId, timeouts, toDashed, transformProperties, transformValueForProperty, unitForProperty, __bind = function(fn, me) {
return function() {
return fn.apply(me, arguments);
};
};
isDocumentVisible = function() {
return document.visibilityState === "visible" || dynamics.tests != null;
};
observeVisibilityChange = function() {
var fns;
fns = [];
if (typeof document !== "undefined" && document !== null) {
document.addEventListener("visibilitychange", function() {
var fn, _i, _len, _results;
_results = [];
for (_i = 0, _len = fns.length; _i < _len; _i++) {
fn = fns[_i];
_results.push(fn(isDocumentVisible()));
}
return _results;
});
}
return function(fn) {
return fns.push(fn);
};
}();
clone = function(o) {
var k, newO, v;
newO = {};
for (k in o) {
v = o[k];
newO[k] = v;
}
return newO;
};
cacheFn = function(func) {
var data;
data = {};
return function() {
var k, key, result, _i, _len;
key = "";
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
k = arguments[_i];
key += k.toString() + ",";
}
result = data[key];
if (!result) {
data[key] = result = func.apply(this, arguments);
}
return result;
};
};
makeArrayFn = function(fn) {
return function(el) {
var args, i, res;
if (el instanceof Array || el instanceof NodeList || el instanceof HTMLCollection) {
res = function() {
var _i, _ref, _results;
_results = [];
for (i = _i = 0, _ref = el.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
args = Array.prototype.slice.call(arguments, 1);
args.splice(0, 0, el[i]);
_results.push(fn.apply(this, args));
}
return _results;
}.apply(this, arguments);
return res;
}
return fn.apply(this, arguments);
};
};
applyDefaults = function(options, defaults) {
var k, v, _results;
_results = [];
for (k in defaults) {
v = defaults[k];
_results.push(options[k] != null ? options[k] : options[k] = v);
}
return _results;
};
applyFrame = function(el, properties) {
var k, v, _results;
if (el.style != null) {
return applyProperties(el, properties);
} else {
_results = [];
for (k in properties) {
v = properties[k];
_results.push(el[k] = v.format());
}
return _results;
}
};
applyProperties = function(el, properties) {
var isSVG, k, matrix, transforms, v;
properties = parseProperties(properties);
transforms = [];
isSVG = isSVGElement(el);
for (k in properties) {
v = properties[k];
if (transformProperties.contains(k)) {
transforms.push([ k, v ]);
} else {
if (v.format != null) {
v = v.format();
} else {
v = "" + v + unitForProperty(k, v);
}
if (isSVG && svgProperties.contains(k)) {
el.setAttribute(k, v);
} else {
el.style[propertyWithPrefix(k)] = v;
}
}
}
if (transforms.length > 0) {
if (isSVG) {
matrix = new Matrix2D();
matrix.applyProperties(transforms);
return el.setAttribute("transform", matrix.decompose().format());
} else {
v = transforms.map(function(transform) {
return transformValueForProperty(transform[0], transform[1]);
}).join(" ");
return el.style[propertyWithPrefix("transform")] = v;
}
}
};
isSVGElement = function(el) {
var _ref, _ref1;
if (typeof SVGElement !== "undefined" && SVGElement !== null && (typeof SVGSVGElement !== "undefined" && SVGSVGElement !== null)) {
return el instanceof SVGElement && !(el instanceof SVGSVGElement);
} else {
return (_ref = (_ref1 = dynamics.tests) != null ? typeof _ref1.isSVG === "function" ? _ref1.isSVG(el) : void 0 : void 0) != null ? _ref : false;
}
};
roundf = function(v, decimal) {
var d;
d = Math.pow(10, decimal);
return Math.round(v * d) / d;
};
Set = function() {
function Set(array) {
var v, _i, _len;
this.obj = {};
for (_i = 0, _len = array.length; _i < _len; _i++) {
v = array[_i];
this.obj[v] = 1;
}
}
Set.prototype.contains = function(v) {
return this.obj[v] === 1;
};
return Set;
}();
toDashed = function(str) {
return str.replace(/([A-Z])/g, function($1) {
return "-" + $1.toLowerCase();
});
};
pxProperties = new Set("marginTop,marginLeft,marginBottom,marginRight,paddingTop,paddingLeft,paddingBottom,paddingRight,top,left,bottom,right,translateX,translateY,translateZ,perspectiveX,perspectiveY,perspectiveZ,width,height,maxWidth,maxHeight,minWidth,minHeight,borderRadius".split(","));
degProperties = new Set("rotate,rotateX,rotateY,rotateZ,skew,skewX,skewY,skewZ".split(","));
transformProperties = new Set("translate,translateX,translateY,translateZ,scale,scaleX,scaleY,scaleZ,rotate,rotateX,rotateY,rotateZ,rotateC,rotateCX,rotateCY,skew,skewX,skewY,skewZ,perspective".split(","));
svgProperties = new Set("accent-height,ascent,azimuth,baseFrequency,baseline-shift,bias,cx,cy,d,diffuseConstant,divisor,dx,dy,elevation,filterRes,fx,fy,gradientTransform,height,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,letter-spacing,limitingConeAngle,markerHeight,markerWidth,numOctaves,order,overline-position,overline-thickness,pathLength,points,pointsAtX,pointsAtY,pointsAtZ,r,radius,rx,ry,seed,specularConstant,specularExponent,stdDeviation,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,surfaceScale,target,targetX,targetY,transform,underline-position,underline-thickness,viewBox,width,x,x1,x2,y,y1,y2,z".split(","));
unitForProperty = function(k, v) {
if (typeof v !== "number") {
return "";
}
if (pxProperties.contains(k)) {
return "px";
} else if (degProperties.contains(k)) {
return "deg";
}
return "";
};
transformValueForProperty = function(k, v) {
var match, unit;
match = ("" + v).match(/^([0-9.-]*)([^0-9]*)$/);
if (match != null) {
v = match[1];
unit = match[2];
} else {
v = parseFloat(v);
}
v = roundf(parseFloat(v), 10);
if (unit == null || unit === "") {
unit = unitForProperty(k, v);
}
return "" + k + "(" + v + unit + ")";
};
parseProperties = function(properties) {
var axis, match, parsed, property, value, _i, _len, _ref;
parsed = {};
for (property in properties) {
value = properties[property];
if (transformProperties.contains(property)) {
match = property.match(/(translate|rotateC|rotate|skew|scale|perspective)(X|Y|Z|)/);
if (match && match[2].length > 0) {
parsed[property] = value;
} else {
_ref = [ "X", "Y", "Z" ];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
axis = _ref[_i];
parsed[match[1] + axis] = value;
}
}
} else {
parsed[property] = value;
}
}
return parsed;
};
defaultValueForKey = function(key) {
var v;
v = key === "opacity" ? 1 : 0;
return "" + v + unitForProperty(key, v);
};
getCurrentProperties = function(el, keys) {
var isSVG, key, matrix, properties, style, v, _i, _j, _len, _len1, _ref;
properties = {};
isSVG = isSVGElement(el);
if (el.style != null) {
style = window.getComputedStyle(el, null);
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
if (transformProperties.contains(key)) {
if (properties["transform"] == null) {
if (isSVG) {
matrix = new Matrix2D((_ref = el.transform.baseVal.consolidate()) != null ? _ref.matrix : void 0);
} else {
matrix = Matrix.fromTransform(style[propertyWithPrefix("transform")]);
}
properties["transform"] = matrix.decompose();
}
} else {
v = style[key];
if (v == null && svgProperties.contains(key)) {
v = el.getAttribute(key);
}
if (v === "" || v == null) {
v = defaultValueForKey(key);
}
properties[key] = createInterpolable(v);
}
}
} else {
for (_j = 0, _len1 = keys.length; _j < _len1; _j++) {
key = keys[_j];
properties[key] = createInterpolable(el[key]);
}
}
return properties;
};
createInterpolable = function(value) {
var interpolable, klass, klasses, _i, _len;
klasses = [ InterpolableColor, InterpolableArray, InterpolableObject, InterpolableWithUnit ];
for (_i = 0, _len = klasses.length; _i < _len; _i++) {
klass = klasses[_i];
interpolable = klass.create(value);
if (interpolable != null) {
return interpolable;
}
}
return null;
};
InterpolableObject = function() {
function InterpolableObject(obj) {
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
this.obj = obj;
}
InterpolableObject.prototype.interpolate = function(endInterpolable, t) {
var end, k, newObj, start, v;
start = this.obj;
end = endInterpolable.obj;
newObj = {};
for (k in start) {
v = start[k];
if (v.interpolate != null) {
newObj[k] = v.interpolate(end[k], t);
} else {
newObj[k] = v;
}
}
return new InterpolableObject(newObj);
};
InterpolableObject.prototype.format = function() {
return this.obj;
};
InterpolableObject.create = function(value) {
var k, obj, v;
if (value instanceof Object) {
obj = {};
for (k in value) {
v = value[k];
obj[k] = createInterpolable(v);
}
return new InterpolableObject(obj);
}
return null;
};
return InterpolableObject;
}();
InterpolableWithUnit = function() {
function InterpolableWithUnit(value, prefix, suffix) {
this.prefix = prefix;
this.suffix = suffix;
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
this.value = parseFloat(value);
}
InterpolableWithUnit.prototype.interpolate = function(endInterpolable, t) {
var end, start;
start = this.value;
end = endInterpolable.value;
return new InterpolableWithUnit((end - start) * t + start, endInterpolable.prefix || this.prefix, endInterpolable.suffix || this.suffix);
};
InterpolableWithUnit.prototype.format = function() {
if (this.prefix == null && this.suffix == null) {
return roundf(this.value, 5);
}
return this.prefix + roundf(this.value, 5) + this.suffix;
};
InterpolableWithUnit.create = function(value) {
var match;
if (typeof value !== "string") {
return new InterpolableWithUnit(value);
}
match = ("" + value).match("([^0-9.+-]*)([0-9.+-]+)([^0-9.+-]*)");
if (match != null) {
return new InterpolableWithUnit(match[2], match[1], match[3]);
}
return null;
};
return InterpolableWithUnit;
}();
InterpolableArray = function() {
function InterpolableArray(values, sep) {
this.values = values;
this.sep = sep;
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
}
InterpolableArray.prototype.interpolate = function(endInterpolable, t) {
var end, i, newValues, start, _i, _ref;
start = this.values;
end = endInterpolable.values;
newValues = [];
for (i = _i = 0, _ref = Math.min(start.length, end.length); 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
if (start[i].interpolate != null) {
newValues.push(start[i].interpolate(end[i], t));
} else {
newValues.push(start[i]);
}
}
return new InterpolableArray(newValues, this.sep);
};
InterpolableArray.prototype.format = function() {
var values;
values = this.values.map(function(val) {
if (val.format != null) {
return val.format();
} else {
return val;
}
});
if (this.sep != null) {
return values.join(this.sep);
} else {
return values;
}
};
InterpolableArray.createFromArray = function(arr, sep) {
var values;
values = arr.map(function(val) {
return createInterpolable(val) || val;
});
values = values.filter(function(val) {
return val != null;
});
return new InterpolableArray(values, sep);
};
InterpolableArray.create = function(value) {
var arr, sep, seps, _i, _len;
if (value instanceof Array) {
return InterpolableArray.createFromArray(value, null);
}
if (typeof value !== "string") {
return;
}
seps = [ " ", ",", "|", ";", "/", ":" ];
for (_i = 0, _len = seps.length; _i < _len; _i++) {
sep = seps[_i];
arr = value.split(sep);
if (arr.length > 1) {
return InterpolableArray.createFromArray(arr, sep);
}
}
return null;
};
return InterpolableArray;
}();
Color = function() {
function Color(rgb, format) {
this.rgb = rgb != null ? rgb : {};
this.format = format;
this.toRgba = __bind(this.toRgba, this);
this.toRgb = __bind(this.toRgb, this);
this.toHex = __bind(this.toHex, this);
}
Color.fromHex = function(hex) {
var hex3, result;
hex3 = hex.match(/^#([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i);
if (hex3 != null) {
hex = "#" + hex3[1] + hex3[1] + hex3[2] + hex3[2] + hex3[3] + hex3[3];
}
result = hex.match(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
if (result != null) {
return new Color({
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
a: 1
}, "hex");
}
return null;
};
Color.fromRgb = function(rgb) {
var match, _ref;
match = rgb.match(/^rgba?\(([0-9.]*), ?([0-9.]*), ?([0-9.]*)(?:, ?([0-9.]*))?\)$/);
if (match != null) {
return new Color({
r: parseFloat(match[1]),
g: parseFloat(match[2]),
b: parseFloat(match[3]),
a: parseFloat((_ref = match[4]) != null ? _ref : 1)
}, match[4] != null ? "rgba" : "rgb");
}
return null;
};
Color.componentToHex = function(c) {
var hex;
hex = c.toString(16);
if (hex.length === 1) {
return "0" + hex;
} else {
return hex;
}
};
Color.prototype.toHex = function() {
return "#" + Color.componentToHex(this.rgb.r) + Color.componentToHex(this.rgb.g) + Color.componentToHex(this.rgb.b);
};
Color.prototype.toRgb = function() {
return "rgb(" + this.rgb.r + ", " + this.rgb.g + ", " + this.rgb.b + ")";
};
Color.prototype.toRgba = function() {
return "rgba(" + this.rgb.r + ", " + this.rgb.g + ", " + this.rgb.b + ", " + this.rgb.a + ")";
};
return Color;
}();
InterpolableColor = function() {
function InterpolableColor(color) {
this.color = color;
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
}
InterpolableColor.prototype.interpolate = function(endInterpolable, t) {
var end, k, rgb, start, v, _i, _len, _ref;
start = this.color;
end = endInterpolable.color;
rgb = {};
_ref = [ "r", "g", "b" ];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
k = _ref[_i];
v = Math.round((end.rgb[k] - start.rgb[k]) * t + start.rgb[k]);
rgb[k] = Math.min(255, Math.max(0, v));
}
k = "a";
v = roundf((end.rgb[k] - start.rgb[k]) * t + start.rgb[k], 5);
rgb[k] = Math.min(1, Math.max(0, v));
return new InterpolableColor(new Color(rgb, end.format));
};
InterpolableColor.prototype.format = function() {
if (this.color.format === "hex") {
return this.color.toHex();
} else if (this.color.format === "rgb") {
return this.color.toRgb();
} else if (this.color.format === "rgba") {
return this.color.toRgba();
}
};
InterpolableColor.create = function(value) {
var color;
if (typeof value !== "string") {
return;
}
color = Color.fromHex(value) || Color.fromRgb(value);
if (color != null) {
return new InterpolableColor(color);
}
return null;
};
return InterpolableColor;
}();
DecomposedMatrix2D = function() {
function DecomposedMatrix2D(props) {
this.props = props;
this.applyRotateCenter = __bind(this.applyRotateCenter, this);
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
}
DecomposedMatrix2D.prototype.interpolate = function(endMatrix, t) {
var i, k, newProps, _i, _j, _k, _l, _len, _len1, _ref, _ref1, _ref2;
newProps = {};
_ref = [ "translate", "scale", "rotate" ];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
k = _ref[_i];
newProps[k] = [];
for (i = _j = 0, _ref1 = this.props[k].length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
newProps[k][i] = (endMatrix.props[k][i] - this.props[k][i]) * t + this.props[k][i];
}
}
for (i = _k = 1; _k <= 2; i = ++_k) {
newProps["rotate"][i] = endMatrix.props["rotate"][i];
}
_ref2 = [ "skew" ];
for (_l = 0, _len1 = _ref2.length; _l < _len1; _l++) {
k = _ref2[_l];
newProps[k] = (endMatrix.props[k] - this.props[k]) * t + this.props[k];
}
return new DecomposedMatrix2D(newProps);
};
DecomposedMatrix2D.prototype.format = function() {
return "translate(" + this.props.translate.join(",") + ") rotate(" + this.props.rotate.join(",") + ") skewX(" + this.props.skew + ") scale(" + this.props.scale.join(",") + ")";
};
DecomposedMatrix2D.prototype.applyRotateCenter = function(rotateC) {
var i, m, m2d, negativeTranslate, _i, _results;
m = baseSVG.createSVGMatrix();
m = m.translate(rotateC[0], rotateC[1]);
m = m.rotate(this.props.rotate[0]);
m = m.translate(-rotateC[0], -rotateC[1]);
m2d = new Matrix2D(m);
negativeTranslate = m2d.decompose().props.translate;
_results = [];
for (i = _i = 0; _i <= 1; i = ++_i) {
_results.push(this.props.translate[i] -= negativeTranslate[i]);
}
return _results;
};
return DecomposedMatrix2D;
}();
baseSVG = typeof document !== "undefined" && document !== null ? document.createElementNS("http://www.w3.org/2000/svg", "svg") : void 0;
Matrix2D = function() {
function Matrix2D(m) {
this.m = m;
this.applyProperties = __bind(this.applyProperties, this);
this.decompose = __bind(this.decompose, this);
if (!this.m) {
this.m = baseSVG.createSVGMatrix();
}
}
Matrix2D.prototype.decompose = function() {
var kx, ky, kz, r0, r1;
r0 = new Vector([ this.m.a, this.m.b ]);
r1 = new Vector([ this.m.c, this.m.d ]);
kx = r0.length();
kz = r0.dot(r1);
r0 = r0.normalize();
ky = r1.combine(r0, 1, -kz).length();
return new DecomposedMatrix2D({
translate: [ this.m.e, this.m.f ],
rotate: [ Math.atan2(this.m.b, this.m.a) * 180 / Math.PI, this.rotateCX, this.rotateCY ],
scale: [ kx, ky ],
skew: kz / ky * 180 / Math.PI
});
};
Matrix2D.prototype.applyProperties = function(properties) {
var hash, k, props, v, _i, _len, _ref, _ref1;
hash = {};
for (_i = 0, _len = properties.length; _i < _len; _i++) {
props = properties[_i];
hash[props[0]] = props[1];
}
for (k in hash) {
v = hash[k];
if (k === "translateX") {
this.m = this.m.translate(v, 0);
} else if (k === "translateY") {
this.m = this.m.translate(0, v);
} else if (k === "scaleX") {
this.m = this.m.scale(v, 1);
} else if (k === "scaleY") {
this.m = this.m.scale(1, v);
} else if (k === "rotateZ") {
this.m = this.m.rotate(v);
} else if (k === "skewX") {
this.m = this.m.skewX(v);
} else if (k === "skewY") {
this.m = this.m.skewY(v);
}
}
this.rotateCX = (_ref = hash.rotateCX) != null ? _ref : 0;
return this.rotateCY = (_ref1 = hash.rotateCY) != null ? _ref1 : 0;
};
return Matrix2D;
}();
Vector = function() {
function Vector(els) {
this.els = els;
this.combine = __bind(this.combine, this);
this.normalize = __bind(this.normalize, this);
this.length = __bind(this.length, this);
this.cross = __bind(this.cross, this);
this.dot = __bind(this.dot, this);
this.e = __bind(this.e, this);
}
Vector.prototype.e = function(i) {
if (i < 1 || i > this.els.length) {
return null;
} else {
return this.els[i - 1];
}
};
Vector.prototype.dot = function(vector) {
var V, n, product;
V = vector.els || vector;
product = 0;
n = this.els.length;
if (n !== V.length) {
return null;
}
n += 1;
while (--n) {
product += this.els[n - 1] * V[n - 1];
}
return product;
};
Vector.prototype.cross = function(vector) {
var A, B;
B = vector.els || vector;
if (this.els.length !== 3 || B.length !== 3) {
return null;
}
A = this.els;
return new Vector([ A[1] * B[2] - A[2] * B[1], A[2] * B[0] - A[0] * B[2], A[0] * B[1] - A[1] * B[0] ]);
};
Vector.prototype.length = function() {
var a, e, _i, _len, _ref;
a = 0;
_ref = this.els;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
e = _ref[_i];
a += Math.pow(e, 2);
}
return Math.sqrt(a);
};
Vector.prototype.normalize = function() {
var e, i, length, newElements, _ref;
length = this.length();
newElements = [];
_ref = this.els;
for (i in _ref) {
e = _ref[i];
newElements[i] = e / length;
}
return new Vector(newElements);
};
Vector.prototype.combine = function(b, ascl, bscl) {
var i, result, _i, _ref;
result = [];
for (i = _i = 0, _ref = this.els.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
result[i] = ascl * this.els[i] + bscl * b.els[i];
}
return new Vector(result);
};
return Vector;
}();
DecomposedMatrix = function() {
function DecomposedMatrix() {
this.toMatrix = __bind(this.toMatrix, this);
this.format = __bind(this.format, this);
this.interpolate = __bind(this.interpolate, this);
}
DecomposedMatrix.prototype.interpolate = function(decomposedB, t, only) {
var angle, decomposed, decomposedA, i, invscale, invth, k, qa, qb, scale, th, _i, _j, _k, _l, _len, _ref, _ref1;
if (only == null) {
only = null;
}
decomposedA = this;
decomposed = new DecomposedMatrix();
_ref = [ "translate", "scale", "skew", "perspective" ];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
k = _ref[_i];
decomposed[k] = [];
for (i = _j = 0, _ref1 = decomposedA[k].length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
if (only == null || only.indexOf(k) > -1 || only.indexOf("" + k + [ "x", "y", "z" ][i]) > -1) {
decomposed[k][i] = (decomposedB[k][i] - decomposedA[k][i]) * t + decomposedA[k][i];
} else {
decomposed[k][i] = decomposedA[k][i];
}
}
}
if (only == null || only.indexOf("rotate") !== -1) {
qa = decomposedA.quaternion;
qb = decomposedB.quaternion;
angle = qa[0] * qb[0] + qa[1] * qb[1] + qa[2] * qb[2] + qa[3] * qb[3];
if (angle < 0) {
for (i = _k = 0; _k <= 3; i = ++_k) {
qa[i] = -qa[i];
}
angle = -angle;
}
if (angle + 1 > .05) {
if (1 - angle >= .05) {
th = Math.acos(angle);
invth = 1 / Math.sin(th);
scale = Math.sin(th * (1 - t)) * invth;
invscale = Math.sin(th * t) * invth;
} else {
scale = 1 - t;
invscale = t;
}
} else {
qb[0] = -qa[1];
qb[1] = qa[0];
qb[2] = -qa[3];
qb[3] = qa[2];
scale = Math.sin(piDouble * (.5 - t));
invscale = Math.sin(piDouble * t);
}
decomposed.quaternion = [];
for (i = _l = 0; _l <= 3; i = ++_l) {
decomposed.quaternion[i] = qa[i] * scale + qb[i] * invscale;
}
} else {
decomposed.quaternion = decomposedA.quaternion;
}
return decomposed;
};
DecomposedMatrix.prototype.format = function() {
return this.toMatrix().toString();
};
DecomposedMatrix.prototype.toMatrix = function() {
var decomposedMatrix, i, j, match, matrix, quaternion, skew, temp, w, x, y, z, _i, _j, _k, _l;
decomposedMatrix = this;
matrix = Matrix.I(4);
for (i = _i = 0; _i <= 3; i = ++_i) {
matrix.els[i][3] = decomposedMatrix.perspective[i];
}
quaternion = decomposedMatrix.quaternion;
x = quaternion[0];
y = quaternion[1];
z = quaternion[2];
w = quaternion[3];
skew = decomposedMatrix.skew;
match = [ [ 1, 0 ], [ 2, 0 ], [ 2, 1 ] ];
for (i = _j = 2; _j >= 0; i = --_j) {
if (skew[i]) {
temp = Matrix.I(4);
temp.els[match[i][0]][match[i][1]] = skew[i];
matrix = matrix.multiply(temp);
}
}
matrix = matrix.multiply(new Matrix([ [ 1 - 2 * (y * y + z * z), 2 * (x * y - z * w), 2 * (x * z + y * w), 0 ], [ 2 * (x * y + z * w), 1 - 2 * (x * x + z * z), 2 * (y * z - x * w), 0 ], [ 2 * (x * z - y * w), 2 * (y * z + x * w), 1 - 2 * (x * x + y * y), 0 ], [ 0, 0, 0, 1 ] ]));
for (i = _k = 0; _k <= 2; i = ++_k) {
for (j = _l = 0; _l <= 2; j = ++_l) {
matrix.els[i][j] *= decomposedMatrix.scale[i];
}
matrix.els[3][i] = decomposedMatrix.translate[i];
}
return matrix;
};
return DecomposedMatrix;
}();
Matrix = function() {
function Matrix(els) {
this.els = els;
this.toString = __bind(this.toString, this);
this.decompose = __bind(this.decompose, this);
this.inverse = __bind(this.inverse, this);
this.augment = __bind(this.augment, this);
this.toRightTriangular = __bind(this.toRightTriangular, this);
this.transpose = __bind(this.transpose, this);
this.multiply = __bind(this.multiply, this);
this.dup = __bind(this.dup, this);
this.e = __bind(this.e, this);
}
Matrix.prototype.e = function(i, j) {
if (i < 1 || i > this.els.length || j < 1 || j > this.els[0].length) {
return null;
}
return this.els[i - 1][j - 1];
};
Matrix.prototype.dup = function() {
return new Matrix(this.els);
};
Matrix.prototype.multiply = function(matrix) {
var M, c, cols, elements, i, j, ki, kj, nc, ni, nj, returnVector, sum;
returnVector = matrix.modulus ? true : false;
M = matrix.els || matrix;
if (typeof M[0][0] === "undefined") {
M = new Matrix(M).els;
}
ni = this.els.length;
ki = ni;
kj = M[0].length;
cols = this.els[0].length;
elements = [];
ni += 1;
while (--ni) {
i = ki - ni;
elements[i] = [];
nj = kj;
nj += 1;
while (--nj) {
j = kj - nj;
sum = 0;
nc = cols;
nc += 1;
while (--nc) {
c = cols - nc;
sum += this.els[i][c] * M[c][j];
}
elements[i][j] = sum;
}
}
M = new Matrix(elements);
if (returnVector) {
return M.col(1);
} else {
return M;
}
};
Matrix.prototype.transpose = function() {
var cols, elements, i, j, ni, nj, rows;
rows = this.els.length;
cols = this.els[0].length;
elements = [];
ni = cols;
ni += 1;
while (--ni) {
i = cols - ni;
elements[i] = [];
nj = rows;
nj += 1;
while (--nj) {
j = rows - nj;
elements[i][j] = this.els[j][i];
}
}
return new Matrix(elements);
};
Matrix.prototype.toRightTriangular = function() {
var M, els, i, j, k, kp, multiplier, n, np, p, _i, _j, _ref, _ref1;
M = this.dup();
n = this.els.length;
k = n;
kp = this.els[0].length;
while (--n) {
i = k - n;
if (M.els[i][i] === 0) {
for (j = _i = _ref = i + 1; _ref <= k ? _i < k : _i > k; j = _ref <= k ? ++_i : --_i) {
if (M.els[j][i] !== 0) {
els = [];
np = kp;
np += 1;
while (--np) {
p = kp - np;
els.push(M.els[i][p] + M.els[j][p]);
}
M.els[i] = els;
break;
}
}
}
if (M.els[i][i] !== 0) {
for (j = _j = _ref1 = i + 1; _ref1 <= k ? _j < k : _j > k; j = _ref1 <= k ? ++_j : --_j) {
multiplier = M.els[j][i] / M.els[i][i];
els = [];
np = kp;
np += 1;
while (--np) {
p = kp - np;
els.push(p <= i ? 0 : M.els[j][p] - M.els[i][p] * multiplier);
}
M.els[j] = els;
}
}
}
return M;
};
Matrix.prototype.augment = function(matrix) {
var M, T, cols, i, j, ki, kj, ni, nj;
M = matrix.els || matrix;
if (typeof M[0][0] === "undefined") {
M = new Matrix(M).els;
}
T = this.dup();
cols = T.els[0].length;
ni = T.els.length;
ki = ni;
kj = M[0].length;
if (ni !== M.length) {
return null;
}
ni += 1;
while (--ni) {
i = ki - ni;
nj = kj;
nj += 1;
while (--nj) {
j = kj - nj;
T.els[i][cols + j] = M[i][j];
}
}
return T;
};
Matrix.prototype.inverse = function() {
var M, divisor, els, i, inverse_elements, j, ki, kp, new_element, ni, np, p, _i;
ni = this.els.length;
ki = ni;
M = this.augment(Matrix.I(ni)).toRightTriangular();
kp = M.els[0].length;
inverse_elements = [];
ni += 1;
while (--ni) {
i = ni - 1;
els = [];
np = kp;
inverse_elements[i] = [];
divisor = M.els[i][i];
np += 1;
while (--np) {
p = kp - np;
new_element = M.els[i][p] / divisor;
els.push(new_element);
if (p >= ki) {
inverse_elements[i].push(new_element);
}
}
M.els[i] = els;
for (j = _i = 0; 0 <= i ? _i < i : _i > i; j = 0 <= i ? ++_i : --_i) {
els = [];
np = kp;
np += 1;
while (--np) {
p = kp - np;
els.push(M.els[j][p] - M.els[i][p] * M.els[j][i]);
}
M.els[j] = els;
}
}
return new Matrix(inverse_elements);
};
Matrix.I = function(n) {
var els, i, j, k, nj;
els = [];
k = n;
n += 1;
while (--n) {
i = k - n;
els[i] = [];
nj = k;
nj += 1;
while (--nj) {
j = k - nj;
els[i][j] = i === j ? 1 : 0;
}
}
return new Matrix(els);
};
Matrix.prototype.decompose = function() {
var els, i, inversePerspectiveMatrix, j, k, matrix, pdum3, perspective, perspectiveMatrix, quaternion, result, rightHandSide, rotate, row, rowElement, s, scale, skew, t, translate, transposedInversePerspectiveMatrix, type, typeKey, v, w, x, y, z, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
matrix = this;
translate = [];
scale = [];
skew = [];
quaternion = [];
perspective = [];
els = [];
for (i = _i = 0; _i <= 3; i = ++_i) {
els[i] = [];
for (j = _j = 0; _j <= 3; j = ++_j) {
els[i][j] = matrix.els[i][j];
}
}
if (els[3][3] === 0) {
return false;
}
for (i = _k = 0; _k <= 3; i = ++_k) {
for (j = _l = 0; _l <= 3; j = ++_l) {
els[i][j] /= els[3][3];
}
}
perspectiveMatrix = matrix.dup();
for (i = _m = 0; _m <= 2; i = ++_m) {
perspectiveMatrix.els[i][3] = 0;
}
perspectiveMatrix.els[3][3] = 1;
if (els[0][3] !== 0 || els[1][3] !== 0 || els[2][3] !== 0) {
rightHandSide = new Vector(els.slice(0, 4)[3]);
inversePerspectiveMatrix = perspectiveMatrix.inverse();
transposedInversePerspectiveMatrix = inversePerspectiveMatrix.transpose();
perspective = transposedInversePerspectiveMatrix.multiply(rightHandSide).els;
for (i = _n = 0; _n <= 2; i = ++_n) {
els[i][3] = 0;
}
els[3][3] = 1;
} else {
perspective = [ 0, 0, 0, 1 ];
}
for (i = _o = 0; _o <= 2; i = ++_o) {
translate[i] = els[3][i];
els[3][i] = 0;
}
row = [];
for (i = _p = 0; _p <= 2; i = ++_p) {
row[i] = new Vector(els[i].slice(0, 3));
}
scale[0] = row[0].length();
row[0] = row[0].normalize();
skew[0] = row[0].dot(row[1]);
row[1] = row[1].combine(row[0], 1, -skew[0]);
scale[1] = row[1].length();
row[1] = row[1].normalize();
skew[0] /= scale[1];
skew[1] = row[0].dot(row[2]);
row[2] = row[2].combine(row[0], 1, -skew[1]);
skew[2] = row[1].dot(row[2]);
row[2] = row[2].combine(row[1], 1, -skew[2]);
scale[2] = row[2].length();
row[2] = row[2].normalize();
skew[1] /= scale[2];
skew[2] /= scale[2];
pdum3 = row[1].cross(row[2]);
if (row[0].dot(pdum3) < 0) {
for (i = _q = 0; _q <= 2; i = ++_q) {
scale[i] *= -1;
for (j = _r = 0; _r <= 2; j = ++_r) {
row[i].els[j] *= -1;
}
}
}
rowElement = function(index, elementIndex) {
return row[index].els[elementIndex];
};
rotate = [];
rotate[1] = Math.asin(-rowElement(0, 2));
if (Math.cos(rotate[1]) !== 0) {
rotate[0] = Math.atan2(rowElement(1, 2), rowElement(2, 2));
rotate[2] = Math.atan2(rowElement(0, 1), rowElement(0, 0));
} else {
rotate[0] = Math.atan2(-rowElement(2, 0), rowElement(1, 1));
rotate[1] = 0;
}
t = rowElement(0, 0) + rowElement(1, 1) + rowElement(2, 2) + 1;
if (t > 1e-4) {
s = .5 / Math.sqrt(t);
w = .25 / s;
x = (rowElement(2, 1) - rowElement(1, 2)) * s;
y = (rowElement(0, 2) - rowElement(2, 0)) * s;
z = (rowElement(1, 0) - rowElement(0, 1)) * s;
} else if (rowElement(0, 0) > rowElement(1, 1) && rowElement(0, 0) > rowElement(2, 2)) {
s = Math.sqrt(1 + rowElement(0, 0) - rowElement(1, 1) - rowElement(2, 2)) * 2;
x = .25 * s;
y = (rowElement(0, 1) + rowElement(1, 0)) / s;
z = (rowElement(0, 2) + rowElement(2, 0)) / s;
w = (rowElement(2, 1) - rowElement(1, 2)) / s;
} else if (rowElement(1, 1) > rowElement(2, 2)) {
s = Math.sqrt(1 + rowElement(1, 1) - rowElement(0, 0) - rowElement(2, 2)) * 2;
x = (rowElement(0, 1) + rowElement(1, 0)) / s;
y = .25 * s;
z = (rowElement(1, 2) + rowElement(2, 1)) / s;
w = (rowElement(0, 2) - rowElement(2, 0)) / s;
} else {
s = Math.sqrt(1 + rowElement(2, 2) - rowElement(0, 0) - rowElement(1, 1)) * 2;
x = (rowElement(0, 2) + rowElement(2, 0)) / s;
y = (rowElement(1, 2) + rowElement(2, 1)) / s;
z = .25 * s;
w = (rowElement(1, 0) - rowElement(0, 1)) / s;
}
quaternion = [ x, y, z, w ];
result = new DecomposedMatrix();
result.translate = translate;
result.scale = scale;
result.skew = skew;
result.quaternion = quaternion;
result.perspective = perspective;
result.rotate = rotate;
for (typeKey in result) {
type = result[typeKey];
for (k in type) {
v = type[k];
if (isNaN(v)) {
type[k] = 0;
}
}
}
return result;
};
Matrix.prototype.toString = function() {
var i, j, str, _i, _j;
str = "matrix3d(";
for (i = _i = 0; _i <= 3; i = ++_i) {
for (j = _j = 0; _j <= 3; j = ++_j) {
str += roundf(this.els[i][j], 10);
if (!(i === 3 && j === 3)) {
str += ",";
}
}
}
str += ")";
return str;
};
Matrix.matrixForTransform = cacheFn(function(transform) {
var matrixEl, result, style, _ref, _ref1, _ref2;
matrixEl = document.createElement("div");
matrixEl.style.position = "absolute";
matrixEl.style.visibility = "hidden";
matrixEl.style[propertyWithPrefix("transform")] = transform;
document.body.appendChild(matrixEl);
style = window.getComputedStyle(matrixEl, null);
result = (_ref = (_ref1 = style.transform) != null ? _ref1 : style[propertyWithPrefix("transform")]) != null ? _ref : (_ref2 = dynamics.tests) != null ? _ref2.matrixForTransform(transform) : void 0;
document.body.removeChild(matrixEl);
return result;
});
Matrix.fromTransform = function(transform) {
var digits, elements, i, match, matrixElements, _i;
match = transform != null ? transform.match(/matrix3?d?\(([-0-9,e \.]*)\)/) : void 0;
if (match) {
digits = match[1].split(",");
digits = digits.map(parseFloat);
if (digits.length === 6) {
elements = [ digits[0], digits[1], 0, 0, digits[2], digits[3], 0, 0, 0, 0, 1, 0, digits[4], digits[5], 0, 1 ];
} else {
elements = digits;
}
} else {
elements = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ];
}
matrixElements = [];
for (i = _i = 0; _i <= 3; i = ++_i) {
matrixElements.push(elements.slice(i * 4, i * 4 + 4));
}
return new Matrix(matrixElements);
};
return Matrix;
}();
prefixFor = cacheFn(function(property) {
var k, prefix, prop, propArray, propertyName, _i, _j, _len, _len1, _ref;
if (document.body.style[property] !== void 0) {
return "";
}
propArray = property.split("-");
propertyName = "";
for (_i = 0, _len = propArray.length; _i < _len; _i++) {
prop = propArray[_i];
propertyName += prop.substring(0, 1).toUpperCase() + prop.substring(1);
}
_ref = [ "Webkit", "Moz", "ms" ];
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
prefix = _ref[_j];
k = prefix + propertyName;
if (document.body.style[k] !== void 0) {
return prefix;
}
}
return "";
});
propertyWithPrefix = cacheFn(function(property) {
var prefix;
prefix = prefixFor(property);
if (prefix === "Moz") {
return "" + prefix + (property.substring(0, 1).toUpperCase() + property.substring(1));
}
if (prefix !== "") {
return "-" + prefix.toLowerCase() + "-" + toDashed(property);
}
return toDashed(property);
});
rAF = typeof window !== "undefined" && window !== null ? window.requestAnimationFrame : void 0;
animations = [];
animationsTimeouts = [];
slow = false;
slowRatio = 1;
if (typeof window !== "undefined" && window !== null) {
window.addEventListener("keyup", function(e) {
if (e.keyCode === 68 && e.shiftKey && e.ctrlKey) {
return dynamics.toggleSlow();
}
});
}
if (rAF == null) {
lastTime = 0;
rAF = function(callback) {
var currTime, id, timeToCall;
currTime = Date.now();
timeToCall = Math.max(0, 16 - (currTime - lastTime));
id = window.setTimeout(function() {
return callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
runLoopRunning = false;
runLoopPaused = false;
startRunLoop = function() {
if (!runLoopRunning) {
runLoopRunning = true;
return rAF(runLoopTick);
}
};
runLoopTick = function(t) {
var animation, toRemoveAnimations, _i, _len;
if (runLoopPaused) {
rAF(runLoopTick);
return;
}
toRemoveAnimations = [];
for (_i = 0, _len = animations.length; _i < _len; _i++) {
animation = animations[_i];
if (!animationTick(t, animation)) {
toRemoveAnimations.push(animation);
}
}
animations = animations.filter(function(animation) {
return toRemoveAnimations.indexOf(animation) === -1;
});
if (animations.length === 0) {
return runLoopRunning = false;
} else {
return rAF(runLoopTick);
}
};
animationTick = function(t, animation) {
var key, properties, property, tt, y, _base, _base1, _ref;
if (animation.tStart == null) {
animation.tStart = t;
}
tt = (t - animation.tStart) / animation.options.duration;
y = animation.curve(tt);
properties = {};
if (tt >= 1) {
if (animation.curve.initialForce) {
properties = animation.properties.start;
} else {
properties = animation.properties.end;
}
} else {
_ref = animation.properties.start;
for (key in _ref) {
property = _ref[key];
properties[key] = interpolate(property, animation.properties.end[key], y);
}
}
applyFrame(animation.el, properties);
if (typeof (_base = animation.options).change === "function") {
_base.change(animation.el);
}
if (tt >= 1) {
if (typeof (_base1 = animation.options).complete === "function") {
_base1.complete(animation.el);
}
}
return tt < 1;
};
interpolate = function(start, end, y) {
if (start != null && start.interpolate != null) {
return start.interpolate(end, y);
}
return null;
};
startAnimation = function(el, properties, options, timeoutId) {
var endProperties, isSVG, k, matrix, startProperties, transforms, v, _base;
if (timeoutId != null) {
animationsTimeouts = animationsTimeouts.filter(function(timeout) {
return timeout.id !== timeoutId;
});
}
dynamics.stop(el, {
timeout: false
});
if (!options.animated) {
dynamics.css(el, properties);
if (typeof options.complete === "function") {
options.complete(this);
}
return;
}
properties = parseProperties(properties);
startProperties = getCurrentProperties(el, Object.keys(properties));
endProperties = {};
transforms = [];
for (k in properties) {
v = properties[k];
if (transformProperties.contains(k)) {
transforms.push([ k, v ]);
} else {
endProperties[k] = createInterpolable(v);
if (endProperties[k] instanceof InterpolableWithUnit && el.style != null) {
endProperties[k].prefix = "";
if ((_base = endProperties[k]).suffix == null) {
_base.suffix = unitForProperty(k, 0);
}
}
}
}
if (transforms.length > 0) {
isSVG = isSVGElement(el);
if (isSVG) {
matrix = new Matrix2D();
matrix.applyProperties(transforms);
} else {
v = transforms.map(function(transform) {
return transformValueForProperty(transform[0], transform[1]);
}).join(" ");
matrix = Matrix.fromTransform(Matrix.matrixForTransform(v));
}
endProperties["transform"] = matrix.decompose();
if (isSVG) {
startProperties.transform.applyRotateCenter([ endProperties.transform.props.rotate[1], endProperties.transform.props.rotate[2] ]);
}
}
animations.push({
el: el,
properties: {
start: startProperties,
end: endProperties
},
options: options,
curve: options.type.call(options.type, options)
});
return startRunLoop();
};
timeouts = [];
timeoutLastId = 0;
setRealTimeout = function(timeout) {
if (!isDocumentVisible()) {
return;
}
return timeout.realTimeoutId = setTimeout(function() {
timeout.fn();
return cancelTimeout(timeout.id);
}, timeout.delay);
};
addTimeout = function(fn, delay) {
var timeout;
timeoutLastId += 1;
timeout = {
id: timeoutLastId,
tStart: Date.now(),
fn: fn,
delay: delay,
originalDelay: delay
};
setRealTimeout(timeout);
timeouts.push(timeout);
return timeoutLastId;
};
cancelTimeout = function(id) {
return timeouts = timeouts.filter(function(timeout) {
if (timeout.id === id) {
clearTimeout(timeout.realTimeoutId);
}
return timeout.id !== id;
});
};
leftDelayForTimeout = function(time, timeout) {
var consumedDelay;
if (time != null) {
consumedDelay = time - timeout.tStart;
return timeout.originalDelay - consumedDelay;
} else {
return timeout.originalDelay;
}
};
if (typeof window !== "undefined" && window !== null) {
window.addEventListener("unload", function() {});
}
timeBeforeVisibilityChange = null;
observeVisibilityChange(function(visible) {
var animation, difference, timeout, _i, _j, _k, _len, _len1, _len2, _results;
runLoopPaused = !visible;
if (!visible) {
timeBeforeVisibilityChange = Date.now();
_results = [];
for (_i = 0, _len = timeouts.length; _i < _len; _i++) {
timeout = timeouts[_i];
_results.push(clearTimeout(timeout.realTimeoutId));
}
return _results;
} else {
if (runLoopRunning) {
difference = Date.now() - timeBeforeVisibilityChange;
for (_j = 0, _len1 = animations.length; _j < _len1; _j++) {
animation = animations[_j];
if (animation.tStart != null) {
animation.tStart += difference;
}
}
}
for (_k = 0, _len2 = timeouts.length; _k < _len2; _k++) {
timeout = timeouts[_k];
timeout.delay = leftDelayForTimeout(timeBeforeVisibilityChange, timeout);
setRealTimeout(timeout);
}
return timeBeforeVisibilityChange = null;
}
});
dynamics = {};
dynamics.linear = function() {
return function(t) {
return t;
};
};
dynamics.spring = function(options) {
var A1, A2, decal, frequency, friction, s;
if (options == null) {
options = {};
}
applyDefaults(options, arguments.callee.defaults);
frequency = Math.max(1, options.frequency / 20);
friction = Math.pow(20, options.friction / 100);
s = options.anticipationSize / 1e3;
decal = Math.max(0, s);
A1 = function(t) {
var M, a, b, x0, x1;
M = .8;
x0 = s / (1 - s);
x1 = 0;
b = (x0 - M * x1) / (x0 - x1);
a = (M - b) / x0;
return a * t * options.anticipationStrength / 100 + b;
};
A2 = function(t) {
return Math.pow(friction / 10, -t) * (1 - t);
};
return function(t) {
var A, At, a, angle, b, frictionT, y0, yS;
frictionT = t / (1 - s) - s / (1 - s);
if (t < s) {
yS = s / (1 - s) - s / (1 - s);
y0 = 0 / (1 - s) - s / (1 - s);
b = Math.acos(1 / A1(yS));
a = (Math.acos(1 / A1(y0)) - b) / (frequency * -s);
A = A1;
} else {
A = A2;
b = 0;
a = 1;
}
At = A(frictionT);
angle = frequency * (t - s) * a + b;
return 1 - At * Math.cos(angle);
};
};
dynamics.bounce = function(options) {
var A, fn, frequency, friction;
if (options == null) {
options = {};
}
applyDefaults(options, arguments.callee.defaults);
frequency = Math.max(1, options.frequency / 20);
friction = Math.pow(20, options.friction / 100);
A = function(t) {
return Math.pow(friction / 10, -t) * (1 - t);
};
fn = function(t) {
var At, a, angle, b;
b = -3.14 / 2;
a = 1;
At = A(t);
angle = frequency * t * a + b;
return At * Math.cos(angle);
};
fn.initialForce = true;
return fn;
};
dynamics.gravity = function(options) {
var L, bounciness, curves, elasticity, fn, getPointInCurve, gravity;
if (options == null) {
options = {};
}
applyDefaults(options, arguments.callee.defaults);
bounciness = Math.min(options.bounciness / 1250, .8);
elasticity = options.elasticity / 1e3;
gravity = 100;
curves = [];
L = function() {
var b, curve;
b = Math.sqrt(2 / gravity);
curve = {
a: -b,
b: b,
H: 1
};
if (options.initialForce) {
curve.a = 0;
curve.b = curve.b * 2;
}
while (curve.H > .001) {
L = curve.b - curve.a;
curve = {
a: curve.b,
b: curve.b + L * bounciness,
H: curve.H * bounciness * bounciness
};
}
return curve.b;
}();
getPointInCurve = function(a, b, H, t) {
var c, t2;
L = b - a;
t2 = 2 / L * t - 1 - a * 2 / L;
c = t2 * t2 * H - H + 1;
if (options.initialForce) {
c = 1 - c;
}
return c;
};
(function() {
var L2, b, curve, _results;
b = Math.sqrt(2 / (gravity * L * L));
curve = {
a: -b,
b: b,
H: 1
};
if (options.initialForce) {
curve.a = 0;
curve.b = curve.b * 2;
}
curves.push(curve);
L2 = L;
_results = [];
while (curve.b < 1 && curve.H > .001) {
L2 = curve.b - curve.a;
curve = {
a: curve.b,
b: curve.b + L2 * bounciness,
H: curve.H * elasticity
};
_results.push(curves.push(curve));
}
return _results;
})();
fn = function(t) {
var curve, i, v;
i = 0;
curve = curves[i];
while (!(t >= curve.a && t <= curve.b)) {
i += 1;
curve = curves[i];
if (!curve) {
break;
}
}
if (!curve) {
v = options.initialForce ? 0 : 1;
} else {
v = getPointInCurve(curve.a, curve.b, curve.H, t);
}
return v;
};
fn.initialForce = options.initialForce;
return fn;
};
dynamics.forceWithGravity = function(options) {
if (options == null) {
options = {};
}
applyDefaults(options, arguments.callee.defaults);
options.initialForce = true;
return dynamics.gravity(options);
};
dynamics.bezier = function() {
var Bezier, Bezier_, yForX;
Bezier_ = function(t, p0, p1, p2, p3) {
return Math.pow(1 - t, 3) * p0 + 3 * Math.pow(1 - t, 2) * t * p1 + 3 * (1 - t) * Math.pow(t, 2) * p2 + Math.pow(t, 3) * p3;
};
Bezier = function(t, p0, p1, p2, p3) {
return {
x: Bezier_(t, p0.x, p1.x, p2.x, p3.x),
y: Bezier_(t, p0.y, p1.y, p2.y, p3.y)
};
};
yForX = function(xTarget, Bs, returnsToSelf) {
var B, aB, i, lower, percent, upper, x, xTolerance, _i, _len;
B = null;
for (_i = 0, _len = Bs.length; _i < _len; _i++) {
aB = Bs[_i];
if (xTarget >= aB(0).x && xTarget <= aB(1).x) {
B = aB;
}
if (B !== null) {
break;
}
}
if (!B) {
if (returnsToSelf) {
return 0;
} else {
return 1;
}
}
xTolerance = 1e-4;
lower = 0;
upper = 1;
percent = (upper + lower) / 2;
x = B(percent).x;
i = 0;
while (Math.abs(xTarget - x) > xTolerance && i < 100) {
if (xTarget > x) {
lower = percent;
} else {
upper = percent;
}
percent = (upper + lower) / 2;
x = B(percent).x;
i += 1;
}
return B(percent).y;
};
return function(options) {
var Bs, points, returnsToSelf;
if (options == null) {
options = {};
}
points = options.points;
returnsToSelf = false;
Bs = function() {
var i, k, _fn;
Bs = [];
_fn = function(pointA, pointB) {
var B2;
B2 = function(t) {
return Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB);
};
return Bs.push(B2);
};
for (i in points) {
k = parseInt(i);
if (k >= points.length - 1) {
break;
}
_fn(points[k], points[k + 1]);
}
return Bs;
}();
return function(t) {
if (t === 0) {
return 0;
} else if (t === 1) {
return 1;
} else {
return yForX(t, Bs, returnsToSelf);
}
};
};
}();
dynamics.easeInOut = function(options) {
var friction, _ref;
if (options == null) {
options = {};
}
friction = (_ref = options.friction) != null ? _ref : arguments.callee.defaults.friction;
return dynamics.bezier({
points: [ {
x: 0,
y: 0,
cp: [ {
x: .92 - friction / 1e3,
y: 0
} ]
}, {
x: 1,
y: 1,
cp: [ {
x: .08 + friction / 1e3,
y: 1
} ]
} ]
});
};
dynamics.easeIn = function(options) {
var friction, _ref;
if (options == null) {
options = {};
}
friction = (_ref = options.friction) != null ? _ref : arguments.callee.defaults.friction;
return dynamics.bezier({
points: [ {
x: 0,
y: 0,
cp: [ {
x: .92 - friction / 1e3,
y: 0
} ]
}, {
x: 1,
y: 1,
cp: [ {
x: 1,
y: 1
} ]
} ]
});
};
dynamics.easeOut = function(options) {
var friction, _ref;
if (options == null) {
options = {};
}
friction = (_ref = options.friction) != null ? _ref : arguments.callee.defaults.friction;
return dynamics.bezier({
points: [ {
x: 0,
y: 0,
cp: [ {
x: 0,
y: 0
} ]
}, {
x: 1,
y: 1,
cp: [ {
x: .08 + friction / 1e3,
y: 1
} ]
} ]
});
};
dynamics.spring.defaults = {
frequency: 300,
friction: 200,
anticipationSize: 0,
anticipationStrength: 0
};
dynamics.bounce.defaults = {
frequency: 300,
friction: 200
};
dynamics.forceWithGravity.defaults = dynamics.gravity.defaults = {
bounciness: 400,
elasticity: 200
};
dynamics.easeInOut.defaults = dynamics.easeIn.defaults = dynamics.easeOut.defaults = {
friction: 500
};
dynamics.css = makeArrayFn(function(el, properties) {
return applyProperties(el, properties, true);
});
dynamics.animate = makeArrayFn(function(el, properties, options) {
var id;
if (options == null) {
options = {};
}
options = clone(options);
applyDefaults(options, {
type: dynamics.easeInOut,
duration: 1e3,
delay: 0,
animated: true
});
options.duration = Math.max(0, options.duration * slowRatio);
options.delay = Math.max(0, options.delay);
if (options.delay === 0) {
return startAnimation(el, properties, options);
} else {
id = dynamics.setTimeout(function() {
return startAnimation(el, properties, options, id);
}, options.delay);
return animationsTimeouts.push({
id: id,
el: el
});
}
});
dynamics.stop = makeArrayFn(function(el, options) {
if (options == null) {
options = {};
}
if (options.timeout == null) {
options.timeout = true;
}
if (options.timeout) {
animationsTimeouts = animationsTimeouts.filter(function(timeout) {
if (timeout.el === el && (options.filter == null || options.filter(timeout))) {
dynamics.clearTimeout(timeout.id);
return true;
}
return false;
});
}
return animations = animations.filter(function(animation) {
return animation.el !== el;
});
});
dynamics.setTimeout = function(fn, delay) {
return addTimeout(fn, delay * slowRatio);
};
dynamics.clearTimeout = function(id) {
return cancelTimeout(id);
};
dynamics.toggleSlow = function() {
slow = !slow;
if (slow) {
slowRatio = 3;
} else {
slowRatio = 1;
}
return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log("dynamics.js: slow animations " + (slow ? "enabled" : "disabled")) : void 0 : void 0;
};
if (typeof module === "object" && typeof module.exports === "object") {
module.exports = dynamics;
} else if (typeof define === "function" && define.amd) {
define(dynamics);
} else {
window.dynamics = dynamics;
}
}).call(this);
(function() {
"use strict";
function FastClick(layer, options) {
var oldOnClick;
options = options || {};
this.trackingClick = false;
this.trackingClickStart = 0;
this.targetElement = null;
this.touchStartX = 0;
this.touchStartY = 0;
this.lastTouchIdentifier = 0;
this.touchBoundary = options.touchBoundary || 10;
this.layer = layer;
this.tapDelay = options.tapDelay || 200;
this.tapTimeout = options.tapTimeout || 700;
if (FastClick.notNeeded(layer)) {
return;
}
function bind(method, context) {
return function() {
return method.apply(context, arguments);
};
}
var methods = [ "onMouse", "onClick", "onTouchStart", "onTouchMove", "onTouchEnd", "onTouchCancel" ];
var context = this;
for (var i = 0, l = methods.length; i < l; i++) {
context[methods[i]] = bind(context[methods[i]], context);
}
if (deviceIsAndroid) {
layer.addEventListener("mouseover", this.onMouse, true);
layer.addEventListener("mousedown", this.onMouse, true);
layer.addEventListener("mouseup", this.onMouse, true);
}
layer.addEventListener("click", this.onClick, true);
layer.addEventListener("touchstart", this.onTouchStart, false);
layer.addEventListener("touchmove", this.onTouchMove, false);
layer.addEventListener("touchend", this.onTouchEnd, false);
layer.addEventListener("touchcancel", this.onTouchCancel, false);
if (!Event.prototype.stopImmediatePropagation) {
layer.removeEventListener = function(type, callback, capture) {
var rmv = Node.prototype.removeEventListener;
if (type === "click") {
rmv.call(layer, type, callback.hijacked || callback, capture);
} else {
rmv.call(layer, type, callback, capture);
}
};
layer.addEventListener = function(type, callback, capture) {
var adv = Node.prototype.addEventListener;
if (type === "click") {
adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
if (!event.propagationStopped) {
callback(event);
}
}), capture);
} else {
adv.call(layer, type, callback, capture);
}
};
}
if (typeof layer.onclick === "function") {
oldOnClick = layer.onclick;
layer.addEventListener("click", function(event) {
oldOnClick(event);
}, false);
layer.onclick = null;
}
}
var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
var deviceIsAndroid = navigator.userAgent.indexOf("Android") > 0 && !deviceIsWindowsPhone;
var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
var deviceIsIOS4 = deviceIsIOS && /OS 4_\d(_\d)?/.test(navigator.userAgent);
var deviceIsIOSWithBadTarget = deviceIsIOS && /OS [6-7]_\d/.test(navigator.userAgent);
var deviceIsBlackBerry10 = navigator.userAgent.indexOf("BB10") > 0;
FastClick.prototype.needsClick = function(target) {
switch (target.nodeName.toLowerCase()) {
case "button":
case "select":
case "textarea":
if (target.disabled) {
return true;
}
break;
case "input":
if (deviceIsIOS && target.type === "file" || target.disabled) {
return true;
}
break;
case "label":
case "iframe":
case "video":
return true;
}
return /\bneedsclick\b/.test(target.className);
};
FastClick.prototype.needsFocus = function(target) {
switch (target.nodeName.toLowerCase()) {
case "textarea":
return true;
case "select":
return !deviceIsAndroid;
case "input":
switch (target.type) {
case "button":
case "checkbox":
case "file":
case "image":
case "radio":
case "submit":
return false;
}
return !target.disabled && !target.readOnly;
default:
return /\bneedsfocus\b/.test(target.className);
}
};
FastClick.prototype.sendClick = function(targetElement, event) {
var clickEvent, touch;
if (document.activeElement && document.activeElement !== targetElement) {
document.activeElement.blur();
}
touch = event.changedTouches[0];
clickEvent = document.createEvent("MouseEvents");
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
FastClick.prototype.determineEventType = function(targetElement) {
if (deviceIsAndroid && targetElement.tagName.toLowerCase() === "select") {
return "mousedown";
}
return "click";
};
FastClick.prototype.focus = function(targetElement) {
var length;
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf("date") !== 0 && targetElement.type !== "time" && targetElement.type !== "month") {
length = targetElement.value.length;
targetElement.setSelectionRange(length, length);
} else {
targetElement.focus();
}
};
FastClick.prototype.updateScrollParent = function(targetElement) {
var scrollParent, parentElement;
scrollParent = targetElement.fastClickScrollParent;
if (!scrollParent || !scrollParent.contains(targetElement)) {
parentElement = targetElement;
do {
if (parentElement.scrollHeight > parentElement.offsetHeight) {
scrollParent = parentElement;
targetElement.fastClickScrollParent = parentElement;
break;
}
parentElement = parentElement.parentElement;
} while (parentElement);
}
if (scrollParent) {
scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
}
};
FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
if (eventTarget.nodeType === Node.TEXT_NODE) {
return eventTarget.parentNode;
}
return eventTarget;
};
FastClick.prototype.onTouchStart = function(event) {
var targetElement, touch, selection;
if (event.targetTouches.length > 1) {
return true;
}
targetElement = this.getTargetElementFromEventTarget(event.target);
touch = event.targetTouches[0];
if (deviceIsIOS) {
selection = window.getSelection();
if (selection.rangeCount && !selection.isCollapsed) {
return true;
}
if (!deviceIsIOS4) {
if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
event.preventDefault();
return false;
}
this.lastTouchIdentifier = touch.identifier;
this.updateScrollParent(targetElement);
}
}
this.trackingClick = true;
this.trackingClickStart = event.timeStamp;
this.targetElement = targetElement;
this.touchStartX = touch.pageX;
this.touchStartY = touch.pageY;
if (event.timeStamp - this.lastClickTime < this.tapDelay) {
event.preventDefault();
}
return true;
};
FastClick.prototype.touchHasMoved = function(event) {
var touch = event.changedTouches[0], boundary = this.touchBoundary;
if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
return true;
}
return false;
};
FastClick.prototype.onTouchMove = function(event) {
if (!this.trackingClick) {
return true;
}
if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
this.trackingClick = false;
this.targetElement = null;
}
return true;
};
FastClick.prototype.findControl = function(labelElement) {
if (labelElement.control !== undefined) {
return labelElement.control;
}
if (labelElement.htmlFor) {
return document.getElementById(labelElement.htmlFor);
}
return labelElement.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea");
};
FastClick.prototype.onTouchEnd = function(event) {
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
if (!this.trackingClick) {
return true;
}
if (event.timeStamp - this.lastClickTime < this.tapDelay) {
this.cancelNextClick = true;
return true;
}
if (event.timeStamp - this.trackingClickStart > this.tapTimeout) {
return true;
}
this.cancelNextClick = false;
this.lastClickTime = event.timeStamp;
trackingClickStart = this.trackingClickStart;
this.trackingClick = false;
this.trackingClickStart = 0;
if (deviceIsIOSWithBadTarget) {
touch = event.changedTouches[0];
targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
}
targetTagName = targetElement.tagName.toLowerCase();
if (targetTagName === "label") {
forElement = this.findControl(targetElement);
if (forElement) {
this.focus(targetElement);
if (deviceIsAndroid) {
return false;
}
targetElement = forElement;
}
} else if (this.needsFocus(targetElement)) {
if (event.timeStamp - trackingClickStart > 100 || deviceIsIOS && window.top !== window && targetTagName === "input") {
this.targetElement = null;
return false;
}
this.focus(targetElement);
this.sendClick(targetElement, event);
if (!deviceIsIOS || targetTagName !== "select") {
this.targetElement = null;
event.preventDefault();
}
return false;
}
if (deviceIsIOS && !deviceIsIOS4) {
scrollParent = targetElement.fastClickScrollParent;
if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
return true;
}
}
if (!this.needsClick(targetElement)) {
event.preventDefault();
this.sendClick(targetElement, event);
}
return false;
};
FastClick.prototype.onTouchCancel = function() {
this.trackingClick = false;
this.targetElement = null;
};
FastClick.prototype.onMouse = function(event) {
if (!this.targetElement) {
return true;
}
if (event.forwardedTouchEvent) {
return true;
}
if (!event.cancelable) {
return true;
}
if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
if (event.stopImmediatePropagation) {
event.stopImmediatePropagation();
} else {
event.propagationStopped = true;
}
event.stopPropagation();
event.preventDefault();
return false;
}
return true;
};
FastClick.prototype.onClick = function(event) {
var permitted;
if (this.trackingClick) {
this.targetElement = null;
this.trackingClick = false;
return true;
}
if (event.target.type === "submit" && event.detail === 0) {
return true;
}
permitted = this.onMouse(event);
if (!permitted) {
this.targetElement = null;
}
return permitted;
};
FastClick.prototype.destroy = function() {
var layer = this.layer;
if (deviceIsAndroid) {
layer.removeEventListener("mouseover", this.onMouse, true);
layer.removeEventListener("mousedown", this.onMouse, true);
layer.removeEventListener("mouseup", this.onMouse, true);
}
layer.removeEventListener("click", this.onClick, true);
layer.removeEventListener("touchstart", this.onTouchStart, false);
layer.removeEventListener("touchmove", this.onTouchMove, false);
layer.removeEventListener("touchend", this.onTouchEnd, false);
layer.removeEventListener("touchcancel", this.onTouchCancel, false);
};
FastClick.notNeeded = function(layer) {
var metaViewport;
var chromeVersion;
var blackberryVersion;
var firefoxVersion;
if (typeof window.ontouchstart === "undefined") {
return true;
}
chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [ , 0 ])[1];
if (chromeVersion) {
if (deviceIsAndroid) {
metaViewport = document.querySelector("meta[name=viewport]");
if (metaViewport) {
if (metaViewport.content.indexOf("user-scalable=no") !== -1) {
return true;
}
if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
} else {
return true;
}
}
if (deviceIsBlackBerry10) {
blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
metaViewport = document.querySelector("meta[name=viewport]");
if (metaViewport) {
if (metaViewport.content.indexOf("user-scalable=no") !== -1) {
return true;
}
if (document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
}
}
if (layer.style.msTouchAction === "none" || layer.style.touchAction === "manipulation") {
return true;
}
firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [ , 0 ])[1];
if (firefoxVersion >= 27) {
metaViewport = document.querySelector("meta[name=viewport]");
if (metaViewport && (metaViewport.content.indexOf("user-scalable=no") !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
return true;
}
}
if (layer.style.touchAction === "none" || layer.style.touchAction === "manipulation") {
return true;
}
return false;
};
FastClick.attach = function(layer, options) {
return new FastClick(layer, options);
};
if (typeof define === "function" && typeof define.amd === "object" && define.amd) {
define(function() {
return FastClick;
});
} else if (typeof module !== "undefined" && module.exports) {
module.exports = FastClick.attach;
module.exports.FastClick = FastClick;
} else {
window.FastClick = FastClick;
}
})();