//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More = {
    version: "1.2.3.1"
};
(function() {
    var a = {
        language: "en-US",
        languages: {
            "en-US": {}
        },
        cascades: ["en-US"]
    };
    var b;
    MooTools.lang = new Events();
    $extend(MooTools.lang, {
        setLanguage: function(c) {
            if (!a.languages[c]) {
                return this;
            }
            a.language = c;
            this.load();
            this.fireEvent("langChange", c);
            return this;
        },
        load: function() {
            var c = this.cascade(this.getCurrentLanguage());
            b = {};
            $each(c, function(e, d) {
                b[d] = this.lambda(e);
            }, this);
        },
        getCurrentLanguage: function() {
            return a.language;
        },
        addLanguage: function(c) {
            a.languages[c] = a.languages[c] || {};
            return this;
        },
        cascade: function(e) {
            var c = (a.languages[e] || {}).cascades || [];
            c.combine(a.cascades);
            c.erase(e).push(e);
            var d = c.map(function(f) {
                return a.languages[f];
            }, this);
            return $merge.apply(this, d);
        },
        lambda: function(c) {
            (c || {}).get = function(e, d) {
                return $lambda(c[e]).apply(this, $splat(d));
            };
            return c;
        },
        get: function(e, d, c) {
            if (b && b[e]) {
                return (d ? b[e].get(d, c) : b[e]);
            }
        },
        set: function(d, e, c) {
            this.addLanguage(d);
            langData = a.languages[d];
            if (!langData[e]) {
                langData[e] = {};
            }
            $extend(langData[e], c);
            if (d == this.getCurrentLanguage()) {
                this.load();
                this.fireEvent("langChange", d);
            }
            return this;
        },
        list: function() {
            return Hash.getKeys(a.languages);
        }
    });
})();
Class.Mutators.Binds = function(a) {
    return a;
};
Class.Mutators.initialize = function(a) {
    return function() {
        $splat(this.Binds).each(function(b) {
            var c = this[b];
            if (c) {
                this[b] = c.bind(this);
            }
        }, this);
        return a.apply(this, arguments);
    };
};
Class.Occlude = new Class({

	occlude: function(property, element){
		element = document.id(element || this.element);
		var instance = element.retrieve(property || this.property);
		if (instance && !$defined(this.occluded))
			return this.occluded = instance;

		this.occluded = false;
		element.store(property || this.property, this);
		return this.occluded;
	}

});
String.implement({

	parseQueryString: function(){
		var vars = this.split(/[&;]/), res = {};
		if (vars.length) vars.each(function(val){
			var index = val.indexOf('='),
				keys = index < 0 ? [''] : val.substr(0, index).match(/[^\]\[]+/g),
				value = decodeURIComponent(val.substr(index + 1)),
				obj = res;
			keys.each(function(key, i){
				var current = obj[key];
				if(i < keys.length - 1)
					obj = obj[key] = current || {};
				else if($type(current) == 'array')
					current.push(value);
				else
					obj[key] = $defined(current) ? [current, value] : value;
			});
		});
		return res;
	},

	cleanQueryString: function(method){
		return this.split('&').filter(function(val){
			var index = val.indexOf('='),
			key = index < 0 ? '' : val.substr(0, index),
			value = val.substr(index + 1);
			return method ? method.run([key, value]) : $chk(value);
		}).join('&');
	}

});

Element.implement({
    measure: function(e) {
        var g = function(h) {
            return !!(!h || h.offsetHeight || h.offsetWidth);
        };
        if (g(this)) {
            return e.apply(this);
        }
        var d = this.getParent(), b = [], f = [];
        while (!g(d) && d != document.body) {
            b.push(d.expose());
            d = d.getParent();
        }
        var c = this.expose();
        var a = e.apply(this);
        c();
        b.each(function(h) {
            h();
        });
        return a;
    },
    expose: function() {
        if (this.getStyle("display") != "none") {
            return $empty;
        }
        var a = this.style.cssText;
        this.setStyles({
            display: "block",
            position: "absolute",
            visibility: "hidden"
        });
        return function() {
            this.style.cssText = a;
        }
.bind(this);
    },
    getDimensions: function(a) {
        a = $merge({
            computeSize: false
        }, a);
        var d = {};
        var c = function(f, e) {
            return (e.computeSize) ? f.getComputedSize(e) : f.getSize();
        };
        if (this.getStyle("display") == "none") {
            d = this.measure(function() {
                return c(this, a);
            });
        }
        else {
            try {
                d = c(this, a);
            } 
            catch (b) {
            }
        }
        return $chk(d.x) ? $extend(d, {
            width: d.x,
            height: d.y
        }) : $extend(d, {
            x: d.width,
            y: d.height
        });
    },
    getComputedSize: function(a) {
        a = $merge({
            styles: ["padding", "border"],
            plains: {
                height: ["top", "bottom"],
                width: ["left", "right"]
            },
            mode: "both"
        }, a);
        var c = {
            width: 0,
            height: 0
        };
        switch (a.mode) {
            case "vertical":
                delete c.width;
                delete a.plains.width;
                break;
            case "horizontal":
                delete c.height;
                delete a.plains.height;
                break;
        }
        var b = [];
        $each(a.plains, function(g, f) {
            g.each(function(h) {
                a.styles.each(function(i) {
                    b.push((i == "border") ? i + "-" + h + "-width" : i + "-" + h);
                });
            });
        });
        var e = {};
        b.each(function(f) {
            e[f] = this.getComputedStyle(f);
        }, this);
        var d = [];
        $each(a.plains, function(g, f) {
            var h = f.capitalize();
            c["total" + h] = 0;
            c["computed" + h] = 0;
            g.each(function(i) {
                c["computed" + i.capitalize()] = 0;
                b.each(function(k, j) {
                    if (k.test(i)) {
                        e[k] = e[k].toInt() || 0;
                        c["total" + h] = c["total" + h] + e[k];
                        c["computed" + i.capitalize()] = c["computed" + i.capitalize()] + e[k];
                    }
                    if (k.test(i) && f != k && (k.test("border") || k.test("padding")) && !d.contains(k)) {
                        d.push(k);
                        c["computed" + h] = c["computed" + h] - e[k];
                    }
                });
            });
        });
        ["Width", "Height"].each(function(g) {
            var f = g.toLowerCase();
            if (!$chk(c[f])) {
                return;
            }
            c[f] = c[f] + this["offset" + g] + c["computed" + g];
            c["total" + g] = c[f] + c["total" + g];
            delete c["computed" + g];
        }, this);
        return $extend(e, c);
    }
});
(function() {
    var a = Element.prototype.position;
    Element.implement({
        position: function(r) {
            if (r && ($defined(r.x) || $defined(r.y))) {
                return a ? a.apply(this, arguments) : this;
            }
            $each(r || {}, function(t, s) {
                if (!$defined(t)) {
                    delete r[s];
                }
            });
            r = $merge({
                relativeTo: document.body,
                position: {
                    x: "center",
                    y: "center"
                },
                edge: false,
                offset: {
                    x: 0,
                    y: 0
                },
                returnPos: false,
                relFixedPosition: false,
                ignoreMargins: false,
                allowNegative: false
            }, r);
            var b = {
                x: 0,
                y: 0
            };
            var h = false;
            var c = this.measure(function() {
                return document.id(this.getOffsetParent());
            });
            if (c && c != this.getDocument().body) {
                b = c.measure(function() {
                    return this.getPosition();
                });
                h = true;
                r.offset.x = r.offset.x - b.x;
                r.offset.y = r.offset.y - b.y;
            }
            var q = function(s) {
                if ($type(s) != "string") {
                    return s;
                }
                s = s.toLowerCase();
                var t = {};
                if (s.test("left")) {
                    t.x = "left";
                }
                else {
                    if (s.test("right")) {
                        t.x = "right";
                    }
                    else {
                        t.x = "center";
                    }
                }
                if (s.test("upper") || s.test("top")) {
                    t.y = "top";
                }
                else {
                    if (s.test("bottom")) {
                        t.y = "bottom";
                    }
                    else {
                        t.y = "center";
                    }
                }
                return t;
            };
            r.edge = q(r.edge);
            r.position = q(r.position);
            if (!r.edge) {
                if (r.position.x == "center" && r.position.y == "center") {
                    r.edge = {
                        x: "center",
                        y: "center"
                    };
                }
                else {
                    r.edge = {
                        x: "left",
                        y: "top"
                    };
                }
            }
            this.setStyle("position", "absolute");
            var p = document.id(r.relativeTo) || document.body;
            var i = p == document.body ? window.getScroll() : p.getPosition();
            var o = i.y;
            var g = i.x;
            if (Browser.Engine.trident) {
                var l = p.getScrolls();
                o += l.y;
                g += l.x;
            }
            var j = this.getDimensions({
                computeSize: true,
                styles: ["padding", "border", "margin"]
            });
            if (r.ignoreMargins) {
                r.offset.x = r.offset.x - j["margin-left"];
                r.offset.y = r.offset.y - j["margin-top"];
            }
            var n = {};
            var d = r.offset.y;
            var e = r.offset.x;
            var k = window.getSize();
            switch (r.position.x) {
                case "left":
                    n.x = g + e;
                    break;
                case "right":
                    n.x = g + e + p.offsetWidth;
                    break;
                default:
                    n.x = g + ((p == document.body ? k.x : p.offsetWidth) / 2) + e;
                    break;
            }
            switch (r.position.y) {
                case "top":
                    n.y = o + d;
                    break;
                case "bottom":
                    n.y = o + d + p.offsetHeight;
                    break;
                default:
                    n.y = o + ((p == document.body ? k.y : p.offsetHeight) / 2) + d;
                    break;
            }
            if (r.edge) {
                var m = {};
                switch (r.edge.x) {
                    case "left":
                        m.x = 0;
                        break;
                    case "right":
                        m.x = -j.x - j.computedRight - j.computedLeft;
                        break;
                    default:
                        m.x = -(j.x / 2);
                        break;
                }
                switch (r.edge.y) {
                    case "top":
                        m.y = 0;
                        break;
                    case "bottom":
                        m.y = -j.y - j.computedTop - j.computedBottom;
                        break;
                    default:
                        m.y = -(j.y / 2);
                        break;
                }
                n.x = n.x + m.x;
                n.y = n.y + m.y;
            }
            n = {
                left: ((n.x >= 0 || h || r.allowNegative) ? n.x : 0).toInt(),
                top: ((n.y >= 0 || h || r.allowNegative) ? n.y : 0).toInt()
            };
            if (p.getStyle("position") == "fixed" || r.relFixedPosition) {
                var f = window.getScroll();
                n.top = n.top.toInt() + f.y;
                n.left = n.left.toInt() + f.x;
            }
            if (r.returnPos) {
                return n;
            }
            else {
                this.setStyles(n);
            }
            return this;
        }
    });
})();
Element.implement({
    isDisplayed: function() {
        return this.getStyle("display") != "none";
    },
    toggle: function() {
        return this[this.isDisplayed() ? "hide" : "show"]();
    },
    hide: function() {
        var b;
        try {
            if ("none" != this.getStyle("display")) {
                b = this.getStyle("display");
            }
        } 
        catch (a) {
        }
        return this.store("originalDisplay", b || "block").setStyle("display", "none");
    },
    show: function(a) {
        return this.setStyle("display", a || this.retrieve("originalDisplay") || "block");
    },
    swapClass: function(a, b) {
        return this.removeClass(a).addClass(b);
    }
});
if (!window.Form) window.Form = {};

(function(){

	Form.Request = new Class({

		Binds: ['onSubmit', 'onFormValidate'],

		Implements: [Options, Events, Class.Occlude],

		options: {
			//onFailure: $empty,
			//onSuccess: #empty, //aliased to onComplete,
			//onSend: $empty
			requestOptions: {
				evalScripts: true,
				useSpinner: true,
				emulation: false,
				link: 'ignore'
			},
			extraData: {},
			resetForm: true
		},

		property: 'form.request',

		initialize: function(form, update, options) {
			this.element = document.id(form);
			if (this.occlude()) return this.occluded;
			this.update = document.id(update);
			this.setOptions(options);
			this.makeRequest();
			if (this.options.resetForm) {
				this.request.addEvent('success', function(){
					$try(function(){ this.element.reset(); }.bind(this));
					if (window.OverText) OverText.update();
				}.bind(this));
			}
			this.attach();
		},

		toElement: function() {
			return this.element;
		},

		makeRequest: function(){
			this.request = new Request.HTML($merge({
					update: this.update,
					emulation: false,
					spinnerTarget: this.element,
					method: this.element.get('method') || 'post'
			}, this.options.requestOptions)).addEvents({
				success: function(text, xml){
					['complete', 'success'].each(function(evt){
						this.fireEvent(evt, [this.update, text, xml]);
					}, this);
				}.bind(this),
				failure: function(xhr){
					this.fireEvent('complete').fireEvent('failure', xhr);
				}.bind(this),
				exception: function(){
					this.fireEvent('failure', xhr);
				}.bind(this)
			});
		},

		attach: function(attach){
			attach = $pick(attach, true);
			method = attach ? 'addEvent' : 'removeEvent';
			
			var fv = this.element.retrieve('validator');
			if (fv) fv[method]('onFormValidate', this.onFormValidate);
			if (!fv || !attach) this.element[method]('submit', this.onSubmit);
		},

		detach: function(){
			this.attach(false);
		},

		//public method
		enable: function(){
			this.attach();
		},

		//public method
		disable: function(){
			this.detach();
		},

		onFormValidate: function(valid, form, e) {
			var fv = this.element.retrieve('validator');
			if (valid || (fv && !fv.options.stopOnFailure)) {
				if (e && e.stop) e.stop();
				this.send();
			}
		},

		onSubmit: function(e){
			if (this.element.retrieve('validator')) {
				//form validator was created after Form.Request
				this.detach();
				return;
			}
			e.stop();
			this.send();
		},

		send: function(){
			var str = this.element.toQueryString().trim();
			var data = $H(this.options.extraData).toQueryString();
			if (str) str += "&" + data;
			else str = data;
			this.fireEvent('send', [this.element, str.parseQueryString()]);
			this.request.send({data: str, url: this.element.get("action")});
			return this;
		}

	});

	Element.Properties.formRequest = {

		set: function(){
			var opt = Array.link(arguments, {options: Object.type, update: Element.type, updateId: String.type});
			var update = opt.update || opt.updateId;
			var updater = this.retrieve('form.request');
			if (update) {
				if (updater) updater.update = document.id(update);
				this.store('form.request:update', update);
			}
			if (opt.options) {
				if (updater) updater.setOptions(opt.options);
				this.store('form.request:options', opt.options);
			}
			return this;
		},

		get: function(){
			var opt = Array.link(arguments, {options: Object.type, update: Element.type, updateId: String.type});
			var update = opt.update || opt.updateId;
			if (opt.options || update || !this.retrieve('form.request')){
				if (opt.options || !this.retrieve('form.request:options')) this.set('form.request', opt.options);
				if (update) this.set('form.request', update);
				this.store('form.request', new Form.Request(this, this.retrieve('form.request:update'), this.retrieve('form.request:options')));
			}
			return this.retrieve('form.request');
		}

	};

	Element.implement({

		formUpdate: function(update, options){
			this.get('form.request', update, options).send();
			return this;
		}

	});

})();
Fx.Elements = new Class({
    Extends: Fx.CSS,
    initialize: function(b, a) {
        this.elements = this.subject = $$(b);
        this.parent(a);
    },
    compute: function(g, h, j) {
        var c = {};
        for (var d in g) {
            var a = g[d], e = h[d], f = c[d] = {};
            for (var b in a) {
                f[b] = this.parent(a[b], e[b], j);
            }
        }
        return c;
    },
    set: function(b) {
        for (var c in b) {
            var a = b[c];
            for (var d in a) {
                this.render(this.elements[c], d, a[d], this.options.unit);
            }
        }
        return this;
    },
    start: function(c) {
        if (!this.check(c)) {
            return this;
        }
        var h = {}, j = {};
        for (var d in c) {
            var f = c[d], a = h[d] = {}, g = j[d] = {};
            for (var b in f) {
                var e = this.prepare(this.elements[d], b, f[b]);
                a[b] = e.from;
                g[b] = e.to;
            }
        }
        return this.parent(h, j);
    }
});
var Accordion = Fx.Accordion = new Class({
    Extends: Fx.Elements,
    options: {
        display: 0,
        show: false,
        height: true,
        width: false,
        opacity: true,
        fixedHeight: false,
        fixedWidth: false,
        wait: false,
        alwaysHide: false,
        trigger: "click",
        initialDisplayFx: true
    },
    initialize: function() {
        var c = Array.link(arguments, {
            container: Element.type,
            options: Object.type,
            togglers: $defined,
            elements: $defined
        });
        this.parent(c.elements, c.options);
        this.togglers = $$(c.togglers);
        this.container = document.id(c.container);
        this.previous = -1;
        if (this.options.alwaysHide) {
            this.options.wait = true;
        }
        if ($chk(this.options.show)) {
            this.options.display = false;
            this.previous = this.options.show;
        }
        if (this.options.start) {
            this.options.display = false;
            this.options.show = false;
        }
        this.effects = {};
        if (this.options.opacity) {
            this.effects.opacity = "fullOpacity";
        }
        if (this.options.width) {
            this.effects.width = this.options.fixedWidth ? "fullWidth" : "offsetWidth";
        }
        if (this.options.height) {
            this.effects.height = this.options.fixedHeight ? "fullHeight" : "scrollHeight";
        }
        for (var b = 0, a = this.togglers.length; b < a; b++) {
            this.addSection(this.togglers[b], this.elements[b]);
        }
        this.elements.each(function(e, d) {
            if (this.options.show === d) {
                this.fireEvent("active", [this.togglers[d], e]);
            }
            else {
                for (var f in this.effects) {
                    e.setStyle(f, 0);
                }
            }
        }, this);
        if ($chk(this.options.display)) {
            this.display(this.options.display, this.options.initialDisplayFx);
        }
    },
    addSection: function(d, b) {
        d = document.id(d);
        b = document.id(b);
        var e = this.togglers.contains(d);
        this.togglers.include(d);
        this.elements.include(b);
        var a = this.togglers.indexOf(d);
        d.addEvent(this.options.trigger, this.display.bind(this, a));
        if (this.options.height) {
            b.setStyles({
                "padding-top": 0,
                "border-top": "none",
                "padding-bottom": 0,
                "border-bottom": "none"
            });
        }
        if (this.options.width) {
            b.setStyles({
                "padding-left": 0,
                "border-left": "none",
                "padding-right": 0,
                "border-right": "none"
            });
        }
        b.fullOpacity = 1;
        if (this.options.fixedWidth) {
            b.fullWidth = this.options.fixedWidth;
        }
        if (this.options.fixedHeight) {
            b.fullHeight = this.options.fixedHeight;
        }
        b.setStyle("overflow", "hidden");
        if (!e) {
            for (var c in this.effects) {
                b.setStyle(c, 0);
            }
        }
        return this;
    },
    display: function(a, b) {
        b = $pick(b, true);
        a = ($type(a) == "element") ? this.elements.indexOf(a) : a;
        if ((this.timer && this.options.wait) || (a === this.previous && !this.options.alwaysHide)) {
            return this;
        }
        this.previous = a;
        var c = {};
        this.elements.each(function(f, e) {
            c[e] = {};
            var d = (e != a) || (this.options.alwaysHide && (f.offsetHeight > 0));
            this.fireEvent(d ? "background" : "active", [this.togglers[e], f]);
            for (var g in this.effects) {
                c[e][g] = d ? 0 : f[this.effects[g]];
            }
        }, this);
        return b ? this.start(c) : this.set(c);
    }
});
Fx.Move = new Class({
    Extends: Fx.Morph,
    options: {
        relativeTo: document.body,
        position: "center",
        edge: false,
        offset: {
            x: 0,
            y: 0
        }
    },
    start: function(a) {
        return this.parent(this.element.position($merge(this.options, a, {
            returnPos: true
        })));
    }
});
Element.Properties.move = {
    set: function(a) {
        var b = this.retrieve("move");
        if (b) {
            b.cancel();
        }
        return this.eliminate("move").store("move:options", $extend({
            link: "cancel"
        }, a));
    },
    get: function(a) {
        if (a || !this.retrieve("move")) {
            if (a || !this.retrieve("move:options")) {
                this.set("move", a);
            }
            this.store("move", new Fx.Move(this, this.retrieve("move:options")));
        }
        return this.retrieve("move");
    }
};
Element.implement({
    move: function(a) {
        this.get("move").start(a);
        return this;
    }
});
Fx.Reveal = new Class({
    Extends: Fx.Morph,
    options: {
        styles: ["padding", "border", "margin"],
        transitionOpacity: !Browser.Engine.trident4,
        mode: "vertical",
        display: "block",
        hideInputs: Browser.Engine.trident ? "select, input, textarea, object, embed" : false
    },
    dissolve: function() {
        try {
            if (!this.hiding && !this.showing) {
                if (this.element.getStyle("display") != "none") {
                    this.hiding = true;
                    this.showing = false;
                    this.hidden = true;
                    var d = this.element.getComputedSize({
                        styles: this.options.styles,
                        mode: this.options.mode
                    });
                    var g = (this.element.style.height === "" || this.element.style.height == "auto");
                    this.element.setStyle("display", "block");
                    if (this.options.transitionOpacity) {
                        d.opacity = 1;
                    }
                    var b = {};
                    $each(d, function(h, e) {
                        b[e] = [h, 0];
                    }, this);
                    var f = this.element.getStyle("overflow");
                    this.element.setStyle("overflow", "hidden");
                    var a = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
                    this.$chain.unshift(function() {
                        if (this.hidden) {
                            this.hiding = false;
                            $each(d, function(h, e) {
                                d[e] = h;
                            }, this);
                            this.element.setStyles($merge({
                                display: "none",
                                overflow: f
                            }, d));
                            if (g) {
                                if (["vertical", "both"].contains(this.options.mode)) {
                                    this.element.style.height = "";
                                }
                                if (["width", "both"].contains(this.options.mode)) {
                                    this.element.style.width = "";
                                }
                            }
                            if (a) {
                                a.setStyle("visibility", "visible");
                            }
                        }
                        this.fireEvent("hide", this.element);
                        this.callChain();
                    }
.bind(this));
                    if (a) {
                        a.setStyle("visibility", "hidden");
                    }
                    this.start(b);
                }
                else {
                    this.callChain.delay(10, this);
                    this.fireEvent("complete", this.element);
                    this.fireEvent("hide", this.element);
                }
            }
            else {
                if (this.options.link == "chain") {
                    this.chain(this.dissolve.bind(this));
                }
                else {
                    if (this.options.link == "cancel" && !this.hiding) {
                        this.cancel();
                        this.dissolve();
                    }
                }
            }
        } 
        catch (c) {
            this.hiding = false;
            this.element.setStyle("display", "none");
            this.callChain.delay(10, this);
            this.fireEvent("complete", this.element);
            this.fireEvent("hide", this.element);
        }
        return this;
    },
    reveal: function() {
        try {
            if (!this.showing && !this.hiding) {
                if (this.element.getStyle("display") == "none" || this.element.getStyle("visiblity") == "hidden" || this.element.getStyle("opacity") == 0) {
                    this.showing = true;
                    this.hiding = false;
                    this.hidden = false;
                    var g, d;
                    this.element.measure(function() {
                        g = (this.element.style.height === "" || this.element.style.height == "auto");
                        d = this.element.getComputedSize({
                            styles: this.options.styles,
                            mode: this.options.mode
                        });
                    }
.bind(this));
                    $each(d, function(h, e) {
                        d[e] = h;
                    });
                    if ($chk(this.options.heightOverride)) {
                        d.height = this.options.heightOverride.toInt();
                    }
                    if ($chk(this.options.widthOverride)) {
                        d.width = this.options.widthOverride.toInt();
                    }
                    if (this.options.transitionOpacity) {
                        this.element.setStyle("opacity", 0);
                        d.opacity = 1;
                    }
                    var b = {
                        height: 0,
                        display: this.options.display
                    };
                    $each(d, function(h, e) {
                        b[e] = 0;
                    });
                    var f = this.element.getStyle("overflow");
                    this.element.setStyles($merge(b, {
                        overflow: "hidden"
                    }));
                    var a = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
                    if (a) {
                        a.setStyle("visibility", "hidden");
                    }
                    this.start(d);
                    this.$chain.unshift(function() {
                        this.element.setStyle("overflow", f);
                        if (!this.options.heightOverride && g) {
                            if (["vertical", "both"].contains(this.options.mode)) {
                                this.element.style.height = "";
                            }
                            if (["width", "both"].contains(this.options.mode)) {
                                this.element.style.width = "";
                            }
                        }
                        if (!this.hidden) {
                            this.showing = false;
                        }
                        if (a) {
                            a.setStyle("visibility", "visible");
                        }
                        this.callChain();
                        this.fireEvent("show", this.element);
                    }
.bind(this));
                }
                else {
                    this.callChain();
                    this.fireEvent("complete", this.element);
                    this.fireEvent("show", this.element);
                }
            }
            else {
                if (this.options.link == "chain") {
                    this.chain(this.reveal.bind(this));
                }
                else {
                    if (this.options.link == "cancel" && !this.showing) {
                        this.cancel();
                        this.reveal();
                    }
                }
            }
        } 
        catch (c) {
            this.element.setStyles({
                display: this.options.display,
                visiblity: "visible",
                opacity: 1
            });
            this.showing = false;
            this.callChain.delay(10, this);
            this.fireEvent("complete", this.element);
            this.fireEvent("show", this.element);
        }
        return this;
    },
    toggle: function() {
        if (this.element.getStyle("display") == "none" || this.element.getStyle("visiblity") == "hidden" || this.element.getStyle("opacity") == 0) {
            this.reveal();
        }
        else {
            this.dissolve();
        }
        return this;
    }
});
Element.Properties.reveal = {
    set: function(a) {
        var b = this.retrieve("reveal");
        if (b) {
            b.cancel();
        }
        return this.eliminate("reveal").store("reveal:options", $extend({
            link: "cancel"
        }, a));
    },
    get: function(a) {
        if (a || !this.retrieve("reveal")) {
            if (a || !this.retrieve("reveal:options")) {
                this.set("reveal", a);
            }
            this.store("reveal", new Fx.Reveal(this, this.retrieve("reveal:options")));
        }
        return this.retrieve("reveal");
    }
};
Element.Properties.dissolve = Element.Properties.reveal;
Element.implement({
    reveal: function(a) {
        this.get("reveal", a).reveal();
        return this;
    },
    dissolve: function(a) {
        this.get("reveal", a).dissolve();
        return this;
    },
    nix: function() {
        var a = Array.link(arguments, {
            destroy: Boolean.type,
            options: Object.type
        });
        this.get("reveal", a.options).dissolve().chain(function() {
            this[a.destroy ? "destroy" : "dispose"]();
        }
.bind(this));
        return this;
    },
    wink: function() {
        var b = Array.link(arguments, {
            duration: Number.type,
            options: Object.type
        });
        var a = this.get("reveal", b.options);
        a.reveal().chain(function() {
            (function() {
                a.dissolve();
            }).delay(b.duration || 2000);
        });
    }
});
Fx.Scroll = new Class({
    Extends: Fx,
    options: {
        offset: {
            x: 0,
            y: 0
        },
        wheelStops: true
    },
    initialize: function(b, a) {
        this.element = this.subject = document.id(b);
        this.parent(a);
        var d = this.cancel.bind(this, false);
        if ($type(this.element) != "element") {
            this.element = document.id(this.element.getDocument().body);
        }
        var c = this.element;
        if (this.options.wheelStops) {
            this.addEvent("start", function() {
                c.addEvent("mousewheel", d);
            }, true);
            this.addEvent("complete", function() {
                c.removeEvent("mousewheel", d);
            }, true);
        }
    },
    set: function() {
        var a = Array.flatten(arguments);
        this.element.scrollTo(a[0], a[1]);
    },
    compute: function(c, b, a) {
        return [0, 1].map(function(d) {
            return Fx.compute(c[d], b[d], a);
        });
    },
    start: function(c, h) {
        if (!this.check(c, h)) {
            return this;
        }
        var e = this.element.getSize(), f = this.element.getScrollSize();
        var b = this.element.getScroll(), d = {
            x: c,
            y: h
        };
        for (var g in d) {
            var a = f[g] - e[g];
            if ($chk(d[g])) {
                d[g] = ($type(d[g]) == "number") ? d[g].limit(0, a) : a;
            }
            else {
                d[g] = b[g];
            }
            d[g] += this.options.offset[g];
        }
        return this.parent([b.x, b.y], [d.x, d.y]);
    },
    toTop: function() {
        return this.start(false, 0);
    },
    toLeft: function() {
        return this.start(0, false);
    },
    toRight: function() {
        return this.start("right", false);
    },
    toBottom: function() {
        return this.start(false, "bottom");
    },
    toElement: function(b) {
        var a = document.id(b).getPosition(this.element);
        return this.start(a.x, a.y);
    },
    scrollIntoView: function(c, e, d) {
        e = e ? $splat(e) : ["x", "y"];
        var h = {};
        c = document.id(c);
        var f = c.getPosition(this.element);
        var i = c.getSize();
        var g = this.element.getScroll();
        var a = this.element.getSize();
        var b = {
            x: f.x + i.x,
            y: f.y + i.y
        };
        ["x", "y"].each(function(j) {
            if (e.contains(j)) {
                if (b[j] > g[j] + a[j]) {
                    h[j] = b[j] - a[j];
                }
                if (f[j] < g[j]) {
                    h[j] = f[j];
                }
            }
            if (h[j] == null) {
                h[j] = g[j];
            }
            if (d && d[j]) {
                h[j] = h[j] + d[j];
            }
        }, this);
        if (h.x != g.x || h.y != g.y) {
            this.start(h.x, h.y);
        }
        return this;
    }
});
Fx.Slide = new Class({
    Extends: Fx,
    options: {
        mode: "vertical"
    },
    initialize: function(b, a) {
        this.addEvent("complete", function() {
            this.open = (this.wrapper["offset" + this.layout.capitalize()] != 0);
            if (this.open && Browser.Engine.webkit419) {
                this.element.dispose().inject(this.wrapper);
            }
        }, true);
        this.element = this.subject = document.id(b);
        this.parent(a);
        var c = this.element.retrieve("wrapper");
        this.wrapper = c || new Element("div", {
            styles: $extend(this.element.getStyles("margin", "position"), {
                overflow: "hidden"
            })
        }).wraps(this.element);
        this.element.store("wrapper", this.wrapper).setStyle("margin", 0);
        this.now = [];
        this.open = 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(a) {
        this.element.setStyle(this.margin, a[0]);
        this.wrapper.setStyle(this.layout, a[1]);
        return this;
    },
    compute: function(c, b, a) {
        return [0, 1].map(function(d) {
            return Fx.compute(c[d], b[d], a);
        });
    },
    start: function(b, e) {
        if (!this.check(b, e)) {
            return this;
        }
        this[e || this.options.mode]();
        var d = this.element.getStyle(this.margin).toInt();
        var c = this.wrapper.getStyle(this.layout).toInt();
        var a = [[d, c], [0, this.offset]];
        var g = [[d, c], [-this.offset, 0]];
        var f;
        switch (b) {
            case "in":
                f = a;
                break;
            case "out":
                f = g;
                break;
            case "toggle":
                f = (c == 0) ? a : g;
        }
        return this.parent(f[0], f[1]);
    },
    slideIn: function(a) {
        return this.start("in", a);
    },
    slideOut: function(a) {
        return this.start("out", a);
    },
    hide: function(a) {
        this[a || this.options.mode]();
        this.open = false;
        return this.set([-this.offset, 0]);
    },
    show: function(a) {
        this[a || this.options.mode]();
        this.open = true;
        return this.set([0, this.offset]);
    },
    toggle: function(a) {
        return this.start("toggle", a);
    }
});
Element.Properties.slide = {
    set: function(b) {
        var a = this.retrieve("slide");
        if (a) {
            a.cancel();
        }
        return this.eliminate("slide").store("slide:options", $extend({
            link: "cancel"
        }, b));
    },
    get: function(a) {
        if (a || !this.retrieve("slide")) {
            if (a || !this.retrieve("slide:options")) {
                this.set("slide", a);
            }
            this.store("slide", new Fx.Slide(this, this.retrieve("slide:options")));
        }
        return this.retrieve("slide");
    }
};
Element.implement({
    slide: function(d, e) {
        d = d || "toggle";
        var b = this.get("slide"), a;
        switch (d) {
            case "hide":
                b.hide(e);
                break;
            case "show":
                b.show(e);
                break;
            case "toggle":
                var c = this.retrieve("slide:flag", b.open);
                b[c ? "slideOut" : "slideIn"](e);
                this.store("slide:flag", !c);
                a = true;
                break;
            default:
                b.start(d, e);
        }
        if (!a) {
            this.eliminate("slide:flag");
        }
        return this;
    }
});
var SmoothScroll = Fx.SmoothScroll = new Class({
    Extends: Fx.Scroll,
    initialize: function(b, c) {
        c = c || document;
        this.doc = c.getDocument();
        var d = c.getWindow();
        this.parent(this.doc, b);
        this.links = this.options.links ? $$(this.options.links) : $$(this.doc.links);
        var a = d.location.href.match(/^[^#]*/)[0] + "#";
        this.links.each(function(f) {
            if (f.href.indexOf(a) != 0) {
                return;
            }
            var e = f.href.substr(a.length);
            if (e) {
                this.useLink(f, e);
            }
        }, this);
        if (!Browser.Engine.webkit419) {
            this.addEvent("complete", function() {
                d.location.hash = this.anchor;
            }, true);
        }
    },
    useLink: function(c, a) {
        var b;
        c.addEvent("click", function(d) {
            if (b !== false && !b) {
                b = document.id(a) || this.doc.getElement("a[name=" + a + "]");
            }
            if (b) {
                d.preventDefault();
                this.anchor = a;
                this.toElement(b);
                c.blur();
            }
        }
.bind(this));
    }
});
Fx.Sort = new Class({
    Extends: Fx.Elements,
    options: {
        mode: "vertical"
    },
    initialize: function(b, a) {
        this.parent(b, a);
        this.elements.each(function(c) {
            if (c.getStyle("position") == "static") {
                c.setStyle("position", "relative");
            }
        });
        this.setDefaultOrder();
    },
    setDefaultOrder: function() {
        this.currentOrder = this.elements.map(function(b, a) {
            return a;
        });
    },
    sort: function(e) {
        if ($type(e) != "array") {
            return false;
        }
        var i = 0;
        var a = 0;
        var h = {};
        var d = this.options.mode == "vertical";
        var f = this.elements.map(function(m, j) {
            var l = m.getComputedSize({
                styles: ["border", "padding", "margin"]
            });
            var n;
            if (d) {
                n = {
                    top: i,
                    margin: l["margin-top"],
                    height: l.totalHeight
                };
                i += n.height - l["margin-top"];
            }
            else {
                n = {
                    left: a,
                    margin: l["margin-left"],
                    width: l.totalWidth
                };
                a += n.width;
            }
            var k = d ? "top" : "left";
            h[j] = {};
            var o = m.getStyle(k).toInt();
            h[j][k] = o || 0;
            return n;
        }, this);
        this.set(h);
        e = e.map(function(j) {
            return j.toInt();
        });
        if (e.length != this.elements.length) {
            this.currentOrder.each(function(j) {
                if (!e.contains(j)) {
                    e.push(j);
                }
            });
            if (e.length > this.elements.length) {
                e.splice(this.elements.length - 1, e.length - this.elements.length);
            }
        }
        i = 0;
        a = 0;
        var b = 0;
        var c = {};
        e.each(function(l, j) {
            var k = {};
            if (d) {
                k.top = i - f[l].top - b;
                i += f[l].height;
            }
            else {
                k.left = a - f[l].left;
                a += f[l].width;
            }
            b = b + f[l].margin;
            c[l] = k;
        }, this);
        var g = {};
        $A(e).sort().each(function(j) {
            g[j] = c[j];
        });
        this.start(g);
        this.currentOrder = e;
        return this;
    },
    rearrangeDOM: function(a) {
        a = a || this.currentOrder;
        var b = this.elements[0].getParent();
        var c = [];
        this.elements.setStyle("opacity", 0);
        a.each(function(d) {
            c.push(this.elements[d].inject(b).setStyles({
                top: 0,
                left: 0
            }));
        }, this);
        this.elements.setStyle("opacity", 1);
        this.elements = $$(c);
        this.setDefaultOrder();
        return this;
    },
    getDefaultOrder: function() {
        return this.elements.map(function(b, a) {
            return a;
        });
    },
    forward: function() {
        return this.sort(this.getDefaultOrder());
    },
    backward: function() {
        return this.sort(this.getDefaultOrder().reverse());
    },
    reverse: function() {
        return this.sort(this.currentOrder.reverse());
    },
    sortByElements: function(a) {
        return this.sort(a.map(function(b) {
            return this.elements.indexOf(b);
        }, this));
    },
    swap: function(c, b) {
        if ($type(c) == "element") {
            c = this.elements.indexOf(c);
        }
        if ($type(b) == "element") {
            b = this.elements.indexOf(b);
        }
        var a = $A(this.currentOrder);
        a[this.currentOrder.indexOf(c)] = b;
        a[this.currentOrder.indexOf(b)] = c;
        this.sort(a);
    }
});
var Drag = new Class({
    Implements: [Events, Options],
    options: {
        snap: 6,
        unit: "px",
        grid: false,
        style: true,
        limit: false,
        handle: false,
        invert: false,
        preventDefault: false,
        modifiers: {
            x: "left",
            y: "top"
        }
    },
    initialize: function() {
        var b = Array.link(arguments, {
            options: Object.type,
            element: $defined
        });
        this.element = document.id(b.element);
        this.document = this.element.getDocument();
        this.setOptions(b.options || {});
        var a = $type(this.options.handle);
        this.handles = ((a == "array" || a == "collection") ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
        this.mouse = {
            now: {},
            pos: {}
        };
        this.value = {
            start: {},
            now: {}
        };
        this.selection = (Browser.Engine.trident) ? "selectstart" : "mousedown";
        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: $lambda(false)
        };
        this.attach();
    },
    attach: function() {
        this.handles.addEvent("mousedown", this.bound.start);
        return this;
    },
    detach: function() {
        this.handles.removeEvent("mousedown", this.bound.start);
        return this;
    },
    start: function(c) {
        if (this.options.preventDefault) {
            c.preventDefault();
        }
        this.mouse.start = c.page;
        this.fireEvent("beforeStart", this.element);
        var a = this.options.limit;
        this.limit = {
            x: [],
            y: []
        };
        for (var d in this.options.modifiers) {
            if (!this.options.modifiers[d]) {
                continue;
            }
            if (this.options.style) {
                this.value.now[d] = this.element.getStyle(this.options.modifiers[d]).toInt();
            }
            else {
                this.value.now[d] = this.element[this.options.modifiers[d]];
            }
            if (this.options.invert) {
                this.value.now[d] *= -1;
            }
            this.mouse.pos[d] = c.page[d] - this.value.now[d];
            if (a && a[d]) {
                for (var b = 2; b--; b) {
                    if ($chk(a[d][b])) {
                        this.limit[d][b] = $lambda(a[d][b])();
                    }
                }
            }
        }
        if ($type(this.options.grid) == "number") {
            this.options.grid = {
                x: this.options.grid,
                y: this.options.grid
            };
        }
        this.document.addEvents({
            mousemove: this.bound.check,
            mouseup: this.bound.cancel
        });
        this.document.addEvent(this.selection, this.bound.eventStop);
    },
    check: function(a) {
        if (this.options.preventDefault) {
            a.preventDefault();
        }
        var b = Math.round(Math.sqrt(Math.pow(a.page.x - this.mouse.start.x, 2) + Math.pow(a.page.y - this.mouse.start.y, 2)));
        if (b > this.options.snap) {
            this.cancel();
            this.document.addEvents({
                mousemove: this.bound.drag,
                mouseup: this.bound.stop
            });
            this.fireEvent("start", [this.element, a]).fireEvent("snap", this.element);
        }
    },
    drag: function(a) {
        if (this.options.preventDefault) {
            a.preventDefault();
        }
        this.mouse.now = a.page;
        for (var b in this.options.modifiers) {
            if (!this.options.modifiers[b]) {
                continue;
            }
            this.value.now[b] = this.mouse.now[b] - this.mouse.pos[b];
            if (this.options.invert) {
                this.value.now[b] *= -1;
            }
            if (this.options.limit && this.limit[b]) {
                if ($chk(this.limit[b][1]) && (this.value.now[b] > this.limit[b][1])) {
                    this.value.now[b] = this.limit[b][1];
                }
                else {
                    if ($chk(this.limit[b][0]) && (this.value.now[b] < this.limit[b][0])) {
                        this.value.now[b] = this.limit[b][0];
                    }
                }
            }
            if (this.options.grid[b]) {
                this.value.now[b] -= ((this.value.now[b] - (this.limit[b][0] || 0)) % this.options.grid[b]);
            }
            if (this.options.style) {
                this.element.setStyle(this.options.modifiers[b], this.value.now[b] + this.options.unit);
            }
            else {
                this.element[this.options.modifiers[b]] = this.value.now[b];
            }
        }
        this.fireEvent("drag", [this.element, a]);
    },
    cancel: function(a) {
        this.document.removeEvent("mousemove", this.bound.check);
        this.document.removeEvent("mouseup", this.bound.cancel);
        if (a) {
            this.document.removeEvent(this.selection, this.bound.eventStop);
            this.fireEvent("cancel", this.element);
        }
    },
    stop: function(a) {
        this.document.removeEvent(this.selection, this.bound.eventStop);
        this.document.removeEvent("mousemove", this.bound.drag);
        this.document.removeEvent("mouseup", this.bound.stop);
        if (a) {
            this.fireEvent("complete", [this.element, a]);
        }
    }
});
Element.implement({
    makeResizable: function(a) {
        var b = new Drag(this, $merge({
            modifiers: {
                x: "width",
                y: "height"
            }
        }, a));
        this.store("resizer", b);
        return b.addEvent("drag", function() {
            this.fireEvent("resize", b);
        }
.bind(this));
    }
});
var Slider = new Class({
    Implements: [Events, Options],
    Binds: ["clickedElement", "draggedKnob", "scrolledElement"],
    options: {
        onTick: function(a) {
            if (this.options.snap) {
                a = this.toPosition(this.step);
            }
            this.knob.setStyle(this.property, a);
        },
        snap: false,
        offset: 0,
        range: false,
        wheel: false,
        steps: 100,
        mode: "horizontal"
    },
    initialize: function(f, a, e) {
        this.setOptions(e);
        this.element = document.id(f);
        this.knob = document.id(a);
        this.previousChange = this.previousEnd = this.step = -1;
        var g, b = {}, d = {
            x: false,
            y: false
        };
        switch (this.options.mode) {
            case "vertical":
                this.axis = "y";
                this.property = "top";
                g = "offsetHeight";
                break;
            case "horizontal":
                this.axis = "x";
                this.property = "left";
                g = "offsetWidth";
        }
        this.half = this.knob[g] / 2;
        this.full = this.element[g] - this.knob[g] + (this.options.offset * 2);
        this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
        this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps;
        this.range = this.max - this.min;
        this.steps = this.options.steps || this.full;
        this.stepSize = Math.abs(this.range) / this.steps;
        this.stepWidth = this.stepSize * this.full / Math.abs(this.range);
        this.knob.setStyle("position", "relative").setStyle(this.property, -this.options.offset);
        d[this.axis] = this.property;
        b[this.axis] = [-this.options.offset, this.full - this.options.offset];
        this.bound = {
            clickedElement: this.clickedElement.bind(this),
            scrolledElement: this.scrolledElement.bindWithEvent(this),
            draggedKnob: this.draggedKnob.bind(this)
        };
        var c = {
            snap: 0,
            limit: b,
            modifiers: d,
            onDrag: this.bound.draggedKnob,
            onStart: this.bound.draggedKnob,
            onBeforeStart: (function() {
                this.isDragging = true;
            }).bind(this),
            onComplete: function() {
                this.isDragging = false;
                this.draggedKnob();
                this.end();
            }
.bind(this)
        };
        if (this.options.snap) {
            c.grid = Math.ceil(this.stepWidth);
            c.limit[this.axis][1] = this.full;
        }
        this.drag = new Drag(this.knob, c);
        this.attach();
    },
    attach: function() {
        this.element.addEvent("mousedown", this.bound.clickedElement);
        if (this.options.wheel) {
            this.element.addEvent("mousewheel", this.bound.scrolledElement);
        }
        this.drag.attach();
        return this;
    },
    detach: function() {
        this.element.removeEvent("mousedown", this.bound.clickedElement);
        this.element.removeEvent("mousewheel", this.bound.scrolledElement);
        this.drag.detach();
        return this;
    },
    set: function(a) {
        if (!((this.range > 0) ^ (a < this.min))) {
            a = this.min;
        }
        if (!((this.range > 0) ^ (a > this.max))) {
            a = this.max;
        }
        this.step = Math.round(a);
        this.checkStep();
        this.fireEvent("tick", this.toPosition(this.step));
        this.end();
        return this;
    },
    clickedElement: function(c) {
        if (this.isDragging || c.target == this.knob) {
            return;
        }
        var b = this.range < 0 ? -1 : 1;
        var a = c.page[this.axis] - this.element.getPosition()[this.axis] - this.half;
        a = a.limit(-this.options.offset, this.full - this.options.offset);
        this.step = Math.round(this.min + b * this.toStep(a));
        this.checkStep();
        this.fireEvent("tick", a);
        this.end();
    },
    scrolledElement: function(a) {
        var b = (this.options.mode == "horizontal") ? (a.wheel < 0) : (a.wheel > 0);
        this.set(b ? this.step - this.stepSize : this.step + this.stepSize);
        a.stop();
    },
    draggedKnob: function() {
        var b = this.range < 0 ? -1 : 1;
        var a = this.drag.value.now[this.axis];
        a = a.limit(-this.options.offset, this.full - this.options.offset);
        this.step = Math.round(this.min + b * this.toStep(a));
        this.checkStep();
    },
    checkStep: function() {
        if (this.previousChange != this.step) {
            this.previousChange = this.step;
            this.fireEvent("change", this.step);
        }
    },
    end: function() {
        if (this.previousEnd !== this.step) {
            this.previousEnd = this.step;
            this.fireEvent("complete", this.step + "");
        }
    },
    toStep: function(a) {
        var b = (a + this.options.offset) * this.stepSize / this.full * this.steps;
        return this.options.steps ? Math.round(b -= b % this.stepSize) : b;
    },
    toPosition: function(a) {
        return (this.full * Math.abs(this.min - a)) / (this.steps * this.stepSize) - this.options.offset;
    }
});
var Asset = {
    javascript: function(f, d) {
        d = $extend({
            onload: $empty,
            document: document,
            check: $lambda(true)
        }, d);
        var b = new Element("script", {
            src: f,
            type: "text/javascript"
        });
        var e = d.onload.bind(b), a = d.check, g = d.document;
        delete d.onload;
        delete d.check;
        delete d.document;
        b.addEvents({
            load: e,
            readystatechange: function() {
                if (["loaded", "complete"].contains(this.readyState)) {
                    e();
                }
            }
        }).set(d);
        if (Browser.Engine.webkit419) {
            var c = (function() {
                if (!$try(a)) {
                    return;
                }
                $clear(c);
                e();
            }).periodical(50);
        }
        return b.inject(g.head);
    },
    css: function(b, a) {
        return new Element("link", $merge({
            rel: "stylesheet",
            media: "screen",
            type: "text/css",
            href: b
        }, a)).inject(document.head);
    },
    image: function(c, b) {
        b = $merge({
            onload: $empty,
            onabort: $empty,
            onerror: $empty
        }, b);
        var d = new Image();
        var a = document.id(d) || new Element("img");
        ["load", "abort", "error"].each(function(e) {
            var f = "on" + e;
            var g = b[f];
            delete b[f];
            d[f] = function() {
                if (!d) {
                    return;
                }
                if (!a.parentNode) {
                    a.width = d.width;
                    a.height = d.height;
                }
                d = d.onload = d.onabort = d.onerror = null;
                g.delay(1, a, a);
                a.fireEvent(e, a, 1);
            };
        });
        d.src = a.src = c;
        if (d && d.complete) {
            d.onload.delay(1);
        }
        return a.set(b);
    },
    images: function(d, c) {
        c = $merge({
            onComplete: $empty,
            onProgress: $empty,
            onError: $empty,
            properties: {}
        }, c);
        d = $splat(d);
        var a = [];
        var b = 0;
        return new Elements(d.map(function(e) {
            return Asset.image(e, $extend(c.properties, {
                onload: function() {
                    c.onProgress.call(this, b, d.indexOf(e));
                    b++;
                    if (b == d.length) {
                        c.onComplete();
                    }
                },
                onerror: function() {
                    c.onError.call(this, b, d.indexOf(e));
                    b++;
                    if (b == d.length) {
                        c.onComplete();
                    }
                }
            }));
        }));
    }
};
var Color = new Native({
    initialize: function(b, c) {
        if (arguments.length >= 3) {
            c = "rgb";
            b = Array.slice(arguments, 0, 3);
        }
        else {
            if (typeof b == "string") {
                if (b.match(/rgb/)) {
                    b = b.rgbToHex().hexToRgb(true);
                }
                else {
                    if (b.match(/hsb/)) {
                        b = b.hsbToRgb();
                    }
                    else {
                        b = b.hexToRgb(true);
                    }
                }
            }
        }
        c = c || "rgb";
        switch (c) {
            case "hsb":
                var a = b;
                b = b.hsbToRgb();
                b.hsb = a;
                break;
            case "hex":
                b = b.hexToRgb(true);
                break;
        }
        b.rgb = b.slice(0, 3);
        b.hsb = b.hsb || b.rgbToHsb();
        b.hex = b.rgbToHex();
        return $extend(b, this);
    }
});
Color.implement({
    mix: function() {
        var a = Array.slice(arguments);
        var c = ($type(a.getLast()) == "number") ? a.pop() : 50;
        var b = this.slice();
        a.each(function(d) {
            d = new Color(d);
            for (var e = 0; e < 3; e++) {
                b[e] = Math.round((b[e] / 100 * (100 - c)) + (d[e] / 100 * c));
            }
        });
        return new Color(b, "rgb");
    },
    invert: function() {
        return new Color(this.map(function(a) {
            return 255 - a;
        }));
    },
    setHue: function(a) {
        return new Color([a, this.hsb[1], this.hsb[2]], "hsb");
    },
    setSaturation: function(a) {
        return new Color([this.hsb[0], a, this.hsb[2]], "hsb");
    },
    setBrightness: function(a) {
        return new Color([this.hsb[0], this.hsb[1], a], "hsb");
    }
});
var $RGB = function(d, c, a) {
    return new Color([d, c, a], "rgb");
};
var $HSB = function(d, c, a) {
    return new Color([d, c, a], "hsb");
};
var $HEX = function(a) {
    return new Color(a, "hex");
};
Array.implement({
    rgbToHsb: function() {
        var b = this[0], c = this[1], j = this[2];
        var g, f, h;
        var i = Math.max(b, c, j), e = Math.min(b, c, j);
        var k = i - e;
        h = i / 255;
        f = (i != 0) ? k / i : 0;
        if (f == 0) {
            g = 0;
        }
        else {
            var d = (i - b) / k;
            var a = (i - c) / k;
            var l = (i - j) / k;
            if (b == i) {
                g = l - a;
            }
            else {
                if (c == i) {
                    g = 2 + d - l;
                }
                else {
                    g = 4 + a - d;
                }
            }
            g /= 6;
            if (g < 0) {
                g++;
            }
        }
        return [Math.round(g * 360), Math.round(f * 100), Math.round(h * 100)];
    },
    hsbToRgb: function() {
        var c = Math.round(this[2] / 100 * 255);
        if (this[1] == 0) {
            return [c, c, c];
        }
        else {
            var a = this[0] % 360;
            var e = a % 60;
            var g = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
            var d = Math.round((this[2] * (6000 - this[1] * e)) / 600000 * 255);
            var b = Math.round((this[2] * (6000 - this[1] * (60 - e))) / 600000 * 255);
            switch (Math.floor(a / 60)) {
                case 0:
                    return [c, b, g];
                case 1:
                    return [d, c, g];
                case 2:
                    return [g, c, b];
                case 3:
                    return [g, d, c];
                case 4:
                    return [b, g, c];
                case 5:
                    return [c, g, d];
            }
        }
        return false;
    }
});
String.implement({
    rgbToHsb: function() {
        var a = this.match(/\d{1,3}/g);
        return (a) ? a.rgbToHsb() : null;
    },
    hsbToRgb: function() {
        var a = this.match(/\d{1,3}/g);
        return (a) ? a.hsbToRgb() : null;
    }
});
var Scroller = new Class({
    Implements: [Events, Options],
    options: {
        area: 20,
        velocity: 1,
        onChange: function(a, b) {
            this.element.scrollTo(a, b);
        },
        fps: 50
    },
    initialize: function(b, a) {
        this.setOptions(a);
        this.element = document.id(b);
        this.listener = ($type(this.element) != "element") ? document.id(this.element.getDocument().body) : this.element;
        this.timer = null;
        this.bound = {
            attach: this.attach.bind(this),
            detach: this.detach.bind(this),
            getCoords: this.getCoords.bind(this)
        };
    },
    start: function() {
        this.listener.addEvents({
            mouseenter: this.bound.attach,
            mouseleave: this.bound.detach
        });
    },
    stop: function() {
        this.listener.removeEvents({
            mouseenter: this.bound.attach,
            mouseleave: this.bound.detach
        });
        this.timer = $clear(this.timer);
    },
    attach: function() {
        this.listener.addEvent("mousemove", this.bound.getCoords);
    },
    detach: function() {
        this.listener.removeEvent("mousemove", this.bound.getCoords);
        this.timer = $clear(this.timer);
    },
    getCoords: function(a) {
        this.page = (this.listener.get("tag") == "body") ? a.client : a.page;
        if (!this.timer) {
            this.timer = this.scroll.periodical(Math.round(1000 / this.options.fps), this);
        }
    },
    scroll: function() {
        var b = this.element.getSize(), a = this.element.getScroll(), f = this.element.getOffsets(), c = this.element.getScrollSize(), e = {
            x: 0,
            y: 0
        };
        for (var d in this.page) {
            if (this.page[d] < (this.options.area + f[d]) && a[d] != 0) {
                e[d] = (this.page[d] - this.options.area - f[d]) * this.options.velocity;
            }
            else {
                if (this.page[d] + this.options.area > (b[d] + f[d]) && a[d] + b[d] != c[d]) {
                    e[d] = (this.page[d] - b[d] + this.options.area - f[d]) * this.options.velocity;
                }
            }
        }
        if (e.y || e.x) {
            this.fireEvent("change", [a.x + e.x, a.y + e.y]);
        }
    }
});
var Tips = new Class({
    Implements: [Events, Options],
    options: {
        onShow: function(a) {
            a.setStyle("visibility", "visible");
        },
        onHide: function(a) {
            a.setStyle("visibility", "hidden");
        },
        title: "title",
        text: function(a) {
            return a.get("rel") || a.get("href");
        },
        showDelay: 100,
        hideDelay: 100,
        className: null,
        offset: {
            x: 16,
            y: 16
        },
        fixed: false
    },
    initialize: function() {
        var a = Array.link(arguments, {
            options: Object.type,
            elements: $defined
        });
        if (a.options && a.options.offsets) {
            a.options.offset = a.options.offsets;
        }
        this.setOptions(a.options);
        this.container = new Element("div", {
            "class": "tip"
        });
        this.tip = this.getTip();
        if (a.elements) {
            this.attach(a.elements);
        }
    },
    getTip: function() {
        return new Element("div", {
            "class": this.options.className,
            styles: {
                visibility: "hidden",
                display: "none",
                position: "absolute",
                top: 0,
                left: 0
            }
        }).adopt(new Element("div", {
            "class": "tip-top"
        }), this.container, new Element("div", {
            "class": "tip-bottom"
        })).inject(document.body);
    },
    attach: function(b) {
        var a = function(d, c) {
            if (d == null) {
                return "";
            }
            return $type(d) == "function" ? d(c) : c.get(d);
        };
        $$(b).each(function(d) {
            var e = a(this.options.title, d);
            d.erase("title").store("tip:native", e).retrieve("tip:title", e);
            d.retrieve("tip:text", a(this.options.text, d));
            var c = ["enter", "leave"];
            if (!this.options.fixed) {
                c.push("move");
            }
            c.each(function(f) {
                d.addEvent("mouse" + f, d.retrieve("tip:" + f, this["element" + f.capitalize()].bindWithEvent(this, d)));
            }, this);
        }, this);
        return this;
    },
    detach: function(a) {
        $$(a).each(function(c) {
            ["enter", "leave", "move"].each(function(d) {
                c.removeEvent("mouse" + d, c.retrieve("tip:" + d) || $empty);
            });
            c.eliminate("tip:enter").eliminate("tip:leave").eliminate("tip:move");
            if ($type(this.options.title) == "string" && this.options.title == "title") {
                var b = c.retrieve("tip:native");
                if (b) {
                    c.set("title", b);
                }
            }
        }, this);
        return this;
    },
    elementEnter: function(b, a) {
        $A(this.container.childNodes).each(Element.dispose);
        ["title", "text"].each(function(d) {
            var c = a.retrieve("tip:" + d);
            if (!c) {
                return;
            }
            this[d + "Element"] = new Element("div", {
                "class": "tip-" + d
            }).inject(this.container);
            this.fill(this[d + "Element"], c);
        }, this);
        this.timer = $clear(this.timer);
        this.timer = this.show.delay(this.options.showDelay, this, a);
        this.tip.setStyle("display", "block");
        this.position((!this.options.fixed) ? b : {
            page: a.getPosition()
        });
    },
    elementLeave: function(b, a) {
        $clear(this.timer);
        this.tip.setStyle("display", "none");
        this.timer = this.hide.delay(this.options.hideDelay, this, a);
    },
    elementMove: function(a) {
        this.position(a);
    },
    position: function(d) {
        var b = window.getSize(), a = window.getScroll(), e = {
            x: this.tip.offsetWidth,
            y: this.tip.offsetHeight
        }, c = {
            x: "left",
            y: "top"
        }, f = {};
        for (var g in c) {
            f[c[g]] = d.page[g] + this.options.offset[g];
            if ((f[c[g]] + e[g] - a[g]) > b[g]) {
                f[c[g]] = d.page[g] - this.options.offset[g] - e[g];
            }
        }
        this.tip.setStyles(f);
    },
    fill: function(a, b) {
        if (typeof b == "string") {
            a.set("html", b);
        }
        else {
            a.adopt(b);
        }
    },
    show: function(a) {
        this.fireEvent("show", [this.tip, a]);
    },
    hide: function(a) {
        this.fireEvent("hide", [this.tip, a]);
    }
});
MooTools.lang.set("en-US", "Date", {
    months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
    days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
    dateOrder: ["month", "date", "year"],
    shortDate: "%m/%d/%Y",
    shortTime: "%I:%M%p",
    AM: "AM",
    PM: "PM",
    ordinal: function(a) {
        return (a > 3 && a < 21) ? "th" : ["th", "st", "nd", "rd", "th"][Math.min(a % 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",
    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"
});

