Anonymous avatar Anonymous committed 4c80c58

initial commit svn r1519

Comments (0)

Files changed (191)

+syntax: glob
+.svn
+*~
+
+MochiKit is dual-licensed software.  It is available under the terms of the
+MIT License, or the Academic Free License version 2.1.  The full text of
+each license is included below.
+
+MIT License
+===========
+
+Copyright (c) 2005 Bob Ippolito.  All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Academic Free License v. 2.1
+============================
+
+Copyright (c) 2005 Bob Ippolito.  All rights reserved.
+
+This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner.
+
+ 
+

MochiKit/Async.js

+/***
+
+MochiKit.Async 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito.  All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Async', '1.5', ['Base']);
+
+/** @id MochiKit.Async.Deferred */
+MochiKit.Async.Deferred = function (/* optional */ canceller) {
+    this.chain = [];
+    this.id = this._nextId();
+    this.fired = -1;
+    this.paused = 0;
+    this.results = [null, null];
+    this.canceller = canceller;
+    this.silentlyCancelled = false;
+    this.chained = false;
+};
+
+MochiKit.Async.Deferred.prototype = {
+    /** @id MochiKit.Async.Deferred.prototype.repr */
+    repr: function () {
+        var state;
+        if (this.fired == -1) {
+            state = 'unfired';
+        } else if (this.fired === 0) {
+            state = 'success';
+        } else {
+            state = 'error';
+        }
+        return 'Deferred(' + this.id + ', ' + state + ')';
+    },
+
+    toString: MochiKit.Base.forwardCall("repr"),
+
+    _nextId: MochiKit.Base.counter(),
+
+    /** @id MochiKit.Async.Deferred.prototype.cancel */
+    cancel: function () {
+        var self = MochiKit.Async;
+        if (this.fired == -1) {
+            if (this.canceller) {
+                this.canceller(this);
+            } else {
+                this.silentlyCancelled = true;
+            }
+            if (this.fired == -1) {
+                this.errback(new self.CancelledError(this));
+            }
+        } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
+            this.results[0].cancel();
+        }
+    },
+
+    _resback: function (res) {
+        /***
+
+        The primitive that means either callback or errback
+
+        ***/
+        this.fired = ((res instanceof Error) ? 1 : 0);
+        this.results[this.fired] = res;
+        this._fire();
+    },
+
+    _check: function () {
+        if (this.fired != -1) {
+            if (!this.silentlyCancelled) {
+                throw new MochiKit.Async.AlreadyCalledError(this);
+            }
+            this.silentlyCancelled = false;
+            return;
+        }
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.callback */
+    callback: function (res) {
+        this._check();
+        if (res instanceof MochiKit.Async.Deferred) {
+            throw new Error("Deferred instances can only be chained if they are the result of a callback");
+        }
+        this._resback(res);
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.errback */
+    errback: function (res) {
+        this._check();
+        var self = MochiKit.Async;
+        if (res instanceof self.Deferred) {
+            throw new Error("Deferred instances can only be chained if they are the result of a callback");
+        }
+        if (!(res instanceof Error)) {
+            res = new self.GenericError(res);
+        }
+        this._resback(res);
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.addBoth */
+    addBoth: function (fn) {
+        if (arguments.length > 1) {
+            fn = MochiKit.Base.partial.apply(null, arguments);
+        }
+        return this.addCallbacks(fn, fn);
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.addCallback */
+    addCallback: function (fn) {
+        if (arguments.length > 1) {
+            fn = MochiKit.Base.partial.apply(null, arguments);
+        }
+        return this.addCallbacks(fn, null);
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.addErrback */
+    addErrback: function (fn) {
+        if (arguments.length > 1) {
+            fn = MochiKit.Base.partial.apply(null, arguments);
+        }
+        return this.addCallbacks(null, fn);
+    },
+
+    /** @id MochiKit.Async.Deferred.prototype.addCallbacks */
+    addCallbacks: function (cb, eb) {
+        if (this.chained) {
+            throw new Error("Chained Deferreds can not be re-used");
+        }
+        this.chain.push([cb, eb]);
+        if (this.fired >= 0) {
+            this._fire();
+        }
+        return this;
+    },
+
+    _fire: function () {
+        /***
+
+        Used internally to exhaust the callback sequence when a result
+        is available.
+
+        ***/
+        var chain = this.chain;
+        var fired = this.fired;
+        var res = this.results[fired];
+        var self = this;
+        var cb = null;
+        while (chain.length > 0 && this.paused === 0) {
+            // Array
+            var pair = chain.shift();
+            var f = pair[fired];
+            if (f === null) {
+                continue;
+            }
+            try {
+                res = f(res);
+                fired = ((res instanceof Error) ? 1 : 0);
+                if (res instanceof MochiKit.Async.Deferred) {
+                    cb = function (res) {
+                        self._resback(res);
+                        self.paused--;
+                        if ((self.paused === 0) && (self.fired >= 0)) {
+                            self._fire();
+                        }
+                    };
+                    this.paused++;
+                }
+            } catch (err) {
+                fired = 1;
+                if (!(err instanceof Error)) {
+                    err = new MochiKit.Async.GenericError(err);
+                }
+                res = err;
+            }
+        }
+        this.fired = fired;
+        this.results[fired] = res;
+        if (cb && this.paused) {
+            // this is for "tail recursion" in case the dependent deferred
+            // is already fired
+            res.addBoth(cb);
+            res.chained = true;
+        }
+    }
+};
+
+MochiKit.Base.update(MochiKit.Async, {
+    /** @id MochiKit.Async.evalJSONRequest */
+    evalJSONRequest: function (req) {
+        return MochiKit.Base.evalJSON(req.responseText);
+    },
+
+    /** @id MochiKit.Async.succeed */
+    succeed: function (/* optional */result) {
+        var d = new MochiKit.Async.Deferred();
+        d.callback.apply(d, arguments);
+        return d;
+    },
+
+    /** @id MochiKit.Async.fail */
+    fail: function (/* optional */result) {
+        var d = new MochiKit.Async.Deferred();
+        d.errback.apply(d, arguments);
+        return d;
+    },
+
+    /** @id MochiKit.Async.getXMLHttpRequest */
+    getXMLHttpRequest: function () {
+        var self = arguments.callee;
+        if (!self.XMLHttpRequest) {
+            var tryThese = [
+                function () { return new XMLHttpRequest(); },
+                function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
+                function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
+                function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
+                function () {
+                    throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
+                }
+            ];
+            for (var i = 0; i < tryThese.length; i++) {
+                var func = tryThese[i];
+                try {
+                    self.XMLHttpRequest = func;
+                    return func();
+                } catch (e) {
+                    // pass
+                }
+            }
+        }
+        return self.XMLHttpRequest();
+    },
+
+    _xhr_onreadystatechange: function (d) {
+        // MochiKit.Logging.logDebug('this.readyState', this.readyState);
+        var m = MochiKit.Base;
+        if (this.readyState == 4) {
+            // IE SUCKS
+            try {
+                this.onreadystatechange = null;
+            } catch (e) {
+                try {
+                    this.onreadystatechange = m.noop;
+                } catch (e) {
+                }
+            }
+            var status = null;
+            try {
+                status = this.status;
+                if (!status && m.isNotEmpty(this.responseText)) {
+                    // 0 or undefined seems to mean cached or local
+                    status = 304;
+                }
+            } catch (e) {
+                // pass
+                // MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
+            }
+            // 200 is OK, 201 is CREATED, 204 is NO CONTENT
+            // 304 is NOT MODIFIED, 1223 is apparently a bug in IE
+            if (status == 200 || status == 201 || status == 204 ||
+                    status == 304 || status == 1223) {
+                d.callback(this);
+            } else {
+                var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
+                if (err.number) {
+                    // XXX: This seems to happen on page change
+                    d.errback(err);
+                } else {
+                    // XXX: this seems to happen when the server is unreachable
+                    d.errback(err);
+                }
+            }
+        }
+    },
+
+    _xhr_canceller: function (req) {
+        // IE SUCKS
+        try {
+            req.onreadystatechange = null;
+        } catch (e) {
+            try {
+                req.onreadystatechange = MochiKit.Base.noop;
+            } catch (e) {
+            }
+        }
+        req.abort();
+    },
+
+
+    /** @id MochiKit.Async.sendXMLHttpRequest */
+    sendXMLHttpRequest: function (req, /* optional */ sendContent) {
+        if (typeof(sendContent) == "undefined" || sendContent === null) {
+            sendContent = "";
+        }
+
+        var m = MochiKit.Base;
+        var self = MochiKit.Async;
+        var d = new self.Deferred(m.partial(self._xhr_canceller, req));
+
+        try {
+            req.onreadystatechange = m.bind(self._xhr_onreadystatechange,
+                req, d);
+            req.send(sendContent);
+        } catch (e) {
+            try {
+                req.onreadystatechange = null;
+            } catch (ignore) {
+                // pass
+            }
+            d.errback(e);
+        }
+
+        return d;
+
+    },
+
+    /** @id MochiKit.Async.doXHR */
+    doXHR: function (url, opts) {
+        /*
+            Work around a Firefox bug by dealing with XHR during
+            the next event loop iteration. Maybe it's this one:
+            https://bugzilla.mozilla.org/show_bug.cgi?id=249843
+        */
+        var self = MochiKit.Async;
+        return self.callLater(0, self._doXHR, url, opts);
+    },
+
+    _doXHR: function (url, opts) {
+        var m = MochiKit.Base;
+        opts = m.update({
+            method: 'GET',
+            sendContent: ''
+            /*
+            queryString: undefined,
+            username: undefined,
+            password: undefined,
+            headers: undefined,
+            mimeType: undefined
+            */
+        }, opts);
+        var self = MochiKit.Async;
+        var req = self.getXMLHttpRequest();
+        if (opts.queryString) {
+            var qs = m.queryString(opts.queryString);
+            if (qs) {
+                url += "?" + qs;
+            }
+        }
+        // Safari will send undefined:undefined, so we have to check.
+        // We can't use apply, since the function is native.
+        if ('username' in opts) {
+            req.open(opts.method, url, true, opts.username, opts.password);
+        } else {
+            req.open(opts.method, url, true);
+        }
+        if (req.overrideMimeType && opts.mimeType) {
+            req.overrideMimeType(opts.mimeType);
+        }
+        req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+        if (opts.headers) {
+            var headers = opts.headers;
+            if (!m.isArrayLike(headers)) {
+                headers = m.items(headers);
+            }
+            for (var i = 0; i < headers.length; i++) {
+                var header = headers[i];
+                var name = header[0];
+                var value = header[1];
+                req.setRequestHeader(name, value);
+            }
+        }
+        return self.sendXMLHttpRequest(req, opts.sendContent);
+    },
+
+    _buildURL: function (url/*, ...*/) {
+        if (arguments.length > 1) {
+            var m = MochiKit.Base;
+            var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
+            if (qs) {
+                return url + "?" + qs;
+            }
+        }
+        return url;
+    },
+
+    /** @id MochiKit.Async.doSimpleXMLHttpRequest */
+    doSimpleXMLHttpRequest: function (url/*, ...*/) {
+        var self = MochiKit.Async;
+        url = self._buildURL.apply(self, arguments);
+        return self.doXHR(url);
+    },
+
+    /** @id MochiKit.Async.loadJSONDoc */
+    loadJSONDoc: function (url/*, ...*/) {
+        var self = MochiKit.Async;
+        url = self._buildURL.apply(self, arguments);
+        var d = self.doXHR(url, {
+            'mimeType': 'text/plain',
+            'headers': [['Accept', 'application/json']]
+        });
+        d = d.addCallback(self.evalJSONRequest);
+        return d;
+    },
+
+    /** @id MochiKit.Async.wait */
+    wait: function (seconds, /* optional */value) {
+        var d = new MochiKit.Async.Deferred();
+        var m = MochiKit.Base;
+        if (typeof(value) != 'undefined') {
+            d.addCallback(function () { return value; });
+        }
+        var timeout = setTimeout(
+            m.bind("callback", d),
+            Math.floor(seconds * 1000));
+        d.canceller = function () {
+            try {
+                clearTimeout(timeout);
+            } catch (e) {
+                // pass
+            }
+        };
+        return d;
+    },
+
+    /** @id MochiKit.Async.callLater */
+    callLater: function (seconds, func) {
+        var m = MochiKit.Base;
+        var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
+        return MochiKit.Async.wait(seconds).addCallback(
+            function (res) { return pfunc(); }
+        );
+    }
+});
+
+
+/** @id MochiKit.Async.DeferredLock */
+MochiKit.Async.DeferredLock = function () {
+    this.waiting = [];
+    this.locked = false;
+    this.id = this._nextId();
+};
+
+MochiKit.Async.DeferredLock.prototype = {
+    __class__: MochiKit.Async.DeferredLock,
+    /** @id MochiKit.Async.DeferredLock.prototype.acquire */
+    acquire: function () {
+        var d = new MochiKit.Async.Deferred();
+        if (this.locked) {
+            this.waiting.push(d);
+        } else {
+            this.locked = true;
+            d.callback(this);
+        }
+        return d;
+    },
+    /** @id MochiKit.Async.DeferredLock.prototype.release */
+    release: function () {
+        if (!this.locked) {
+            throw TypeError("Tried to release an unlocked DeferredLock");
+        }
+        this.locked = false;
+        if (this.waiting.length > 0) {
+            this.locked = true;
+            this.waiting.shift().callback(this);
+        }
+    },
+    _nextId: MochiKit.Base.counter(),
+    repr: function () {
+        var state;
+        if (this.locked) {
+            state = 'locked, ' + this.waiting.length + ' waiting';
+        } else {
+            state = 'unlocked';
+        }
+        return 'DeferredLock(' + this.id + ', ' + state + ')';
+    },
+    toString: MochiKit.Base.forwardCall("repr")
+
+};
+
+/** @id MochiKit.Async.DeferredList */
+MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) {
+
+    // call parent constructor
+    MochiKit.Async.Deferred.apply(this, [canceller]);
+
+    this.list = list;
+    var resultList = [];
+    this.resultList = resultList;
+
+    this.finishedCount = 0;
+    this.fireOnOneCallback = fireOnOneCallback;
+    this.fireOnOneErrback = fireOnOneErrback;
+    this.consumeErrors = consumeErrors;
+
+    var cb = MochiKit.Base.bind(this._cbDeferred, this);
+    for (var i = 0; i < list.length; i++) {
+        var d = list[i];
+        resultList.push(undefined);
+        d.addCallback(cb, i, true);
+        d.addErrback(cb, i, false);
+    }
+
+    if (list.length === 0 && !fireOnOneCallback) {
+        this.callback(this.resultList);
+    }
+
+};
+
+MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
+
+MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
+    this.resultList[index] = [succeeded, result];
+    this.finishedCount += 1;
+    if (this.fired == -1) {
+        if (succeeded && this.fireOnOneCallback) {
+            this.callback([index, result]);
+        } else if (!succeeded && this.fireOnOneErrback) {
+            this.errback(result);
+        } else if (this.finishedCount == this.list.length) {
+            this.callback(this.resultList);
+        }
+    }
+    if (!succeeded && this.consumeErrors) {
+        result = null;
+    }
+    return result;
+};
+
+/** @id MochiKit.Async.gatherResults */
+MochiKit.Async.gatherResults = function (deferredList) {
+    var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
+    d.addCallback(function (results) {
+        var ret = [];
+        for (var i = 0; i < results.length; i++) {
+            ret.push(results[i][1]);
+        }
+        return ret;
+    });
+    return d;
+};
+
+/** @id MochiKit.Async.maybeDeferred */
+MochiKit.Async.maybeDeferred = function (func) {
+    var self = MochiKit.Async;
+    var result;
+    try {
+        var r = func.apply(null, MochiKit.Base.extend([], arguments, 1));
+        if (r instanceof self.Deferred) {
+            result = r;
+        } else if (r instanceof Error) {
+            result = self.fail(r);
+        } else {
+            result = self.succeed(r);
+        }
+    } catch (e) {
+        result = self.fail(e);
+    }
+    return result;
+};
+
+
+MochiKit.Async.__new__ = function () {
+    var m = MochiKit.Base;
+    var ne = m.partial(m._newNamedError, this);
+
+    ne("AlreadyCalledError",
+        /** @id MochiKit.Async.AlreadyCalledError */
+        function (deferred) {
+            /***
+
+            Raised by the Deferred if callback or errback happens
+            after it was already fired.
+
+            ***/
+            this.deferred = deferred;
+        }
+    );
+
+    ne("CancelledError",
+        /** @id MochiKit.Async.CancelledError */
+        function (deferred) {
+            /***
+
+            Raised by the Deferred cancellation mechanism.
+
+            ***/
+            this.deferred = deferred;
+        }
+    );
+
+    ne("BrowserComplianceError",
+        /** @id MochiKit.Async.BrowserComplianceError */
+        function (msg) {
+            /***
+
+            Raised when the JavaScript runtime is not capable of performing
+            the given function.  Technically, this should really never be
+            raised because a non-conforming JavaScript runtime probably
+            isn't going to support exceptions in the first place.
+
+            ***/
+            this.message = msg;
+        }
+    );
+
+    ne("GenericError",
+        /** @id MochiKit.Async.GenericError */
+        function (msg) {
+            this.message = msg;
+        }
+    );
+
+    ne("XMLHttpRequestError",
+        /** @id MochiKit.Async.XMLHttpRequestError */
+        function (req, msg) {
+            /***
+
+            Raised when an XMLHttpRequest does not complete for any reason.
+
+            ***/
+            this.req = req;
+            this.message = msg;
+            try {
+                // Strange but true that this can raise in some cases.
+                this.number = req.status;
+            } catch (e) {
+                // pass
+            }
+        }
+    );
+
+    m.nameFunctions(this);
+};
+
+MochiKit.Async.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Async);
+/***
+
+MochiKit.Base 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito.  All rights Reserved.
+
+***/
+
+if (typeof(MochiKit) == 'undefined') {
+    MochiKit = {};
+}
+if (typeof(MochiKit.__export__) == "undefined") {
+    MochiKit.__export__ = true;
+}
+if (typeof(MochiKit.Base) == 'undefined') {
+    MochiKit.Base = {};
+}
+
+/**
+ * Registers a new MochiKit module. This function will insert a new
+ * property into the "MochiKit" object, making sure that all
+ * dependency modules have already been inserted. It will also make
+ * sure that the appropriate properties and default module functions
+ * are defined.
+ *
+ * @param {String} name the module name, e.g. "Base"
+ * @param {String} version the module version, e.g. "1.5"
+ * @param {Array} deps the array of module dependencies (as strings)
+ */
+MochiKit.Base._module = function (name, version, deps) {
+    if (!(name in MochiKit)) {
+        MochiKit[name] = {};
+    }
+    var module = MochiKit[name];
+    module.NAME = "MochiKit." + name;
+    module.VERSION = version;
+    module.__repr__ = function () {
+        return "[" + this.NAME + " " + this.VERSION + "]";
+    };
+    module.toString = function () {
+        return this.__repr__();
+    };
+    for (var i = 0; i < deps.length; i++) {
+        if (!(deps[i] in MochiKit)) {
+            throw 'MochiKit.' + name + ' depends on MochiKit.' + deps[i] + '!';
+        }
+    }
+}
+
+MochiKit.Base._module("Base", "1.5", []);
+
+/** @id MochiKit.Base.update */
+MochiKit.Base.update = function (self, obj/*, ... */) {
+    if (self === null || self === undefined) {
+        self = {};
+    }
+    for (var i = 1; i < arguments.length; i++) {
+        var o = arguments[i];
+        if (typeof(o) != 'undefined' && o !== null) {
+            for (var k in o) {
+                self[k] = o[k];
+            }
+        }
+    }
+    return self;
+};
+
+MochiKit.Base.update(MochiKit.Base, {
+    /** @id MochiKit.Base.camelize */
+    camelize: function (selector) {
+        /* from dojo.style.toCamelCase */
+        var arr = selector.split('-');
+        var cc = arr[0];
+        for (var i = 1; i < arr.length; i++) {
+            cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+        }
+        return cc;
+    },
+
+    /** @id MochiKit.Base.counter */
+    counter: function (n/* = 1 */) {
+        if (arguments.length === 0) {
+            n = 1;
+        }
+        return function () {
+            return n++;
+        };
+    },
+
+    /** @id MochiKit.Base.clone */
+    clone: function (obj) {
+        var me = arguments.callee;
+        if (arguments.length == 1) {
+            me.prototype = obj;
+            return new me();
+        }
+    },
+    
+    _flattenArray: function (res, lst) {
+        for (var i = 0; i < lst.length; i++) {
+            var o = lst[i];
+            if (o instanceof Array) {
+                arguments.callee(res, o);
+            } else {
+                res.push(o);
+            }
+        }
+        return res;
+    },
+
+    /** @id MochiKit.Base.flattenArray */
+    flattenArray: function (lst) {
+        return MochiKit.Base._flattenArray([], lst);
+    },
+
+    /** @id MochiKit.Base.flattenArguments */
+    flattenArguments: function (lst/* ...*/) {
+        var res = [];
+        var m = MochiKit.Base;
+        var args = m.extend(null, arguments);
+        while (args.length) {
+            var o = args.shift();
+            if (o && typeof(o) == "object" && typeof(o.length) == "number") {
+                for (var i = o.length - 1; i >= 0; i--) {
+                    args.unshift(o[i]);
+                }
+            } else {
+                res.push(o);
+            }
+        }
+        return res;
+    },
+
+    /** @id MochiKit.Base.extend */
+    extend: function (self, obj, /* optional */skip) {
+        // Extend an array with an array-like object starting
+        // from the skip index
+        if (!skip) {
+            skip = 0;
+        }
+        if (obj) {
+            // allow iterable fall-through, but skip the full isArrayLike
+            // check for speed, this is called often.
+            var l = obj.length;
+            if (typeof(l) != 'number' /* !isArrayLike(obj) */) {
+                if (typeof(MochiKit.Iter) != "undefined") {
+                    obj = MochiKit.Iter.list(obj);
+                    l = obj.length;
+                } else {
+                    throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+                }
+            }
+            if (!self) {
+                self = [];
+            }
+            for (var i = skip; i < l; i++) {
+                self.push(obj[i]);
+            }
+        }
+        // This mutates, but it's convenient to return because
+        // it's often used like a constructor when turning some
+        // ghetto array-like to a real array
+        return self;
+    },
+
+
+    /** @id MochiKit.Base.updatetree */
+    updatetree: function (self, obj/*, ...*/) {
+        if (self === null || self === undefined) {
+            self = {};
+        }
+        for (var i = 1; i < arguments.length; i++) {
+            var o = arguments[i];
+            if (typeof(o) != 'undefined' && o !== null) {
+                for (var k in o) {
+                    var v = o[k];
+                    if (typeof(self[k]) == 'object' && typeof(v) == 'object') {
+                        arguments.callee(self[k], v);
+                    } else {
+                        self[k] = v;
+                    }
+                }
+            }
+        }
+        return self;
+    },
+
+    /** @id MochiKit.Base.setdefault */
+    setdefault: function (self, obj/*, ...*/) {
+        if (self === null || self === undefined) {
+            self = {};
+        }
+        for (var i = 1; i < arguments.length; i++) {
+            var o = arguments[i];
+            for (var k in o) {
+                if (!(k in self)) {
+                    self[k] = o[k];
+                }
+            }
+        }
+        return self;
+    },
+
+    /** @id MochiKit.Base.keys */
+    keys: function (obj) {
+        var rval = [];
+        for (var prop in obj) {
+            rval.push(prop);
+        }
+        return rval;
+    },
+
+    /** @id MochiKit.Base.values */
+    values: function (obj) {
+        var rval = [];
+        for (var prop in obj) {
+            rval.push(obj[prop]);
+        }
+        return rval;
+    },
+
+     /** @id MochiKit.Base.items */
+    items: function (obj) {
+        var rval = [];
+        var e;
+        for (var prop in obj) {
+            var v;
+            try {
+                v = obj[prop];
+            } catch (e) {
+                continue;
+            }
+            rval.push([prop, v]);
+        }
+        return rval;
+    },
+
+
+    _newNamedError: function (module, name, func) {
+        func.prototype = new MochiKit.Base.NamedError(module.NAME + "." + name);
+        module[name] = func;
+    },
+
+
+    /** @id MochiKit.Base.operator */
+    operator: {
+        // unary logic operators
+        /** @id MochiKit.Base.truth */
+        truth: function (a) { return !!a; },
+        /** @id MochiKit.Base.lognot */
+        lognot: function (a) { return !a; },
+        /** @id MochiKit.Base.identity */
+        identity: function (a) { return a; },
+
+        // bitwise unary operators
+        /** @id MochiKit.Base.not */
+        not: function (a) { return ~a; },
+        /** @id MochiKit.Base.neg */
+        neg: function (a) { return -a; },
+
+        // binary operators
+        /** @id MochiKit.Base.add */
+        add: function (a, b) { return a + b; },
+        /** @id MochiKit.Base.sub */
+        sub: function (a, b) { return a - b; },
+        /** @id MochiKit.Base.div */
+        div: function (a, b) { return a / b; },
+        /** @id MochiKit.Base.mod */
+        mod: function (a, b) { return a % b; },
+        /** @id MochiKit.Base.mul */
+        mul: function (a, b) { return a * b; },
+
+        // bitwise binary operators
+        /** @id MochiKit.Base.and */
+        and: function (a, b) { return a & b; },
+        /** @id MochiKit.Base.or */
+        or: function (a, b) { return a | b; },
+        /** @id MochiKit.Base.xor */
+        xor: function (a, b) { return a ^ b; },
+        /** @id MochiKit.Base.lshift */
+        lshift: function (a, b) { return a << b; },
+        /** @id MochiKit.Base.rshift */
+        rshift: function (a, b) { return a >> b; },
+        /** @id MochiKit.Base.zrshift */
+        zrshift: function (a, b) { return a >>> b; },
+
+        // near-worthless built-in comparators
+        /** @id MochiKit.Base.eq */
+        eq: function (a, b) { return a == b; },
+        /** @id MochiKit.Base.ne */
+        ne: function (a, b) { return a != b; },
+        /** @id MochiKit.Base.gt */
+        gt: function (a, b) { return a > b; },
+        /** @id MochiKit.Base.ge */
+        ge: function (a, b) { return a >= b; },
+        /** @id MochiKit.Base.lt */
+        lt: function (a, b) { return a < b; },
+        /** @id MochiKit.Base.le */
+        le: function (a, b) { return a <= b; },
+
+        // strict built-in comparators
+        seq: function (a, b) { return a === b; },
+        sne: function (a, b) { return a !== b; },
+
+        // compare comparators
+        /** @id MochiKit.Base.ceq */
+        ceq: function (a, b) { return MochiKit.Base.compare(a, b) === 0; },
+        /** @id MochiKit.Base.cne */
+        cne: function (a, b) { return MochiKit.Base.compare(a, b) !== 0; },
+        /** @id MochiKit.Base.cgt */
+        cgt: function (a, b) { return MochiKit.Base.compare(a, b) == 1; },
+        /** @id MochiKit.Base.cge */
+        cge: function (a, b) { return MochiKit.Base.compare(a, b) != -1; },
+        /** @id MochiKit.Base.clt */
+        clt: function (a, b) { return MochiKit.Base.compare(a, b) == -1; },
+        /** @id MochiKit.Base.cle */
+        cle: function (a, b) { return MochiKit.Base.compare(a, b) != 1; },
+
+        // binary logical operators
+        /** @id MochiKit.Base.logand */
+        logand: function (a, b) { return a && b; },
+        /** @id MochiKit.Base.logor */
+        logor: function (a, b) { return a || b; },
+        /** @id MochiKit.Base.contains */
+        contains: function (a, b) { return b in a; }
+    },
+
+    /** @id MochiKit.Base.forwardCall */
+    forwardCall: function (func) {
+        return function () {
+            return this[func].apply(this, arguments);
+        };
+    },
+
+    /** @id MochiKit.Base.itemgetter */
+    itemgetter: function (func) {
+        return function (arg) {
+            return arg[func];
+        };
+    },
+
+    /** @id MochiKit.Base.bool */
+    bool: function (value) {
+        if (typeof(value) === "boolean" || value instanceof Boolean) {
+            return value.valueOf();
+        } else if (typeof(value) === "string" || value instanceof String) {
+            return value.length > 0 && value != "false" && value != "null" &&
+                   value != "undefined" && value != "0";
+        } else if (typeof(value) === "number" || value instanceof Number) {
+            return !isNaN(value) && value != 0;
+        } else if (value != null && typeof(value.length) === "number") {
+            return value.length !== 0
+        } else {
+            return value != null;
+        }
+    },
+
+    /** @id MochiKit.Base.typeMatcher */
+    typeMatcher: function (/* typ */) {
+        var types = {};
+        for (var i = 0; i < arguments.length; i++) {
+            var typ = arguments[i];
+            types[typ] = typ;
+        }
+        return function () {
+            for (var i = 0; i < arguments.length; i++) {
+                if (!(typeof(arguments[i]) in types)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+    },
+
+    /** @id MochiKit.Base.isNull */
+    isNull: function (/* ... */) {
+        for (var i = 0; i < arguments.length; i++) {
+            if (arguments[i] !== null) {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /** @id MochiKit.Base.isUndefinedOrNull */
+    isUndefinedOrNull: function (/* ... */) {
+        for (var i = 0; i < arguments.length; i++) {
+            var o = arguments[i];
+            if (!(typeof(o) == 'undefined' || o === null)) {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /** @id MochiKit.Base.isEmpty */
+    isEmpty: function (obj) {
+        return !MochiKit.Base.isNotEmpty.apply(this, arguments);
+    },
+
+    /** @id MochiKit.Base.isNotEmpty */
+    isNotEmpty: function (obj) {
+        for (var i = 0; i < arguments.length; i++) {
+            var o = arguments[i];
+            if (!(o && o.length)) {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /** @id MochiKit.Base.isArrayLike */
+    isArrayLike: function () {
+        for (var i = 0; i < arguments.length; i++) {
+            var o = arguments[i];
+            var typ = typeof(o);
+            if (
+                (typ != 'object' && !(typ == 'function' && typeof(o.item) == 'function')) ||
+                o === null ||
+                typeof(o.length) != 'number' ||
+                o.nodeType === 3 ||
+                o.nodeType === 4
+            ) {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /** @id MochiKit.Base.isDateLike */
+    isDateLike: function () {
+        for (var i = 0; i < arguments.length; i++) {
+            var o = arguments[i];
+            if (typeof(o) != "object" || o === null
+                    || typeof(o.getTime) != 'function') {
+                return false;
+            }
+        }
+        return true;
+    },
+
+
+    /** @id MochiKit.Base.xmap */
+    xmap: function (fn/*, obj... */) {
+        if (fn === null) {
+            return MochiKit.Base.extend(null, arguments, 1);
+        }
+        var rval = [];
+        for (var i = 1; i < arguments.length; i++) {
+            rval.push(fn(arguments[i]));
+        }
+        return rval;
+    },
+
+    /** @id MochiKit.Base.map */
+    map: function (fn, lst/*, lst... */) {
+        var m = MochiKit.Base;
+        var itr = MochiKit.Iter;
+        var isArrayLike = m.isArrayLike;
+        if (arguments.length <= 2) {
+            // allow an iterable to be passed
+            if (!isArrayLike(lst)) {
+                if (itr) {
+                    // fast path for map(null, iterable)
+                    lst = itr.list(lst);
+                    if (fn === null) {
+                        return lst;
+                    }
+                } else {
+                    throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+                }
+            }
+            // fast path for map(null, lst)
+            if (fn === null) {
+                return m.extend(null, lst);
+            }
+            // disabled fast path for map(fn, lst)
+            /*
+            if (false && typeof(Array.prototype.map) == 'function') {
+                // Mozilla fast-path
+                return Array.prototype.map.call(lst, fn);
+            }
+            */
+            var rval = [];
+            for (var i = 0; i < lst.length; i++) {
+                rval.push(fn(lst[i]));
+            }
+            return rval;
+        } else {
+            // default for map(null, ...) is zip(...)
+            if (fn === null) {
+                fn = Array;
+            }
+            var length = null;
+            for (var i = 1; i < arguments.length; i++) {
+                // allow iterables to be passed
+                if (!isArrayLike(arguments[i])) {
+                    if (itr) {
+                        return itr.list(itr.imap.apply(null, arguments));
+                    } else {
+                        throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+                    }
+                }
+                // find the minimum length
+                var l = arguments[i].length;
+                if (length === null || length > l) {
+                    length = l;
+                }
+            }
+            rval = [];
+            for (var i = 0; i < length; i++) {
+                var args = [];
+                for (var j = 1; j < arguments.length; j++) {
+                    args.push(arguments[j][i]);
+                }
+                rval.push(fn.apply(this, args));
+            }
+            return rval;
+        }
+    },
+
+    /** @id MochiKit.Base.xfilter */
+    xfilter: function (fn/*, obj... */) {
+        var rval = [];
+        if (fn === null) {
+            fn = MochiKit.Base.operator.truth;
+        }
+        for (var i = 1; i < arguments.length; i++) {
+            var o = arguments[i];
+            if (fn(o)) {
+                rval.push(o);
+            }
+        }
+        return rval;
+    },
+
+    /** @id MochiKit.Base.filter */
+    filter: function (fn, lst, self) {
+        var rval = [];
+        // allow an iterable to be passed
+        var m = MochiKit.Base;
+        if (!m.isArrayLike(lst)) {
+            if (MochiKit.Iter) {
+                lst = MochiKit.Iter.list(lst);
+            } else {
+                throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+            }
+        }
+        if (fn === null) {
+            fn = m.operator.truth;
+        }
+        if (typeof(Array.prototype.filter) == 'function') {
+            // Mozilla fast-path
+            return Array.prototype.filter.call(lst, fn, self);
+        } else if (typeof(self) == 'undefined' || self === null) {
+            for (var i = 0; i < lst.length; i++) {
+                var o = lst[i];
+                if (fn(o)) {
+                    rval.push(o);
+                }
+            }
+        } else {
+            for (var i = 0; i < lst.length; i++) {
+                o = lst[i];
+                if (fn.call(self, o)) {
+                    rval.push(o);
+                }
+            }
+        }
+        return rval;
+    },
+
+
+    _wrapDumbFunction: function (func) {
+        return function () {
+            // fast path!
+            switch (arguments.length) {
+                case 0: return func();
+                case 1: return func(arguments[0]);
+                case 2: return func(arguments[0], arguments[1]);
+                case 3: return func(arguments[0], arguments[1], arguments[2]);
+            }
+            var args = [];
+            for (var i = 0; i < arguments.length; i++) {
+                args.push("arguments[" + i + "]");
+            }
+            return eval("(func(" + args.join(",") + "))");
+        };
+    },
+
+    /** @id MochiKit.Base.methodcaller */
+    methodcaller: function (func/*, args... */) {
+        var args = MochiKit.Base.extend(null, arguments, 1);
+        if (typeof(func) == "function") {
+            return function (obj) {
+                return func.apply(obj, args);
+            };
+        } else {
+            return function (obj) {
+                return obj[func].apply(obj, args);
+            };
+        }
+    },
+
+    /** @id MochiKit.Base.method */
+    method: function (self, func) {
+        var m = MochiKit.Base;
+        return m.bind.apply(this, m.extend([func, self], arguments, 2));
+    },
+
+    /** @id MochiKit.Base.compose */
+    compose: function (f1, f2/*, f3, ... fN */) {
+        var fnlist = [];
+        var m = MochiKit.Base;
+        if (arguments.length === 0) {
+            throw new TypeError("compose() requires at least one argument");
+        }
+        for (var i = 0; i < arguments.length; i++) {
+            var fn = arguments[i];
+            if (typeof(fn) != "function") {
+                throw new TypeError(m.repr(fn) + " is not a function");
+            }
+            fnlist.push(fn);
+        }
+        return function () {
+            var args = arguments;
+            for (var i = fnlist.length - 1; i >= 0; i--) {
+                args = [fnlist[i].apply(this, args)];
+            }
+            return args[0];
+        };
+    },
+
+    /** @id MochiKit.Base.bind */
+    bind: function (func, self/* args... */) {
+        if (typeof(func) == "string") {
+            func = self[func];
+        }
+        var im_func = func.im_func;
+        var im_preargs = func.im_preargs;
+        var im_self = func.im_self;
+        var m = MochiKit.Base;
+        if (typeof(func) == "function" && typeof(func.apply) == "undefined") {
+            // this is for cases where JavaScript sucks ass and gives you a
+            // really dumb built-in function like alert() that doesn't have
+            // an apply
+            func = m._wrapDumbFunction(func);
+        }
+        if (typeof(im_func) != 'function') {
+            im_func = func;
+        }
+        if (typeof(self) != 'undefined') {
+            im_self = self;
+        }
+        if (typeof(im_preargs) == 'undefined') {
+            im_preargs = [];
+        } else  {
+            im_preargs = im_preargs.slice();
+        }
+        m.extend(im_preargs, arguments, 2);
+        var newfunc = function () {
+            var args = arguments;
+            var me = arguments.callee;
+            if (me.im_preargs.length > 0) {
+                args = m.concat(me.im_preargs, args);
+            }
+            var self = me.im_self;
+            if (!self) {
+                self = this;
+            }
+            return me.im_func.apply(self, args);
+        };
+        newfunc.im_self = im_self;
+        newfunc.im_func = im_func;
+        newfunc.im_preargs = im_preargs;
+        return newfunc;
+    },
+
+    /** @id MochiKit.Base.bindLate */
+    bindLate: function (func, self/* args... */) {
+        var m = MochiKit.Base;
+        var args = arguments;
+        if (typeof(func) === "string") {
+            args = m.extend([m.forwardCall(func)], arguments, 1);
+            return m.bind.apply(this, args);
+        }
+        return m.bind.apply(this, args);
+    },
+
+    /** @id MochiKit.Base.bindMethods */
+    bindMethods: function (self) {
+        var bind = MochiKit.Base.bind;
+        for (var k in self) {
+            var func = self[k];
+            if (typeof(func) == 'function') {
+                self[k] = bind(func, self);
+            }
+        }
+    },
+
+    /** @id MochiKit.Base.registerComparator */
+    registerComparator: function (name, check, comparator, /* optional */ override) {
+        MochiKit.Base.comparatorRegistry.register(name, check, comparator, override);
+    },
+
+    _primitives: {'boolean': true, 'string': true, 'number': true},
+
+    /** @id MochiKit.Base.compare */
+    compare: function (a, b) {
+        if (a == b) {
+            return 0;
+        }
+        var aIsNull = (typeof(a) == 'undefined' || a === null);
+        var bIsNull = (typeof(b) == 'undefined' || b === null);
+        if (aIsNull && bIsNull) {
+            return 0;
+        } else if (aIsNull) {
+            return -1;
+        } else if (bIsNull) {
+            return 1;
+        }
+        var m = MochiKit.Base;
+        // bool, number, string have meaningful comparisons
+        var prim = m._primitives;
+        if (!(typeof(a) in prim && typeof(b) in prim)) {
+            try {
+                return m.comparatorRegistry.match(a, b);
+            } catch (e) {
+                if (e != m.NotFound) {
+                    throw e;
+                }
+            }
+        }
+        if (a < b) {
+            return -1;
+        } else if (a > b) {
+            return 1;
+        }
+        // These types can't be compared
+        var repr = m.repr;
+        throw new TypeError(repr(a) + " and " + repr(b) + " can not be compared");
+    },
+
+    /** @id MochiKit.Base.compareDateLike */
+    compareDateLike: function (a, b) {
+        return MochiKit.Base.compare(a.getTime(), b.getTime());
+    },
+
+    /** @id MochiKit.Base.compareArrayLike */
+    compareArrayLike: function (a, b) {
+        var compare = MochiKit.Base.compare;
+        var count = a.length;
+        var rval = 0;
+        if (count > b.length) {
+            rval = 1;
+            count = b.length;
+        } else if (count < b.length) {
+            rval = -1;
+        }
+        for (var i = 0; i < count; i++) {
+            var cmp = compare(a[i], b[i]);
+            if (cmp) {
+                return cmp;
+            }
+        }
+        return rval;
+    },
+
+    /** @id MochiKit.Base.registerRepr */
+    registerRepr: function (name, check, wrap, /* optional */override) {
+        MochiKit.Base.reprRegistry.register(name, check, wrap, override);
+    },
+
+    /** @id MochiKit.Base.repr */
+    repr: function (o) {
+        if (typeof(o) == "undefined") {
+            return "undefined";
+        } else if (o === null) {
+            return "null";
+        }
+        try {
+            if (typeof(o.__repr__) == 'function') {
+                return o.__repr__();
+            } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
+                return o.repr();
+            }
+            return MochiKit.Base.reprRegistry.match(o);
+        } catch (e) {
+            if (typeof(o.NAME) == 'string' && (
+                    o.toString == Function.prototype.toString ||
+                    o.toString == Object.prototype.toString
+                )) {
+                return o.NAME;
+            }
+        }
+        try {
+            var ostring = (o + "");
+        } catch (e) {
+            return "[" + typeof(o) + "]";
+        }
+        if (typeof(o) == "function") {
+            ostring = ostring.replace(/^\s+/, "").replace(/\s+/g, " ");
+            ostring = ostring.replace(/,(\S)/, ", $1");
+            var idx = ostring.indexOf("{");
+            if (idx != -1) {
+                ostring = ostring.substr(0, idx) + "{...}";
+            }
+        }
+        return ostring;
+    },
+
+    /** @id MochiKit.Base.reprArrayLike */
+    reprArrayLike: function (o) {
+        var m = MochiKit.Base;
+        return "[" + m.map(m.repr, o).join(", ") + "]";
+    },
+
+    /** @id MochiKit.Base.reprString */
+    reprString: function (o) {
+        return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+            ).replace(/[\f]/g, "\\f"
+            ).replace(/[\b]/g, "\\b"
+            ).replace(/[\n]/g, "\\n"
+            ).replace(/[\t]/g, "\\t"
+            ).replace(/[\v]/g, "\\v"
+            ).replace(/[\r]/g, "\\r");
+    },
+
+    /** @id MochiKit.Base.reprNumber */
+    reprNumber: function (o) {
+        return o + "";
+    },
+
+    /** @id MochiKit.Base.registerJSON */
+    registerJSON: function (name, check, wrap, /* optional */override) {
+        MochiKit.Base.jsonRegistry.register(name, check, wrap, override);
+    },
+
+
+    /** @id MochiKit.Base.evalJSON */
+    evalJSON: function () {
+        return eval("(" + MochiKit.Base._filterJSON(arguments[0]) + ")");
+    },
+
+    _filterJSON: function (s) {
+        var m = s.match(/^\s*\/\*(.*)\*\/\s*$/);
+        if (m) {
+            return m[1];
+        }
+        return s;
+    },
+
+    /** @id MochiKit.Base.serializeJSON */
+    serializeJSON: function (o) {
+        var objtype = typeof(o);
+        if (objtype == "number" || objtype == "boolean") {
+            return o + "";
+        } else if (o === null) {
+            return "null";
+        } else if (objtype == "string") {
+            var res = "";
+            for (var i = 0; i < o.length; i++) {
+                var c = o.charAt(i);
+                if (c == '\"') {
+                    res += '\\"';
+                } else if (c == '\\') {
+                    res += '\\\\';
+                } else if (c == '\b') {
+                    res += '\\b';
+                } else if (c == '\f') {
+                    res += '\\f';
+                } else if (c == '\n') {
+                    res += '\\n';
+                } else if (c == '\r') {
+                    res += '\\r';
+                } else if (c == '\t') {
+                    res += '\\t';
+                } else if (o.charCodeAt(i) <= 0x1F) {
+                    var hex = o.charCodeAt(i).toString(16);
+                    if (hex.length < 2) {
+                        hex = '0' + hex;
+                    }
+                    res += '\\u00' + hex.toUpperCase();
+                } else {
+                    res += c;
+                }
+            }
+            return '"' + res + '"';
+        }
+        // recurse
+        var me = arguments.callee;
+        // short-circuit for objects that support "json" serialization
+        // if they return "self" then just pass-through...
+        var newObj;
+        if (typeof(o.__json__) == "function") {
+            newObj = o.__json__();
+            if (o !== newObj) {
+                return me(newObj);
+            }
+        }
+        if (typeof(o.json) == "function") {
+            newObj = o.json();
+            if (o !== newObj) {
+                return me(newObj);
+            }
+        }
+        // array
+        if (objtype != "function" && typeof(o.length) == "number") {
+            var res = [];
+            for (var i = 0; i < o.length; i++) {
+                var val = me(o[i]);
+                if (typeof(val) != "string") {
+                    // skip non-serializable values
+                    continue;
+                }
+                res.push(val);
+            }
+            return "[" + res.join(", ") + "]";
+        }
+        // look in the registry
+        var m = MochiKit.Base;
+        try {
+            newObj = m.jsonRegistry.match(o);
+            if (o !== newObj) {
+                return me(newObj);
+            }
+        } catch (e) {
+            if (e != m.NotFound) {
+                // something really bad happened
+                throw e;
+            }
+        }
+        // undefined is outside of the spec
+        if (objtype == "undefined") {
+            throw new TypeError("undefined can not be serialized as JSON");
+        }
+        // it's a function with no adapter, bad
+        if (objtype == "function") {
+            return null;
+        }
+        // generic object code path
+        res = [];
+        for (var k in o) {
+            var useKey;
+            if (typeof(k) == "number") {
+                useKey = '"' + k + '"';
+            } else if (typeof(k) == "string") {
+                useKey = me(k);
+            } else {
+                // skip non-string or number keys
+                continue;
+            }
+            val = me(o[k]);
+            if (typeof(val) != "string") {
+                // skip non-serializable values
+                continue;
+            }
+            res.push(useKey + ":" + val);
+        }
+        return "{" + res.join(", ") + "}";
+    },
+
+
+    /** @id MochiKit.Base.objEqual */
+    objEqual: function (a, b) {
+        return (MochiKit.Base.compare(a, b) === 0);
+    },
+
+    /** @id MochiKit.Base.arrayEqual */
+    arrayEqual: function (self, arr) {
+        if (self.length != arr.length) {
+            return false;
+        }
+        return (MochiKit.Base.compare(self, arr) === 0);
+    },
+
+    /** @id MochiKit.Base.concat */
+    concat: function (/* lst... */) {
+        var rval = [];
+        var extend = MochiKit.Base.extend;
+        for (var i = 0; i < arguments.length; i++) {
+            extend(rval, arguments[i]);
+        }
+        return rval;
+    },
+
+    /** @id MochiKit.Base.keyComparator */
+    keyComparator: function (key/* ... */) {
+        // fast-path for single key comparisons
+        var m = MochiKit.Base;
+        var compare = m.compare;
+        if (arguments.length == 1) {
+            return function (a, b) {
+                return compare(a[key], b[key]);
+            };
+        }
+        var compareKeys = m.extend(null, arguments);
+        return function (a, b) {
+            var rval = 0;
+            // keep comparing until something is inequal or we run out of
+            // keys to compare
+            for (var i = 0; (rval === 0) && (i < compareKeys.length); i++) {
+                var key = compareKeys[i];
+                rval = compare(a[key], b[key]);
+            }
+            return rval;
+        };
+    },
+
+    /** @id MochiKit.Base.reverseKeyComparator */
+    reverseKeyComparator: function (key) {
+        var comparator = MochiKit.Base.keyComparator.apply(this, arguments);
+        return function (a, b) {
+            return comparator(b, a);
+        };
+    },
+
+    /** @id MochiKit.Base.partial */
+    partial: function (func) {
+        var m = MochiKit.Base;
+        return m.bind.apply(this, m.extend([func, undefined], arguments, 1));
+    },
+
+    /** @id MochiKit.Base.listMinMax */
+    listMinMax: function (which, lst) {
+        if (lst.length === 0) {
+            return null;
+        }
+        var cur = lst[0];
+        var compare = MochiKit.Base.compare;
+        for (var i = 1; i < lst.length; i++) {
+            var o = lst[i];
+            if (compare(o, cur) == which) {
+                cur = o;
+            }
+        }
+        return cur;
+    },
+
+    /** @id MochiKit.Base.objMax */
+    objMax: function (/* obj... */) {
+        return MochiKit.Base.listMinMax(1, arguments);
+    },
+
+    /** @id MochiKit.Base.objMin */
+    objMin: function (/* obj... */) {
+        return MochiKit.Base.listMinMax(-1, arguments);
+    },
+
+    /** @id MochiKit.Base.findIdentical */
+    findIdentical: function (lst, value, start/* = 0 */, /* optional */end) {
+        if (typeof(end) == "undefined" || end === null) {
+            end = lst.length;
+        }
+        if (typeof(start) == "undefined" || start === null) {
+            start = 0;
+        }
+        for (var i = start; i < end; i++) {
+            if (lst[i] === value) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    /** @id MochiKit.Base.mean */
+    mean: function(/* lst... */) {
+        /* http://www.nist.gov/dads/HTML/mean.html */
+        var sum = 0;
+
+        var m = MochiKit.Base;
+        var args = m.extend(null, arguments);
+        var count = args.length;
+
+        while (args.length) {
+            var o = args.shift();
+            if (o && typeof(o) == "object" && typeof(o.length) == "number") {
+                count += o.length - 1;
+                for (var i = o.length - 1; i >= 0; i--) {
+                    sum += o[i];
+                }
+            } else {
+                sum += o;
+            }
+        }
+
+        if (count <= 0) {
+            throw new TypeError('mean() requires at least one argument');
+        }
+
+        return sum/count;
+    },
+
+    /** @id MochiKit.Base.median */
+    median: function(/* lst... */) {
+        /* http://www.nist.gov/dads/HTML/median.html */
+        var data = MochiKit.Base.flattenArguments(arguments);
+        if (data.length === 0) {
+            throw new TypeError('median() requires at least one argument');
+        }
+        data.sort(compare);
+        if (data.length % 2 == 0) {
+            var upper = data.length / 2;
+            return (data[upper] + data[upper - 1]) / 2;
+        } else {
+            return data[(data.length - 1) / 2];
+        }
+    },
+
+    /** @id MochiKit.Base.findValue */
+    findValue: function (lst, value, start/* = 0 */, /* optional */end) {
+        if (typeof(end) == "undefined" || end === null) {
+            end = lst.length;
+        }
+        if (typeof(start) == "undefined" || start === null) {
+            start = 0;
+        }
+        var cmp = MochiKit.Base.compare;
+        for (var i = start; i < end; i++) {
+            if (cmp(lst[i], value) === 0) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    /** @id MochiKit.Base.nodeWalk */
+    nodeWalk: function (node, visitor) {
+        var nodes = [node];
+        var extend = MochiKit.Base.extend;
+        while (nodes.length) {
+            var res = visitor(nodes.shift());
+            if (res) {
+                extend(nodes, res);
+            }
+        }
+    },
+
+
+    /** @id MochiKit.Base.nameFunctions */
+    nameFunctions: function (namespace) {
+        var base = namespace.NAME;
+        if (typeof(base) == 'undefined') {
+            base = '';
+        } else {
+            base = base + '.';
+        }
+        for (var name in namespace) {
+            var o = namespace[name];
+            if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
+                try {
+                    o.NAME = base + name;
+                } catch (e) {
+                    // pass
+                }
+            }
+        }
+    },
+
+
+    /** @id MochiKit.Base.queryString */
+    queryString: function (names, values) {
+        // check to see if names is a string or a DOM element, and if
+        // MochiKit.DOM is available.  If so, drop it like it's a form
+        // Ugliest conditional in MochiKit?  Probably!
+        if (typeof(MochiKit.DOM) != "undefined" && arguments.length == 1
+            && (typeof(names) == "string" || (
+                typeof(names.nodeType) != "undefined" && names.nodeType > 0
+            ))
+        ) {
+            var kv = MochiKit.DOM.formContents(names);
+            names = kv[0];
+            values = kv[1];
+        } else if (arguments.length == 1) {
+            // Allow the return value of formContents to be passed directly
+            if (typeof(names.length) == "number" && names.length == 2) {
+                return arguments.callee(names[0], names[1]);
+            }
+            var o = names;
+            names = [];
+            values = [];
+            for (var k in o) {
+                var v = o[k];
+                if (typeof(v) == "function") {
+                    continue;
+                } else if (MochiKit.Base.isArrayLike(v)){
+                    for (var i = 0; i < v.length; i++) {
+                        names.push(k);
+                        values.push(v[i]);
+                    }
+                } else {
+                    names.push(k);
+                    values.push(v);
+                }
+            }
+        }
+        var rval = [];
+        var len = Math.min(names.length, values.length);
+        var urlEncode = MochiKit.Base.urlEncode;
+        for (var i = 0; i < len; i++) {
+            v = values[i];
+            if (typeof(v) != 'undefined' && v !== null) {
+                rval.push(urlEncode(names[i]) + "=" + urlEncode(v));
+            }
+        }
+        return rval.join("&");
+    },
+
+
+    /** @id MochiKit.Base.parseQueryString */
+    parseQueryString: function (encodedString, useArrays) {
+        // strip a leading '?' from the encoded string
+        var qstr = (encodedString.charAt(0) == "?")
+            ? encodedString.substring(1)
+            : encodedString;
+        var pairs = qstr.replace(/\+/g, "%20").split(/\&amp\;|\&\#38\;|\&#x26;|\&/);
+        var o = {};
+        var decode;
+        if (typeof(decodeURIComponent) != "undefined") {
+            decode = decodeURIComponent;
+        } else {
+            decode = unescape;
+        }
+        if (useArrays) {
+            for (var i = 0; i < pairs.length; i++) {
+                var pair = pairs[i].split("=");
+                var name = decode(pair.shift());
+                if (!name) {
+                    continue;
+                }
+                var arr = o[name];
+                if (!(arr instanceof Array)) {
+                    arr = [];
+                    o[name] = arr;
+                }
+                arr.push(decode(pair.join("=")));
+            }
+        } else {
+            for (var i = 0; i < pairs.length; i++) {
+                pair = pairs[i].split("=");
+                var name = pair.shift();
+                if (!name) {
+                    continue;
+                }
+                o[decode(name)] = decode(pair.join("="));
+            }
+        }
+        return o;
+    }
+});
+
+/** @id MochiKit.Base.AdapterRegistry */
+MochiKit.Base.AdapterRegistry = function () {
+    this.pairs = [];
+};
+
+MochiKit.Base.AdapterRegistry.prototype = {
+    /** @id MochiKit.Base.AdapterRegistry.prototype.register */
+    register: function (name, check, wrap, /* optional */ override) {
+        if (override) {
+            this.pairs.unshift([name, check, wrap]);
+        } else {
+            this.pairs.push([name, check, wrap]);
+        }
+    },
+
+    /** @id MochiKit.Base.AdapterRegistry.prototype.match */
+    match: function (/* ... */) {
+        for (var i = 0; i < this.pairs.length; i++) {
+            var pair = this.pairs[i];
+            if (pair[1].apply(this, arguments)) {
+                return pair[2].apply(this, arguments);
+            }
+        }
+        throw MochiKit.Base.NotFound;
+    },
+
+    /** @id MochiKit.Base.AdapterRegistry.prototype.unregister */
+    unregister: function (name) {
+        for (var i = 0; i < this.pairs.length; i++) {
+            var pair = this.pairs[i];
+            if (pair[0] == name) {
+                this.pairs.splice(i, 1);
+                return true;
+            }
+        }
+        return false;
+    }
+};
+
+MochiKit.Base._exportSymbols = function (globals, module) {
+    if (MochiKit.__export__ === false || module.__export__ === false) {
+        return;
+    }
+    for (var k in module) {
+        var v = module[k];
+        if (v != null) {
+            var okName = (k[0] !== "_" && k !== "toString");
+            if (v.__export__ === true || (v.__export__ !== false && okName)) {
+                globals[k] = module[k];
+            }
+        }
+    }
+};
+
+/**
+ * Creates a deprecated function alias in the specified module. The
+ * deprecated function will forward all calls and arguments to a
+ * target function, while also logging a debug message on the first
+ * call (if MochiKit.Logging is loaded). The destination function may
+ * be located in another module, which must be loaded, or an
+ * exception will be thrown.
+ *
+ * @param {Object/String} module the source module or module name
+ *            (e.g. 'DOM' or 'MochiKit.DOM')
+ * @param {String} name the deprecated function name (e.g. 'getStyle')
+ * @param {String} target the fully qualified name of the target
+ *            function (e.g. 'MochiKit.Style.getStyle')
+ * @param {String} version the first version when the source function
+ *            was deprecated (e.g. '1.4')
+ * @param {Boolean} [exportable] the exportable function flag,
+ *            defaults to true
+ */
+MochiKit.Base._deprecated = function (module, name, target, version, exportable) {
+    if (typeof(module) === 'string') {
+        if (module.indexOf('MochiKit.') === 0) {
+            module = module.substring(9);
+        }
+        module = MochiKit[module];
+    }