if (typeof LMI === 'undefined') {
    window.LMI = {};
} (function() {
    function getObject(obj, create, parent) {
        parent = parent || window;
        var i = obj.indexOf('.');
        if (i < 0) {
            if (obj in parent) {
                return parent[obj];
            } else if (create) {
                return (parent[obj] = {});
            }
        } else {
            var tmp = obj.substring(0, i);
            var rest = obj.substring(i + 1);
            if (tmp) {
                if (! (tmp in parent) && create) {
                    parent[tmp] = {};
                }
                return getObject(rest, create, parent[tmp]);
            }
        }
        return null;
    }
    var L = getObject("LMI.Lang", true);
    L.getObject = getObject;
    L.extend = function(child, parent) {
        function P() {}
        P.prototype = parent.prototype;
        child.prototype = new P();
        child.prototype.constructor = child;
        child.superclass = parent.prototype;
    };
    L.importFunctions = function(cls, intrfc) {
        if (typeof intrfc.ExportFunctions != 'undefined') {
            for (var i in intrfc.ExportFunctions) {
                if (intrfc.ExportFunctions.hasOwnProperty(i)) {
                    cls.prototype[i] = intrfc.ExportFunctions[i];
                }
            }
        }
    };
    L.useObject = function(objName, func) {
        var obj = (typeof(objName) === 'object' ? objName: L.getObject(objName));
        if (typeof(obj) === 'object') {
            func(obj);
        }
    };
    L.forEach = function(list, func, scope) {
        var i, l;
        if (list.forEach) {
            list.forEach(func, scope);
        } else {
            for (i = 0, l = list.length; i < l; ++i) {
                func.call(scope, list[i], i, list);
            }
        }
    };
    L.filter = function(list, func) {
        var i, l = list.length,
        a = [];
        for (i = 0; i < l; ++i) {
            if (func(list[i])) {
                a.push(list[i]);
            }
        }
        return a;
    };
    L.some = function(list, func) {
        var i, l = list.length;
        for (i = 0; i < l; ++i) {
            if (func(list[i])) {
                return true;
            }
        }
        return false;
    };
    L.indexOf = function(list, el, start) {
        start = start || 0;
        var i = start,
        len = list.length;
        for (; i < len; ++i) {
            if (list[i] === el) {
                return i;
            }
        }
        return - 1;
    };
    L.mergeObjects = function(base, override) {
        var i;
        if (base && override) {
            for (i in override) {
                if (override.hasOwnProperty(i)) {
                    base[i] = override[i];
                }
            }
        }
        return base;
    };
})();
if (typeof(Ext) === 'undefined') {
    Ext = {};
}
Ext.DomQuery = function() {
    var cache = {},
    simpleCache = {},
    valueCache = {};
    var nonSpace = /\S/;
    var trimRe = /^\s*(.*?)\s*$/;
    var tplRe = /\{(\d+)\}/g;
    var modeRe = /^(\s?[\/>]\s?|\s|$)/;
    var tagTokenRe = /^(#)?([\w-\*\|]+)/;
    function child(p, index) {
        var i = 0;
        var n = p.firstChild;
        while (n) {
            if (n.nodeType == 1) {
                if (++i == index) {
                    return n;
                }
            }
            n = n.nextSibling;
        }
        return null;
    };
    function next(n) {
        while ((n = n.nextSibling) && n.nodeType != 1);
        return n;
    };
    function prev(n) {
        while ((n = n.previousSibling) && n.nodeType != 1);
        return n;
    };
    function clean(d) {
        var n = d.firstChild,
        ni = -1;
        while (n) {
            var nx = n.nextSibling;
            if (n.nodeType == 3 && !nonSpace.test(n.nodeValue)) {
                d.removeChild(n);
            } else {
                n.nodeIndex = ++ni;
            }
            n = nx;
        }
        return this;
    };
    function byClassName(c, a, v, re, cn) {
        if (!v) {
            return c;
        }
        var r = [];
        for (var i = 0, ci; ci = c[i]; i++) {
            cn = ci.className;
            if (cn && (' ' + cn + ' ').indexOf(v) != -1) {
                r[r.length] = ci;
            }
        }
        return r;
    };
    function attrValue(n, attr) {
        if (!n.tagName && typeof n.length != "undefined") {
            n = n[0];
        }
        if (!n) {
            return null;
        }
        if (attr == "for") {
            return n.htmlFor;
        }
        if (attr == "class" || attr == "className") {
            return n.className;
        }
        return n.getAttribute(attr) || n[attr];
    };
    function getNodes(ns, mode, tagName) {
        var result = [],
        cs;
        if (!ns) {
            return result;
        }
        mode = mode ? mode.replace(trimRe, "$1") : "";
        tagName = tagName || "*";
        if (typeof ns.getElementsByTagName != "undefined") {
            ns = [ns];
        }
        if (mode != "/" && mode != ">") {
            for (var i = 0, ni; ni = ns[i]; i++) {
                cs = ni.getElementsByTagName(tagName);
                for (var j = 0, ci; ci = cs[j]; j++) {
                    result[result.length] = ci;
                }
            }
        } else {
            for (var i = 0, ni; ni = ns[i]; i++) {
                var cn = ni.getElementsByTagName(tagName);
                for (var j = 0, cj; cj = cn[j]; j++) {
                    if (cj.parentNode == ni) {
                        result[result.length] = cj;
                    }
                }
            }
        }
        return result;
    };
    function concat(a, b) {
        if (b.slice) {
            return a.concat(b);
        }
        for (var i = 0, l = b.length; i < l; i++) {
            a[a.length] = b[i];
        }
        return a;
    }
    function byTag(cs, tagName) {
        if (cs.tagName || cs == document) {
            cs = [cs];
        }
        if (!tagName) {
            return cs;
        }
        var r = [];
        tagName = tagName.toLowerCase();
        for (var i = 0, ci; ci = cs[i]; i++) {
            if (ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName) {
                r[r.length] = ci;
            }
        }
        return r;
    };
    function byId(cs, attr, id) {
        if (cs.tagName || cs == document) {
            cs = [cs];
        }
        if (!id) {
            return cs;
        }
        var r = [];
        for (var i = 0, ci; ci = cs[i]; i++) {
            if (ci && ci.id == id) {
                r[r.length] = ci;
                return r;
            }
        }
        return r;
    };
    function byAttribute(cs, attr, value, op, custom) {
        var r = [],
        st = custom == "{";
        var f = Ext.DomQuery.operators[op];
        for (var i = 0; ci = cs[i]; i++) {
            var a;
            if (st) {
                a = Ext.DomQuery.getStyle(ci, attr);
            }
            else if (attr == "class" || attr == "className") {
                a = ci.className;
            } else if (attr == "for") {
                a = ci.htmlFor;
            } else if (attr == "href") {
                a = ci.getAttribute("href", 2);
            } else {
                a = ci.getAttribute(attr);
            }
            if ((f && f(a, value)) || (!f && a)) {
                r[r.length] = ci;
            }
        }
        return r;
    };
    function byPseudo(cs, name, value) {
        return Ext.DomQuery.pseudos[name](cs, value);
    };
    var isIE = window.ActiveXObject ? true: false;
    var key = 30803;
    function nodupIEXml(cs) {
        var d = ++key;
        cs[0].setAttribute("_nodup", d);
        var r = [cs[0]];
        for (var i = 1, len = cs.length; i < len; i++) {
            var c = cs[i];
            if (!c.getAttribute("_nodup") != d) {
                c.setAttribute("_nodup", d);
                r[r.length] = c;
            }
        }
        for (var i = 0, len = cs.length; i < len; i++) {
            cs[i].removeAttribute("_nodup");
        }
        return r;
    }
    function nodup(cs) {
        var len, c, i, r = cs,
        cj;
        if (cs === null) {
            return [];
        }
        len = cs.length;
        if (!len || typeof cs.nodeType != "undefined" || len == 1) {
            return cs;
        }
        if (isIE && typeof cs[0].selectSingleNode != "undefined") {
            return nodupIEXml(cs);
        }
        var d = ++key;
        cs[0]._nodup = d;
        for (i = 1; c = cs[i]; i++) {
            if (c._nodup != d) {
                c._nodup = d;
            } else {
                r = [];
                for (var j = 0; j < i; j++) {
                    r[r.length] = cs[j];
                }
                for (j = i + 1; cj = cs[j]; j++) {
                    if (cj._nodup != d) {
                        cj._nodup = d;
                        r[r.length] = cj;
                    }
                }
                return r;
            }
        }
        return r;
    }
    function quickDiffIEXml(c1, c2) {
        var d = ++key;
        for (var i = 0, len = c1.length; i < len; i++) {
            c1[i].setAttribute("_qdiff", d);
        }
        var r = [];
        for (var i = 0, len = c2.length; i < len; i++) {
            if (c2[i].getAttribute("_qdiff") != d) {
                r[r.length] = c2[i];
            }
        }
        for (var i = 0, len = c1.length; i < len; i++) {
            c1[i].removeAttribute("_qdiff");
        }
        return r;
    }
    function quickDiff(c1, c2) {
        var len1 = c1.length;
        if (!len1) {
            return c2;
        }
        if (isIE && c1[0].selectSingleNode) {
            return quickDiffIEXml(c1, c2);
        }
        var d = ++key;
        for (var i = 0; i < len1; i++) {
            c1[i]._qdiff = d;
        }
        var r = [];
        for (var i = 0, len = c2.length; i < len; i++) {
            if (c2[i]._qdiff != d) {
                r[r.length] = c2[i];
            }
        }
        return r;
    }
    function gebi(parent, id) {
        var r = parent.getElementById(id);
        return r && r.id === id ? r: null;
    }
    function quickId(ns, mode, root, id) {
        if (ns == root) {
            var d = root.ownerDocument || root;
            return gebi(d, id);
        }
        ns = getNodes(ns, mode, "*");
        return byId(ns, null, id);
    }
    return {
        getStyle: function(el, name) {
            return Ext.fly(el).getStyle(name);
        },
        compile: function(path, type) {
            while (path.substr(0, 1) == "/") {
                path = path.substr(1);
            }
            type = type || "select";
            var fn = ["var f = function(root){\n var mode; var n = root || document;\n"];
            var q = path,
            mode, lq;
            var tk = Ext.DomQuery.matchers;
            var tklen = tk.length;
            var mm;
            while (q && lq != q) {
                lq = q;
                var tm = q.match(tagTokenRe);
                if (type == "select") {
                    if (tm) {
                        if (tm[1] == "#") {
                            fn[fn.length] = 'n = quickId(n, mode, root, "' + tm[2] + '");';
                        } else {
                            fn[fn.length] = 'n = getNodes(n, mode, "' + tm[2] + '");';
                        }
                        q = q.replace(tm[0], "");
                    } else if (q.substr(0, 1) != '@') {
                        fn[fn.length] = 'n = getNodes(n, mode, "*");';
                    }
                } else {
                    if (tm) {
                        if (tm[1] == "#") {
                            fn[fn.length] = 'n = byId(n, null, "' + tm[2] + '");';
                        } else {
                            fn[fn.length] = 'n = byTag(n, "' + tm[2] + '");';
                        }
                        q = q.replace(tm[0], "");
                    }
                }
                while (! (mm = q.match(modeRe))) {
                    var matched = false;
                    for (var j = 0; j < tklen; j++) {
                        var t = tk[j];
                        var m = q.match(t.re);
                        if (m) {
                            fn[fn.length] = t.select.replace(tplRe,
                            function(x, i) {
                                return m[i];
                            });
                            q = q.replace(m[0], "");
                            matched = true;
                            break;
                        }
                    }
                    if (!matched) {
                        throw 'Error parsing selector, parsing failed at "' + q + '"';
                    }
                }
                if (mm[1]) {
                    fn[fn.length] = 'mode="' + mm[1] + '";';
                    q = q.replace(mm[1], "");
                }
            }
            fn[fn.length] = "return nodup(n);\n}";
            eval(fn.join(""));
            return f;
        },
        select: function(path, root, type) {
            if (!root || root == document) {
                root = document;
            }
            if (typeof root == "string") {
                root = gebi(document, root);
            }
            var paths = path.split(",");
            var results = [];
            for (var i = 0, len = paths.length; i < len; i++) {
                var p = paths[i].replace(trimRe, "$1");
                if (!cache[p]) {
                    cache[p] = Ext.DomQuery.compile(p);
                    if (!cache[p]) {
                        throw p + " is not a valid selector";
                    }
                }
                var result = cache[p](root);
                if (result && result != document) {
                    results = results.concat(result);
                }
            }
            return results;
        },
        selectNode: function(path, root) {
            return Ext.DomQuery.select(path, root)[0];
        },
        selectValue: function(path, root, defaultValue) {
            path = path.replace(trimRe, "$1");
            if (!valueCache[path]) {
                valueCache[path] = Ext.DomQuery.compile(path, "select");
            }
            var n = valueCache[path](root);
            n = n[0] ? n[0] : n;
            var v = (n && n.firstChild ? n.firstChild.nodeValue: null);
            return (v === null ? defaultValue: v);
        },
        selectNumber: function(path, root, defaultValue) {
            var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
            return parseFloat(v);
        },
        is: function(el, ss) {
            if (typeof el == "string") {
                el = gebi(document, el);
            }
            var isArray = (el instanceof Array);
            var result = Ext.DomQuery.filter(isArray ? el: [el], ss);
            return isArray ? (result.length == el.length) : (result.length > 0);
        },
        filter: function(els, ss, nonMatches) {
            ss = ss.replace(trimRe, "$1");
            if (!simpleCache[ss]) {
                simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
            }
            var result = simpleCache[ss](els);
            return nonMatches ? quickDiff(result, els) : result;
        },
        matchers: [{
            re: /^\.([\w-]+)/,
            select: 'n = byClassName(n, null, " {1} ");'
        },
        {
            re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
            select: 'n = byPseudo(n, "{1}", "{2}");'
        },
        {
            re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
            select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
        },
        {
            re: /^#([\w-]+)/,
            select: 'n = byId(n, null, "{1}");'
        },
        {
            re: /^@([\w-]+)/,
            select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
        }],
        operators: {
            "=": function(a, v) {
                return a == v;
            },
            "!=": function(a, v) {
                return a != v;
            },
            "^=": function(a, v) {
                return a && a.substr(0, v.length) == v;
            },
            "$=": function(a, v) {
                return a && a.substr(a.length - v.length) == v;
            },
            "*=": function(a, v) {
                return a && a.indexOf(v) !== -1;
            },
            "%=": function(a, v) {
                return (a % v) == 0;
            }
        },
        pseudos: {
            "first-child": function(c) {
                var r = [],
                n;
                for (var i = 0, ci; ci = n = c[i]; i++) {
                    while ((n = n.previousSibling) && n.nodeType != 1);
                    if (!n) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "last-child": function(c) {
                var r = [];
                for (var i = 0, ci; ci = n = c[i]; i++) {
                    while ((n = n.nextSibling) && n.nodeType != 1);
                    if (!n) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "nth-child": function(c, a) {
                var r = [];
                if (a != "odd" && a != "even") {
                    for (var i = 0, ci; ci = c[i]; i++) {
                        var m = child(ci.parentNode, a);
                        if (m == ci) {
                            r[r.length] = m;
                        }
                    }
                    return r;
                }
                var p;
                for (var i = 0, l = c.length; i < l; i++) {
                    var cp = c[i].parentNode;
                    if (cp != p) {
                        clean(cp);
                        p = cp;
                    }
                }
                for (var i = 0, ci; ci = c[i]; i++) {
                    var m = false;
                    if (a == "odd") {
                        m = ((ci.nodeIndex + 1) % 2 == 1);
                    } else if (a == "even") {
                        m = ((ci.nodeIndex + 1) % 2 == 0);
                    }
                    if (m) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "only-child": function(c) {
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    if (!prev(ci) && !next(ci)) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "empty": function(c) {
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    var cns = ci.childNodes,
                    j = 0,
                    cn, empty = true;
                    while (cn = cns[j]) {++j;
                        if (cn.nodeType == 1 || cn.nodeType == 3) {
                            empty = false;
                            break;
                        }
                    }
                    if (empty) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "contains": function(c, v) {
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    if (ci.innerHTML.indexOf(v) !== -1) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "nodeValue": function(c, v) {
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    if (ci.firstChild && ci.firstChild.nodeValue == v) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "checked": function(c) {
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    if (ci.checked == true) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "not": function(c, ss) {
                return Ext.DomQuery.filter(c, ss, true);
            },
            "odd": function(c) {
                return this["nth-child"](c, "odd");
            },
            "even": function(c) {
                return this["nth-child"](c, "even");
            },
            "nth": function(c, a) {
                return c[a - 1];
            },
            "first": function(c) {
                return c[0];
            },
            "last": function(c) {
                return c[c.length - 1];
            },
            "has": function(c, ss) {
                var s = Ext.DomQuery.select;
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    if (s(ss, ci).length > 0) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "next": function(c, ss) {
                var is = Ext.DomQuery.is;
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    var n = next(ci);
                    if (n && is(n, ss)) {
                        r[r.length] = ci;
                    }
                }
                return r;
            },
            "prev": function(c, ss) {
                var is = Ext.DomQuery.is;
                var r = [];
                for (var i = 0, ci; ci = c[i]; i++) {
                    var n = prev(ci);
                    if (n && is(n, ss)) {
                        r[r.length] = ci;
                    }
                }
                return r;
            }
        }
    };
} ();
Ext.query = Ext.DomQuery.select;
LMI.Event = function() {
    this.events = {};
};
LMI.Event.prototype = (function() {
    var L = {
        registerEvent: function(type) {
            if (typeof this.events[type] !== 'undefined') {
                throw ('Attempt to re-register event type: ' + type);
            } else {
                this.events[type] = [];
            }
        },
        triggerEvent: function(type, evt, obj) {
            if (typeof this.events[type] === 'undefined') {
                throw ('Unknown event: ' + type);
            }
            if (typeof evt !== 'object' || evt === null) {
                evt = {};
            }
            evt.eventType = type;
            for (var i = 0; i < this.events[type].length; ++i) {
                if (this.events[type][i](evt, obj) === false) {
                    return false;
                }
            }
            return true;
        },
        addListener: function(type, callback) {
            if (typeof this.events[type] === 'undefined') {
                throw ('attempt to listen to unknown event type: ' + type);
            } else {
                this.events[type].push(callback);
            }
            return new LMI.Event.Token(null, type, callback);
        },
        bind: function(type, obj, func, arg) {
            var f = function(e, o) {
                func.call(obj, e, o, arg);
            };
            return this.addListener(type, f);
        },
        removeListener: function(type, callback) {
            var t = type,
            f = callback;
            if (typeof type.type !== 'undefined' && typeof type.func !== 'undefined') {
                t = type.type;
                f = type.func;
            }
            if (this.events[t]) {
                for (var i = 0; i < this.events[t].length; ++i) {
                    if (this.events[t][i] === f) {
                        this.events[t].splice(i, 1);
                        break;
                    }
                }
            }
        },
        getListeners: function(type) {
            return this.events[type] || [];
        }
    };
    return L;
})();
LMI.Event.ExportFunctions = (function() {
    var memberName = '__LMIEvents__';
    return {
        initEvents: function() {
            if (!this[memberName]) {
                this[memberName] = new LMI.Event();
            }
            for (var i = 0; i < arguments.length; ++i) {
                this[memberName].registerEvent(arguments[i]);
            }
        },
        addEventListener: function(type, callback) {
            return this[memberName].addListener(type, callback);
        },
        removeEventListener: function(type, callback) {
            return this[memberName].removeListener(type, callback);
        },
        bindEvent: function(type, obj, func, arg) {
            return this[memberName].bind(type, obj, func, arg);
        },
        triggerEvent: function(type, evt, obj) {
            this[memberName].triggerEvent(type, evt, obj);
        },
        getListeners: function(type) {
            return this[memberName].getListeners(type);
        }
    };
})();
LMI.Event.Token = function(e, t, f) {
    this.elem = e;
    this.type = t;
    this.func = f;
};
function DSCollection() {
    this.init();
}
DSCollection.prototype.init = function() {
    this.collection = [];
};
DSCollection.prototype.getLength = function() {
    return this.collection.length;
};
DSCollection.prototype.getByIndex = function(i) {
    return this.collection[i];
};
DSCollection.prototype.push = function() {
    for (var i = 0; i < arguments.length; ++i) {
        this.collection.push(arguments[i]);
    }
};
DSCollection.prototype.remove = function(index) {
    this.collection.splice(index, 1);
};
function DSIterator(collection) {
    this.pos = 0;
    this.collection = collection;
}
DSIterator.prototype.hasNext = function() {
    return this.pos < this.collection.getLength();
};
DSIterator.prototype.next = function() {
    if (this.hasNext()) {
        return this.collection.getByIndex(this.pos++);
    }
    var undef;
    return undef;
};
function DSInteraction() {}
DSInteraction.Drag = function(el, options) {
    this.init(el, options);
};
LMI.Lang.importFunctions(DSInteraction.Drag, LMI.Event);
DSInteraction.Drag.prototype.init = function(el, options) {
    this.element = el;
    this.options = options || {};
    if (YAHOO.env.ua.ie) {
        document.body.ondrag = function() {
            return false;
        };
    }
    this.handle = this.options.handle || this.element;
    this.initEvents('startDrag', 'drag', 'endDrag');
    this.elStartLeft = this.elStartTop = null;
    this.startX = 0;
    this.startY = 0;
    if (!this.options.disable) {
        this.enable();
    }
};
DSInteraction.Drag.prototype.enable = function() {
    if (!this.enabled) {
        this.enabled = true;
        YAHOO.util.Event.on(this.handle, 'mousedown', this.startDrag, this, true);
    }
};
DSInteraction.Drag.prototype.disable = function() {
    if (this.enabled) {
        YAHOO.util.Event.removeListener(this.handle, 'mousedown', this.startDrag, this, true);
        this.enabled = false;
    }
};
DSInteraction.Drag.prototype.getEventObject = function() {
    return {
        clickStartPosition: {
            x: this.startX,
            y: this.startY
        },
        elementCurrentPosition: {
            x: this.getElementLeft(),
            y: this.getElementTop()
        },
        elementStartPosition: {
            x: this.elStartLeft,
            y: this.elStartTop
        }
    };
};
DSInteraction.Drag.prototype.getElementLeft = function() {
    return parseInt(YAHOO.util.Dom.getStyle(this.element, 'left'), 10);
};
DSInteraction.Drag.prototype.getElementTop = function() {
    return parseInt(YAHOO.util.Dom.getStyle(this.element, 'top'), 10);
};
DSInteraction.Drag.prototype.startDrag = function(e) {
    var button = e.which || e.button;
    if (button === 1) {
        this.startX = YAHOO.util.Event.getPageX(e);
        this.startY = YAHOO.util.Event.getPageY(e);
        this.originalPos = YAHOO.util.Dom.getStyle(this.element, 'position');
        if (this.originalPos != 'absolute') {
            var offsets = LMI.Element.getOffsets(this.element);
            this.element.style.position = 'absolute';
            this.element.style.top = offsets.y + 'px';
            this.element.style.left = offsets.x + 'px';
        }
        this.elStartLeft = this.getElementLeft();
        this.elStartTop = this.getElementTop();
        YAHOO.util.Event.removeListener(document, 'mousemove', this.drag, this, true);
        YAHOO.util.Event.removeListener(document, 'mouseup', this.endDrag, this, true);
        YAHOO.util.Event.on(document, 'mousemove', this.drag, this, true);
        YAHOO.util.Event.on(document, 'mouseup', this.endDrag, this, true);
        YAHOO.util.Event.on(window, 'mouseout', this.endDrag, this, true);
        this.triggerEvent('startDrag', this.getEventObject(), this);
        YAHOO.util.Event.stopEvent(e);
    }
};
DSInteraction.Drag.prototype.endDrag = function(e) {
    if (e.type != 'mouseout' || !YAHOO.util.Event.getRelatedTarget(e)) {
        YAHOO.util.Event.removeListener(document, 'mousemove', this.drag);
        YAHOO.util.Event.removeListener(document, 'mouseup', this.endDrag);
        YAHOO.util.Event.removeListener(window, 'mouseout', this.endDrag);
        var o = this.getEventObject();
        o.clickEndPosition = {
            x: YAHOO.util.Event.getPageX(e),
            y: YAHOO.util.Event.getPageY(e)
        };
        o.elementEndPosition = {
            x: this.getElementLeft(),
            y: this.getElementTop()
        };
        this.startX = 0;
        this.startY = 0;
        if (this.originalPos != 'absolute') {
            this.element.style.position = this.originalPos;
        }
        this.triggerEvent('endDrag', o, this);
    }
};
DSInteraction.Drag.prototype.drag = function(e) {
    if (!this.options.lockX) {
        var x = YAHOO.util.Event.getPageX(e);
        var newx = this.elStartLeft - (this.startX - x);
        if (this.options.maxX && newx > this.options.maxX) {
            newx = this.options.maxX;
        } else if (this.options.minX && newx < this.options.minX) {
            newx = this.options.minX;
        }
        this.element.style.left = newx + 'px';
    }
    if (!this.options.lockY) {
        var y = YAHOO.util.Event.getPageY(e);
        var newy = this.elStartTop - (this.startY - y);
        if (this.options.maxY && newy > this.options.maxY) {
            newy = this.options.maxY;
        } else if (this.options.minY && newy < this.options.minY) {
            newy = this.options.minY;
        }
        this.element.style.top = newy + 'px';
    }
    this.triggerEvent('drag', this.getEventObject(), this);
    YAHOO.util.Event.stopEvent(e);
};
LMI.Element = (function() {
    var Y = YAHOO.util,
    $D = Y.Dom,
    $E = Y.Event;
    var L = {
        create: function(type, parent, argsObj) {
            var el, evt, prop, o, val, src;
            argsObj = argsObj || {};
            type = type || argsObj.tag || argsObj.elType || 'text';
            delete argsObj.elType;
            delete argsObj.tag;
            if (type === "text") {
                el = document.createTextNode(argsObj.textValue || argsObj.text);
            } else {
                if (type === 'input' && argsObj.name) {
                    try {
                        el = document.createElement("<input type='" + argsObj.type + "' name='" + argsObj.name + "'>");
                    } catch(ex) {}
                }
                if (!el) {
                    el = document.createElement(type);
                }
                for (o in argsObj) {
                    if (argsObj.hasOwnProperty(o)) {
                        switch (o) {
                        case 'children':
                            LMI.Lang.forEach(argsObj[o],
                            function(o) {
                                L.create(null, el, o);
                            });
                            break;
                        case 'class':
                        case 'className':
                            LMI.Lang.forEach(argsObj[o].split(' '),
                            function(c) {
                                $D.addClass(el, c);
                            });
                            break;
                        case 'colspan':
                            el.colSpan = argsObj[o];
                            break;
                        case 'text':
                        case 'textValue':
                            el.appendChild(document.createTextNode(argsObj[o]));
                            break;
                        case 'src':
                            src = argsObj[o];
                            break;
                        case 'maxlength':
                            el.setAttribute('maxLength', argsObj[o]);
                            break;
                        case 'events':
                        case 'browserEvents':
                            for (evt in argsObj[o]) {
                                if (argsObj[o].hasOwnProperty(evt)) {
                                    val = argsObj[o][evt];
                                    if (YAHOO.lang.isFunction(val)) {
                                        $E.on(el, evt, val);
                                    } else if ('fn' in val) {
                                        prop = [el, evt, val.fn];
                                        if ('obj' in val) {
                                            prop.push(val.obj);
                                            if ('scope' in val) {
                                                prop.push(val.scope);
                                            }
                                        }
                                        $E.on.apply($E, prop);
                                    }
                                }
                            }
                            break;
                        case 'style':
                            if (document.all && !window.opera) {
                                el.style.cssText = argsObj[o];
                            } else {
                                el.setAttribute(o, argsObj[o]);
                            }
                            break;
                        default:
                            el.setAttribute(o, argsObj[o]);
                        }
                    }
                }
            }
            if (src) {
                L.setImageSrc(el, src);
            }
            if (parent) {
                parent.appendChild(el);
            }
            return el;
        },
        getAll: function(selector, root) {
            if (typeof Ext === 'undefined' || !"DomQuery" in Ext) {
                throw new Error("DomQuery must be loaded before getAll is called");
            }
            return Ext.DomQuery.select(selector, root);
        },
        getOne: function(el, root) {
            if (typeof Ext === 'undefined' || !"DomQuery" in Ext) {
                throw new Error("DomQuery must be loaded before getOne is called");
            }
            if (typeof el === 'string') {
                return Ext.DomQuery.selectNode(el, root);
            } else {
                return el;
            }
        },
        findAncestor: function(node, elType, className) {
            var n = elType.toUpperCase(),
            checkClass = !!className;
            while ((node = node.parentNode) && (node.nodeName !== n || (checkClass && !$D.hasClass(node, className)))) {}
            return node;
        },
        getImageSrc: function(img) {
            var loader, filter, ie = YAHOO.env.ua.ie;
            if (ie && ie < 7) {
                loader = "DXImageTransform.Microsoft.AlphaImageLoader";
                filter = img.filters[loader];
                if (filter) {
                    return filter.src;
                } else if (img) {
                    return img.src;
                }
            } else if (img) {
                return img.src;
            }
            return '';
        },
        setAlphaImageLoader: function(img, src, sizing) {
            var s = sizing ? ', sizingMethod="' + sizing + '"': '';
            img.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '"' + s + ')';
            img.src = 'images/pixel_trans.gif';
        },
        setImageSrc: function(img, src, sizing) {
            var ie = YAHOO.env.ua.ie;
            if (ie && ie < 7) {
                if (src.match(/\.png(;|$|\?)/) && !$D.hasClass(img, 'notTransparent')) {
                    L.setAlphaImageLoader(img, src, sizing);
                } else if (img.src != src) {
                    img.src = src;
                }
            } else if (img) {
                img.src = src;
            }
        },
        getOffsets: function(el) {
            var xy = {
                x: 0,
                y: 0,
                w: el.offsetWidth,
                h: el.offsetHeight
            };
            while (el) {
                xy.x += el.offsetLeft;
                xy.y += el.offsetTop;
                el = el.offsetParent;
            }
            return xy;
        },
        createImage: function(src, parent, left, top, zIndex, width, height, alt, title) {
            var style = 'position: absolute;';
            if (typeof left !== 'undefined') {
                style += 'left:    ' + left + 'px;';
            }
            if (typeof top !== 'undefined') {
                style += 'top:     ' + top + 'px;';
            }
            if (typeof zIndex !== 'undefined') {
                style += 'z-index: ' + zIndex + ';';
            }
            var i = L.create('img', parent, {
                galleryImg: 'no',
                style: style,
                title: (title ? title: ''),
                alt: (alt ? alt: '')
            });
            L.setImageSrc(i, src);
            if (width !== undefined) {
                i.width = width;
            }
            if (height !== undefined) {
                i.height = height;
            }
            return i;
        },
        destroy: function(el) {
            $E.purgeElement(el, true);
            if (el.parentNode) {
                el.parentNode.removeChild(el);
            }
        },
        truncate: function(el) {
            while (el && el.firstChild) {
                L.destroy(el.firstChild);
            }
        },
        changeLinkText: function(el, text) {
            if (el && el.firstChild && el.firstChild.nodeValue) {
                el.firstChild.nodeValue = text;
            }
        },
        blink: function(el, delay) {
            if (el) {
                if (typeof(el) !== 'object') {
                    el = L.getAll(el);
                }
                if (typeof(el) === 'object' && el !== null) {
                    if (!el instanceof Array) {
                        el = [el];
                    }
                    LMI.Lang.forEach(el,
                    function(o) {
                        var oDisplay = YAHOO.util.Dom.getStyle(o, 'display');
                        if (oDisplay) {
                            o.style.display = 'none';
                            if (typeof(delay) !== 'undefined') {
                                window.setTimeout(function() {
                                    o.style.display = oDisplay;
                                },
                                delay);
                            } else {
                                o.style.display = oDisplay;
                            }
                        }
                    });
                }
            }
        }
    };
    return L;
})();
function DSRange(low, high) {
    this.low = low;
    this.high = high;
}
DSRange.prototype.contains = function(n) {
    return n >= this.low && n <= this.high;
};
DSRange.prototype.limitNumber = function(number) {
    number = Math.max(parseFloat(number), this.low);
    return Math.min(number, this.high);
};
function DSCircle(low, high) {
    this.low = low;
    this.high = high;
}
DSCircle.prototype.limitNumber = function(number) {
    number = parseFloat(number);
    while (number > this.high) {
        number -= this.high - this.low;
    }
    while (number < this.low) {
        number += this.high - this.low;
    }
    return number;
};
function DSCircleSegment(circle, low, high) {
    this.circle = circle;
    this.low = low;
    this.high = high;
}
DSCircleSegment.prototype.contains = function(point) {
    var p = this.circle.limitNumber(point);
    if (this.low > this.high) {
        return (p >= this.low && p <= this.circle.high) || (p >= this.circle.low && p <= this.high);
    } else {
        return p >= this.low && p <= this.high;
    }
};
var DSLatitude = new DSRange( - 90, 90);
var DSLongitude = new DSCircle( - 180, 180);
function DSBoundingBox(lower, upper) {
    this.lower = lower;
    this.upper = upper;
    this.width = new DSCircleSegment(DSLongitude, lower.lng, upper.lng);
    this.height = new DSRange(lower.lat, upper.lat);
}
DSBoundingBox.prototype.contains = function(point) {
    return this.width.contains(point.lng) && this.height.contains(point.lat);
};
function DSCopyright(text, boxes, minzoom, maxzoom, tileset) {
    this.text = text;
    this.boxes = (typeof boxes.length == 'undefined' ? [boxes] : boxes);
    this.minzoom = minzoom;
    this.maxzoom = maxzoom;
    this.tileset = tileset;
}
DSCopyright.prototype.contains = function(point, zoom, tileset) {
    var t = (!tileset || !this.tileset || (tileset == this.tileset));
    var z = (!this.minzoom || zoom >= this.minzoom) && (!this.maxzoom || zoom <= this.maxzoom);
    var p = false;
    for (var i = 0; i < this.boxes.length; ++i) {
        if (this.boxes[i].contains(point)) {
            p = true;
            break;
        }
    }
    return p && z && t;
};
function DSCopyrightSet() {
    this.copyrights = [];
}
DSCopyrightSet.prototype.getCopyright = function(point, zoom, tileset) {
    var t = [];
    if (point && zoom) {
        for (var i = 0; i < this.copyrights.length; ++i) {
            if (this.copyrights[i].contains(point, zoom, tileset)) {
                t.push(this.copyrights[i].text);
            }
        }
    }
    return t.join(' - ');
};
DSCopyrightSet.prototype.addCopyright = function(c) {
    this.copyrights.push(c);
};
function DSMapDecoratorCollection() {
    this.init();
}
LMI.Lang.extend(DSMapDecoratorCollection, DSCollection);
DSMapDecoratorCollection.prototype.getByType = function(type) {
    var it = new DSIterator(this),
    ret = [],
    d;
    while ((d = it.next())) {
        if (d.type == type) {
            ret.push(d);
        }
    }
    return ret;
};
DSMapDecoratorCollection.prototype.getByName = function(name) {
    var it = new DSIterator(this),
    d;
    while ((d = it.next())) {
        if (d.name == name) {
            return d;
        }
    }
    return ret;
};
function DSMapDecorator(map, el, pos, type, name) {
    this.init(map, el, pos, type, name);
}
DSMapDecorator.prototype.init = function(map, el, pos, type, name) {
    this.map = map;
    this.element = el;
    this.position = pos;
    this.type = type;
    this.name = name;
    this.updatePosition();
};
DSMapDecorator.prototype.getElement = function() {
    return this.element;
};
DSMapDecorator.prototype.getFirstElement = function() {
    for (i = 0, iLen = this.element.childNodes.length; i < iLen; ++i) {
        var o = this.element.childNodes[i];
        if (!YAHOO.util.Dom.hasClass(o, 'skip')) {
            return o;
        }
    }
};
DSMapDecorator.prototype.updatePosition = function() {
    this.element.style.position = 'absolute';
    if (typeof this.position.left != 'undefined') {
        this.element.style.left = parseInt(this.position.left, 10) + 'px';
    }
    if (typeof this.position.right != 'undefined') {
        this.element.style.right = parseInt(this.position.right, 10) + 'px';
    }
    if (typeof this.position.top != 'undefined') {
        this.element.style.top = parseInt(this.position.top, 10) + 'px';
    }
    if (typeof this.position.bottom != 'undefined') {
        this.element.style.bottom = parseInt(this.position.bottom, 10) + 'px';
    }
    for (var i in {
        width: '',
        height: ''
    }) {
        if (typeof this.position[i] != 'undefined') {
            this.element.style[i] = parseInt(this.position[i], 10) + 'px';
        }
    }
    if (typeof this.position.zIndex != 'undefined') {
        this.element.style.zIndex = parseInt(this.position.zIndex, 10);
    }
};
DSMapDecorator.prototype.setPosition = function(pos) {
    for (var i in pos) {
        if (pos.hasOwnProperty(i)) {
            this.position[i] = pos[i];
        }
    }
    this.updatePosition();
};
DSMapDecorator.prototype.getPosition = function() {
    return this.position;
};
(function() {
    function InvalidLatException(msg) {
        this.name = 'InvalidLatException';
        this.message = msg;
    }
    LMI.Lang.extend(InvalidLatException, TypeError);
    function InvalidLngException(msg) {
        this.name = 'InvalidLngException';
        this.message = msg;
    }
    LMI.Lang.extend(InvalidLngException, TypeError);
    function degrees(rad) {
        return rad * (180.0 / Math.PI);
    }
    function radians(deg) {
        return deg * (Math.PI / 180.0);
    }
    var M = LMI.Lang.getObject('LMI.Mapping', true);
    M.Point = function(lat, lng) {
        this.init(lat, lng);
    };
    M.Point.prototype = {
        init: function(lat, lng) {
            this.setLat(lat);
            this.setLng(lng);
        },
        latAsRad: function() {
            return radians(this.lat);
        },
        lngAsRad: function() {
            return radians(this.lng);
        },
        equals: function(p) {
            return p && this.lat === p.lat && this.lng === p.lng;
        },
        limitLat: function(lat) {
            return DSLatitude.limitNumber(lat);
        },
        limitLng: function(lng) {
            return DSLongitude.limitNumber(lng);
        },
        toString: function() {
            return 'LMI.Mapping.Point(' + this.lat + ',' + this.lng + ')';
        },
        setLat: function(lat) {
            var latn = parseFloat(lat);
            if (latn != lat || isNaN(latn)) {
                throw new InvalidLatException('Invalid latitude: ' + lat);
            }
            this.lat = Math.round(this.limitLat(latn) * 100000) / 100000;
        },
        setLng: function(lng) {
            var lngn = parseFloat(lng);
            if (lngn != lng || isNaN(lngn)) {
                throw new InvalidLngException('Invalid longitude: ' + lng);
            }
            this.lng = Math.round(this.limitLng(lngn) * 100000) / 100000;
        },
        setLatFromRad: function(latRad) {
            this.setLat(degrees(latRad));
        },
        setLngFromRad: function(lngRad) {
            this.setLng(degrees(lngRad));
        }
    };
    M.Point.fromRadians = function(lat, lng) {
        return new M.Point(degrees(lat), degrees(lng));
    };
    M.Point.getPointsFromString = function(encodedPoints) {
        var b, shift, result, delta, index = 0,
        len = encodedPoints.length,
        lat = 0,
        lng = 0,
        points = [];
        try {
            while (index < len) {
                shift = result = 0;
                do {
                    b = encodedPoints.charCodeAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                delta = ((result & 1) ? ~ (result >> 1) : (result >> 1));
                lat += delta;
                shift = result = 0;
                do {
                    b = encodedPoints.charCodeAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                delta = ((result & 1) ? ~ (result >> 1) : (result >> 1));
                lng += delta;
                points.push(new LMI.Mapping.Point(lat * 1e-5, lng * 1e-5));
            }
        } catch(ex) {}
        return points;
    };
})();
function DSMapObject_Iterator(coll, offset) {
    this.coll = coll;
    this.pos = (offset ? offset: 0);
}
function DSMapObject_HasNext() {
    if (this.coll && (this.pos + 1) <= this.coll.order.length) {
        return true;
    }
    this.pos = 0;
    return false;
}
function DSMapObject_Next() {
    return (this.coll.objects[this.coll.order[this.pos++]]);
}
function DSMapObject_GetId() {
    return this.coll.order[this.pos - 1];
}
function DSMapObject_SetIteratorOffset(offset) {
    this.pos = offset;
}
function DSMapObject_GetIteratorOffset() {
    return this.pos;
}
function DSMapObject_Add(obj) {
    this.objects[this.currIdx] = obj;
    this.order.push(this.currIdx);
    return this.currIdx++;
}
function DSMapObject_Remove(key) {
    var i, len;
    if (this.objects[key]) {
        delete this.objects[key];
        for (i = 0, len = this.order.length; i < len; ++i) {
            if (this.order[i] == key) {
                this.order.splice(i, 1);
            }
        }
        return true;
    }
    return false;
}
function DSMapObject_RemoveAll() {
    this.objects = {};
    this.order = [];
    this.currPos = this.currIdx = 0;
}
function DSMapObject_GetByIndex(i) {
    return this.objects[this.order[i]];
}
function DSMapObject_GetById(id) {
    return this.objects[id] ? this.objects[id] : null;
}
function DSMapObject_Size() {
    return this.order.length;
}
function DSMapObject_GetByProperty(name, val) {
    for (var i = 0; i < this.order.length; ++i) {
        if (this.objects[this.order[i]].getProperty(name) == val) {
            return this.objects[this.order[i]];
        }
    }
    return null;
}
function DSMapObject_GetIdsByProperty(name, val) {
    var ids = [];
    for (var i = 0; i < this.order.length; ++i) {
        if (this.objects[this.order[i]].getProperty(name) == val) {
            ids.push(this.order[i]);
        }
    }
    return ids;
}
function DSMapObject_Collection() {
    this.objects = {};
    this.order = [];
    this.currPos = this.currIdx = 0;
}
DSMapObject_Collection.prototype.add = DSMapObject_Add;
DSMapObject_Collection.prototype.remove = DSMapObject_Remove;
DSMapObject_Collection.prototype.getById = DSMapObject_GetById;
DSMapObject_Collection.prototype.getByIndex = DSMapObject_GetByIndex;
DSMapObject_Collection.prototype.size = DSMapObject_Size;
DSMapObject_Collection.prototype.getByProperty = DSMapObject_GetByProperty;
DSMapObject_Collection.prototype.getIdsByProperty = DSMapObject_GetIdsByProperty;
DSMapObject_Collection.prototype.removeAll = DSMapObject_RemoveAll;
DSMapObject_Iterator.prototype.next = DSMapObject_Next;
DSMapObject_Iterator.prototype.getId = DSMapObject_GetId;
DSMapObject_Iterator.prototype.hasNext = DSMapObject_HasNext;
DSMapObject_Iterator.prototype.setOffset = DSMapObject_SetIteratorOffset;
DSMapObject_Iterator.prototype.getOffset = DSMapObject_GetIteratorOffset;
LMI.Mapping.MapObject = (function() {
    function MapObject(point, element) {
        this.init(point, element);
    }
    MapObject.prototype = {
        init: function(point, element) {
            this.element = element;
            this.properties = {};
            this.setPoint(point);
            this.setXOffset(0);
            this.setYOffset(0);
            this.setZOffset(0);
            this.setIncludedInBestFit(true);
            this.initEvents('click', 'mouseout', 'mouseover', 'add', 'remove');
        },
        setPoint: function(point) {
            this.point = point;
        },
        getPoint: function() {
            return this.point;
        },
        getBoundingBox: function() {
            if ('boundingBox' in this) {
                return this.boundingBox;
            }
            return null;
        },
        getWidth: function() {
            return this.element.offsetWidth;
        },
        getHeight: function() {
            return this.element.offsetHeight;
        },
        setXOffset: function(xOffset) {
            this.xOffset = xOffset;
        },
        getXOffset: function() {
            return this.xOffset;
        },
        setYOffset: function(yOffset) {
            this.yOffset = yOffset;
        },
        getYOffset: function() {
            return this.yOffset;
        },
        setZOffset: function(zOffset) {
            this.zOffset = zOffset;
        },
        getZOffset: function() {
            return this.zOffset;
        },
        setProperty: function(name, val) {
            this.properties[name] = val;
        },
        setProperties: function() {
            var i, o;
            if (typeof arguments[0] === 'object') {
                o = arguments[0];
                for (i in o) {
                    if (o.hasOwnProperty(i)) {
                        this.setProperty(i, o[i]);
                    }
                }
            } else {
                o = arguments.length;
                for (i = 0; i < o; ++i) {
                    this.properties[arguments[i]] = arguments[++i];
                }
            }
            return this;
        },
        getProperty: function(name) {
            return (name && name in this.properties ? this.properties[name] : "");
        },
        setIncludedInBestFit: function(included) {
            this.includedInBestFit = !!included;
        },
        isIncludedInBestFit: function() {
            return this.includedInBestFit;
        },
        setZIndex: function(zIndex) {
            this.element.style.zIndex = zIndex;
        },
        add: function(map) {
            this.shownOnMap = true;
            this.map = map;
            this.triggerEvent('add', {
                map: map
            },
            this);
        },
        update: function(map) {},
        remove: function(map) {
            this.triggerEvent('remove', {
                map: map
            },
            this);
            this.shownOnMap = false;
            this.map = null;
        }
    };
    LMI.Lang.importFunctions(MapObject, LMI.Event);
    MapObject.prototype._addEventListener = MapObject.prototype.addEventListener;
    MapObject.prototype.addEventListener = function(type, func) {
        var that;
        switch (type) {
        case 'click':
            YAHOO.util.Dom.setStyle(this.element, 'cursor', 'pointer');
        case 'mouseout':
        case 'mouseover':
            if (this.getListeners(type).length === 0) {
                that = this;
                YAHOO.util.Event.on(this.element, type,
                function(e) {
                    that.triggerEvent(type, e, that);
                });
            }
            break;
        }
        return this._addEventListener(type, func);
    };
    MapObject.prototype.bindEvent = function(type, obj, func, arg) {
        var f = function(e, o) {
            func.call(obj, e, o, arg);
        };
        return this.addEventListener(type, f);
    };
    return MapObject;
})();
LMI.Mapping.Icon = (function() {
    function Icon(point, option) {
        this.init(point, option);
    }
    LMI.Lang.extend(Icon, LMI.Mapping.MapObject);
    var proto = Icon.prototype,
    superclass = Icon.superclass;
    proto.init = function(point, option) {
        this.option = option;
        var img = LMI.Element.create('img');
        YAHOO.util.Event.on(img, 'error', imgError, this, true);
        superclass.init.call(this, point, img);
        this.setIconSrc(this.getRecommendedIconSrc());
        this.setXOffset(24);
        this.setYOffset(27);
    };
    proto.getIconSrc = function() {
        return LMI.Element.getImageSrc(this.element);
    };
    proto.setIconSrc = function(src) {
        LMI.Element.setImageSrc(this.element, src);
    };
    proto.getRecommendedIconSrc = function() {
        var i = parseInt(this.option, 10),
        lets = 'abcdefghijklmnopqrstuvwxyz',
        l = (i >= 0 && i < lets.length ? lets.charAt(i) : 'blank');
        return 'images/nodes/red/map_icon_' + l + '.png';
    };
    proto.getHeight = function() {
        return 27;
    };
    proto.getWidth = function() {
        return 24;
    };
    proto.getDefaultIcon = function() {
        var src = this.getIconSrc();
        return src.replace(/((?:https?:\/\/)?(?:[^\/]+\/)*)[^\/]+/, '$1map_icon_blank.png');
    };
    function imgError(e) {
        var i = this.element,
        defaultIcon = this.getDefaultIcon();
        if (LMI.Element.getImageSrc(i).match(defaultIcon)) {
            i.alt = 'X';
        } else {
            LMI.Element.setImageSrc(i, defaultIcon);
        }
    }
    return Icon;
})();
LMI.Mapping.EquiRectangularMapProjection = (function() {
    var EQUITORIAL_EARTH_RADIUS_MEAN_METERS = 6.378245e6,
    HALF_PI = Math.PI / 2.0;
    function adjust_lon(lon) {
        if (lon < -Math.PI) {
            return lon - (Math.floor(lon / Math.PI) * Math.PI);
        } else if (lon > Math.PI) {
            return - (Math.PI - lon + (Math.floor(lon / Math.PI) * Math.PI));
        }
        return lon;
    }
    function EquiRectangularMapProjection(lon, lat) {
        this._center_lon = lon;
        this._center_lat = lat;
        this._cos_center_lat = Math.cos(lat);
        this._R = EQUITORIAL_EARTH_RADIUS_MEAN_METERS;
    }
    EquiRectangularMapProjection.prototype = {
        setRadius: function(r) {
            this._R = r;
        },
        getEarthRadius: function() {
            return EQUITORIAL_EARTH_RADIUS_MEAN_METERS;
        },
        setOrigin: function(lon, lat) {
            this.translations = null;
            var xy = this.forward(lon, lat);
            this.translations = {
                x: -xy.x,
                y: -xy.y
            }
        },
        forward: function(lon, lat) {
            var xy = {
                x: this._R * adjust_lon(lon - this._center_lon) * this._cos_center_lat,
                y: this._R * lat
            };
            if (this.translations) {
                xy.x += this.translations.x;
                xy.y += this.translations.y;
            }
            return xy;
        },
        inverse: function(x, y) {
            if (this.translations) {
                x -= this.translations.x;
                y -= this.translations.y;
            }
            return {
                x: adjust_lon(this._center_lon + x / (this._R * this._cos_center_lat)),
                y: Math.min(y / this._R, HALF_PI)
            };
        }
    };
    EquiRectangularMapProjection.getGridCS = function(zoom, options) {
        options = options || {};
        if (! ('standardParallel' in options)) {
            options.standardParallel = 40;
        }
        if (! ('scales' in options)) {
            options.scales = [1.7021276, 3.4042553, 6.80851064, 13.61702128, 27.23404256, 54.46808512, 108.93617024, 217.87234048, 435.74468096, 871.48936192, 1742.97872384, 3485.95744768, 6971.9148953, 13943.82979072];
        }
        var center = new LMI.Mapping.Point(options.standardParallel, 0),
        origin = new LMI.Mapping.Point(90, -180),
        projection = new EquiRectangularMapProjection(center.lngAsRad(), center.latAsRad()),
        gcs = new LMI.Mapping.GridCS(projection, zoom),
        scale = options.scales[zoom - 1];
        gcs.setGridWidth(((2 * Math.PI * EQUITORIAL_EARTH_RADIUS_MEAN_METERS) / scale) / gcs.tileSize);
        projection.setRadius(gcs.radius);
        projection.setOrigin(origin.lngAsRad(), origin.latAsRad());
        return gcs;
    };
    return EquiRectangularMapProjection;
})();
LMI.Mapping.GridCS = (function() {
    function rint(n) {
        var f = Math.floor(n);
        if (Math.abs(n - f) !== 0.5) {
            return Math.round(n);
        }
        return (f % 2 === 0 ? f: f + 1);
    }
    function GridCS(projection, zoom, size) {
        this.projection = projection;
        this.tileSize = size || 256;
        this.setGridWidth(rint(Math.pow(2, zoom)));
    }
    GridCS.prototype = {
        setGridWidth: function(w) {
            this.gridWidth = w;
            this.radius = (w * this.tileSize) / (2 * Math.PI);
        },
        getScale: function() {
            return this.projection.getEarthRadius() / this.radius;
        },
        gridX: function(x) {
            return Math.floor(x / this.tileSize);
        },
        gridY: function(y) {
            return Math.floor(y / this.tileSize);
        },
        grid: function(x, y) {
            if (arguments.length === 1) {
                y = x.y;
                x = x.x;
            }
            return {
                x: this.gridX(x),
                y: this.gridY(y)
            };
        },
        offsetX: function(x) {
            return x % this.tileSize;
        },
        offsetY: function(y) {
            return y % this.tileSize;
        },
        restrictGridX: function(x) {
            if (x < 0 || x >= this.gridWidth) {
                x -= (this.gridWidth * Math.floor(x / this.gridWidth));
            }
            return x;
        },
        offset: function(x, y) {
            if (arguments.length == 1) {
                y = x.y;
                x = x.x;
            }
            return {
                x: this.offsetX(x),
                y: this.offsetY(y)
            };
        },
        gridToX: function(grid) {
            var offset = (arguments.length == 2 ? arguments[1] : 0);
            return (grid * this.tileSize) + offset;
        },
        gridToY: function(grid) {
            var offset = (arguments.length == 2 ? arguments[1] : 0);
            return (grid * this.tileSize) + offset;
        },
        toXY: function(p) {
            var xy = this.projection.forward(p.lngAsRad(), p.latAsRad());
            xy.y = -xy.y;
            return xy;
        },
        toLL: function(x, y) {
            var xy = this.projection.inverse(x, -y);
            return LMI.Mapping.Point.fromRadians(xy.y, xy.x);
        },
        getUpperLeftPoint: function(center, width, height) {
            var xy = this.toXY(center);
            return {
                x: xy.x - (width / 2.0),
                y: xy.y - (height / 2.0)
            };
        },
        getLowerRightPoint: function(center, width, height) {
            var xy = this.toXY(center);
            return {
                x: xy.x + (width / 2.0),
                y: xy.y + (height / 2.0)
            };
        },
        getLowerLeftPoint: function(center, width, height) {
            var xy = this.toXY(center);
            return {
                x: xy.x - (width / 2.0),
                y: xy.y + (height / 2.0)
            };
        },
        getUpperRightPoint: function(center, width, height) {
            var xy = this.toXY(center);
            return {
                x: xy.x + (width / 2.0),
                y: xy.y - (height / 2.0)
            };
        },
        processBoundingBox: function(callback, ul, lr) {
            var tile_min = this.grid(this.toXY(ul)),
            tile_max = this.grid(this.toXY(lr));
            this.processArea2(callback, tile_min.x, tile_min.y, tile_max.x, tile_max.y);
        },
        processArea: function(callback, center, width, height) {
            var tile_min = this.grid(this.getUpperLeftPoint(center, width, height)),
            tile_max = this.grid(this.getLowerRightPoint(center, width, height));
            this.processArea2(callback, tile_min.x, tile_min.y, tile_max.x, tile_max.y);
        },
        processArea2: function(callback, min_x, min_y, max_x, max_y) {
            var x, x_grid, y_grid, x_start = min_x,
            y_start = Math.max(0, min_y);
            while (min_x > max_x) {
                min_x -= this.gridWidth;
            }
            while (x_start < 0) {
                x_start += this.gridWidth;
            }
            for (y_grid = y_start; y_grid <= max_y; ++y_grid) {
                for (x_grid = x_start; x_grid <= max_x; ++x_grid) {
                    x = this.restrictGridX(x_grid);
                    callback.processArea(x, y_grid, x_grid - x_start, y_grid - y_start, max_x - x_start, max_y, y_start);
                }
            }
        }
    };
    return GridCS;
})();
LMI.Mapping.MercatorMapProjection = (function() {
    var EQUITORIAL_EARTH_RADIUS_WGS84_METERS = 6.378137e6,
    INVERSE_FLATTEN_WGS84 = 298.257223563,
    HALF_PI = Math.PI / 2.0,
    EPSLN = 1.0e-10;
    function adjust_lon(lon) {
        if (lon < -Math.PI) {
            return lon - (Math.floor(lon / Math.PI) * Math.PI);
        } else if (lon > Math.PI) {
            return - (Math.PI - lon + (Math.floor(lon / Math.PI) * Math.PI));
        }
        return lon;
    }
    function tsfnz(e, phi, sinphi) {
        var e_sinphi, t = (1 + sinphi) / (1 - sinphi);
        if (e !== 0) {
            e_sinphi = e * sinphi;
            t *= Math.pow((1 - e_sinphi) / (1 + e_sinphi), e);
        }
        return t;
    }
    function phi2z(e, ts) {
        var phi = HALF_PI - 2.0 * Math.atan(ts);
        if (e === 0) {
            return phi;
        }
        var i, sinphi, e_sinphi, dphi;
        for (i = 0; i <= 15; ++i) {
            sinphi = Math.sin(phi);
            e_sinphi = e * sinphi;
            dphi = HALF_PI - 2 * Math.atan(ts * Math.pow((1 - e_sinphi) / (1 + e_sinphi), 0.5 * e)) - phi;
            phi += dphi;
            if (Math.abs(dphi) <= EPSLN) {
                return phi;
            }
        }
    }
    function MercatorMapProjection(lon, lat) {
        this.center_lon = lon;
        this.center_lat = lat;
        this.setRadius(EQUITORIAL_EARTH_RADIUS_WGS84_METERS);
    }
    MercatorMapProjection.prototype = {
        setRadius: function(R, r) {
            var temp;
            this.R = R;
            if (arguments.length === 1) {
                this.r = R;
                this.es = 0;
                this.e = 0;
                this.m1 = Math.cos(this.center_lat);
            } else {
                temp = r / R;
                var sinPhi = Math.sin(this.center_lat);
                this.r = r;
                this.es = 1.0 - (temp * temp);
                this.e = Math.sqrt(this.es);
                this.m1 = Math.cos(this.center_lat) / Math.sqrt(1 - this.es * sinPhi * sinPhi);
            }
        },
        getEarthRadius: function() {
            return EQUITORIAL_EARTH_RADIUS_WGS84_METERS;
        },
        forward: function(lon, lat) {
            if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
                throw "transformation cannot be computed at the poles";
            }
            return {
                x: this.falseEasting + this.R * this.m1 * adjust_lon(lon - this.center_lon),
                y: this.falseNorthing + this.R * this.m1 * 0.5 * Math.log(tsfnz(this.e, lat, Math.sin(lat)))
            };
        },
        inverse: function(x, y) {
            x -= this.falseEasting;
            y -= this.falseNorthing;
            return {
                x: adjust_lon(this.center_lon + x / (this.R * this.m1)),
                y: phi2z(this.e, Math.exp( - y / (this.R * this.m1)))
            };
        }
    };
    MercatorMapProjection.getGridCS = function(zoom, options) {
        var projection = new MercatorMapProjection(0, 0),
        gcs = new LMI.Mapping.GridCS(projection, zoom),
        radius = gcs.radius;
        if ('isEllipsoidal' in options && options.isEllipsoidal) {
            projection.setRadius(radius, radius - (radius / INVERSE_FLATTEN_WGS84));
        } else {
            projection.setRadius(radius);
        }
        projection.falseEasting = radius * Math.PI;
        projection.falseNorthing = -radius * Math.PI;
        return gcs;
    };
    return MercatorMapProjection;
})();
LMI.Mapping.TileUrl = (function() {
    function TileUrl(options) {
        this.init(options);
    }
    TileUrl.defaults = {
        baseUrl: 'http://mapping-dev.corp.localmatters.com/tiles/mercator-ellipsoid/',
        extension: '.png',
        suffix: '',
        locale: ''
    };
    TileUrl.prototype = {
        init: function(options) {
            this.initOptions(options);
            this.base = this.options.baseUrl;
            this.suffix = this.options.suffix;
            this.post = this.options.extension + '?';
            this.setLocale(this.options.locale);
        },
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            TileUrl.defaults);
            if ('config' in TileUrl) {
                LMI.Lang.mergeObjects(this.options, TileUrl.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        setMapWidth: function(w) {
            this.mapWidth = w;
        },
        setMapHeight: function(h) {
            this.mapHeight = h;
        },
        setLocale: function(l) {
            this.locale = l;
        },
        getPre: function() {
            return this.base + (this.locale.length ? this.locale + '/': '');
        },
        getPost: function() {
            return this.post + 'w=' + this.mapWidth + '&h=' + this.mapHeight + this.suffix;
        },
        getUrl: function(x, y, z) {
            return this.getPre() + z + '/' + x + '/' + y + this.getPost();
        }
    };
    return TileUrl;
})();
LMI.Mapping.TileManager = (function() {
    function TileManager(el, options) {
        this.init(el, options);
    }
    TileManager.defaults = {
        minLevel: 1,
        maxLevel: 14,
        tileLevels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
        totalLevels: 14,
        invertLevels: true,
        projection: LMI.Mapping.MercatorMapProjection,
        projectionOptions: {
            isEllipsoidal: true
        },
        tileUrlStrategy: LMI.Mapping.TileUrl,
        tileUrlOptions: {},
        tileWidth: 256,
        tileHeight: 256
    };
    TileManager.prototype = {
        init: function(el, options) {
            this.tiles = [];
            this.parentEl = el;
            this.grids = [];
            this.initOptions(options);
            this.tileWidth = this.options.tileWidth;
            this.tileHeight = this.options.tileHeight;
            this.scale = 1;
            this.minLevel = this.options.minLevel;
            this.maxLevel = this.options.maxLevel;
            this.tileLevels = this.options.tileLevels;
            this.zoomLevels = this.options.totalLevels;
            this.bufferWidth = this.tileWidth / 2;
            this.bufferHeight = this.tileHeight / 2;
            this.projection = this.options.projection;
            this.projectionOptions = this.options.projectionOptions;
            this.tileUrls = new this.options.tileUrlStrategy(this.options.tileUrlOptions);
            if ('width' in this.options) {
                this.setMapWidth(this.options.width);
            }
            if ('height' in this.options) {
                this.setMapHeight(this.options.height);
            }
            if ('locale' in this.options) {
                this.setLocale(this.options.locale);
            }
            this.createTiles();
        },
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            TileManager.defaults);
            if ('config' in TileManager) {
                LMI.Lang.mergeObjects(this.options, TileManager.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        setMapWidth: function(w) {
            this.mapWidth = w;
            this.tileUrls.setMapWidth(this.mapWidth);
        },
        setMapHeight: function(h) {
            this.mapHeight = h;
            this.tileUrls.setMapHeight(this.mapHeight);
        },
        setLocale: function(locale) {
            this.locale = locale;
            this.tileUrls.setLocale(locale);
        },
        setZoomLevel: function(z) {
            this.setScale(1);
            this.zoomLevel = z;
        },
        getZoomLevel: function(z) {
            z = z || this.zoomLevel || 1;
            z = this.options.invertLevels ? this.options.totalLevels - z + 1 : z;
            return Math.max(1, Math.min(z, this.options.totalLevels));
        },
        getScaledZoomLevel: function(z) {
            z = z || this.zoomLevel || 1;
            return this.options.invertLevels ? this.tileLevels[this.options.totalLevels - z] : this.tileLevels[z - 1];
        },
        getZoomLevelIndex: function(z) {
            var i;
            z = z || this.zoomLevel || 0;
            for (i = 0; i < this.maxLevel; i++) {
                if (z <= this.tileLevels[i]) {
                    if (this.options.invertLevels) {
                        return this.options.totalLevels - i;
                    } else {
                        return i;
                    }
                }
            }
            if (this.options.invertLevels) {
                return this.minLevel;
            } else {
                return this.maxLevel;
            }
        },
        setCenterPoint: function(p) {
            this.center = p;
        },
        getCenterPoint: function() {
            return this.center;
        },
        remove: function() {
            this.tileLayer.parentNode.removeChild(this.tileLayer);
        },
        add: function(map) {
            map.tileLayer.appendChild(this.tileLayer);
        },
        createTiles: function() {
            var i, j, tw = this.tileWidth,
            th = this.tileHeight;
            this.rows = Math.ceil(this.mapHeight / th) + 2;
            this.columns = Math.ceil(this.mapWidth / tw) + 2;
            this.tileLayer = LMI.Element.create('div', null, {
                className: 'tileLayer'
            });
            this.width = this.columns * tw;
            this.height = this.rows * th;
            for (i = 0; i < this.rows; ++i) {
                for (j = 0; j < this.columns; ++j) {
                    this.tiles.push(new LMI.Mapping.Tile(this.tileLayer, {
                        width: tw,
                        height: th
                    }));
                }
            }
        },
        setCenterOffset: function(x, y) {
            this.centerOffset = {
                x: x,
                y: y
            };
        },
        getCenterOffset: function() {
            return {
                x: this.centerOffset.x * this.scale,
                y: this.centerOffset.y * this.scale
            };
        },
        getPosition: function(p) {
            var grid, xy;
            if (this.offsets) {
                grid = this.getGrid();
                xy = grid.toXY(p);
                return {
                    x: xy.x - grid.gridToX(this.getGridLeft(), -this.offsets.x),
                    y: xy.y - grid.gridToY(this.getGridTop(), -this.offsets.y)
                };
            }
            return null;
        },
        getPointByPosition: function(x, y) {
            var grid = this.getGrid();
            return grid.toLL(grid.gridToX(this.getGridLeft(), x - this.offsets.x), grid.gridToY(this.getGridTop(), y - this.offsets.y));
        },
        wrapNorth: function() {
            var i, t, zoom = this.getZoomLevel();
            this.offsets.y -= this.tileHeight;
            this.setGridTop(this.getGridTop() - 1);
            for (i = 0; i < this.columns; ++i) {
                t = this.tiles.pop();
                this.tiles.unshift(t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + ((this.columns - 1) - i)), this.getGridTop(), this.tileLevels[zoom - 1]));
            }
            for (i = 0; i < this.columns; ++i) {
                this.positionTile(i);
            }
        },
        wrapSouth: function() {
            var i, len, t, zoom = this.getZoomLevel();
            this.offsets.y += this.tileHeight;
            for (i = 0; i < this.columns; ++i) {
                t = this.tiles.shift();
                this.tiles.push(t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + i), this.getGridTop() + this.rows, this.tileLevels[zoom - 1]));
            }
            for (i = this.columns * (this.rows - 1), len = this.tiles.length; i < len; ++i) {
                this.positionTile(i);
            }
            this.setGridTop(this.getGridTop() + 1);
        },
        wrapWest: function() {
            var i, t, x, zoom = this.getZoomLevel();
            this.offsets.x -= this.tileWidth;
            this.setGridLeft(this.getGridLeft() - 1);
            for (i = 1; i <= this.rows; ++i) {
                x = this.columns * i - 1;
                t = this.tiles.splice(x, 1)[0];
                x -= this.columns - 1;
                this.tiles.splice(x, 0, t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft()), this.getGridTop() + i - 1, this.tileLevels[zoom - 1]));
                this.positionTile(x);
            }
        },
        wrapEast: function() {
            var i, t, x, zoom = this.getZoomLevel();
            this.offsets.x += this.tileWidth;
            for (i = 0; i < this.rows; ++i) {
                x = this.columns * i;
                t = this.tiles.splice(x, 1)[0];
                x += this.columns - 1;
                this.tiles.splice(x, 0, t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + this.columns), this.getGridTop() + i, this.tileLevels[zoom - 1]));
                this.positionTile(x);
            }
            this.setGridLeft(this.getGridLeft() + 1);
        },
        calculateCenterPoint: function() {
            var grid = this.getGrid();
            this.setCenterPoint(grid.toLL(grid.gridToX(this.getGridLeft(), -(this.mapOffsets.x + this.offsets.x) + (this.mapWidth / 2)), grid.gridToY(this.getGridTop(), -(this.mapOffsets.y + this.offsets.y) + (this.mapHeight / 2))));
        },
        getZoomByBounds: function(bounds, width, height) {
            var i, grid, nexy, swxy, max = this.tileLevels.length,
            ne = bounds.upper,
            sw = bounds.lower;
            width = width || this.mapWidth;
            height = height || this.mapHeight;
            for (i = 1; i < max; ++i) {
                grid = this.getGrid(i);
                nexy = grid.toXY(ne);
                swxy = grid.toXY(sw);
                if (Math.abs(nexy.x - swxy.x) < width && Math.abs(nexy.y - swxy.y) < height) {
                    return i
                }
            }
            return max;
        },
        getBoundsAndCentroid: function(points) {
            var xy, north, south, east, west, np, sp, ep, wp, proj = this.getGrid().projection;
            LMI.Lang.forEach(points,
            function(pt) {
                xy = proj.forward(pt.lngAsRad(), pt.latAsRad());
                if (!north) {
                    north = south = xy.y;
                    east = west = xy.x;
                    np = sp = pt.lat;
                    ep = wp = pt.lng;
                } else {
                    if (xy.y > north) {
                        north = xy.y;
                        np = pt.lat;
                    } else if (xy.y < south) {
                        south = xy.y;
                        sp = pt.lat;
                    }
                    if (xy.x > east) {
                        east = xy.x;
                        ep = pt.lng;
                    } else if (xy.x < west) {
                        west = xy.x;
                        wp = pt.lng;
                    }
                }
            });
            xy = proj.inverse((west + east) / 2, (south + north) / 2);
            return {
                centroid: LMI.Mapping.Point.fromRadians(xy.y, xy.x),
                upper: new LMI.Mapping.Point(np, ep),
                lower: new LMI.Mapping.Point(sp, wp),
                upperGrid: {
                    x: east,
                    y: north
                },
                lowerGrid: {
                    x: west,
                    y: south
                }
            };
        },
        setMapOffsets: function(x, y) {
            this.mapOffsets = {
                x: x,
                y: y
            };
        },
        updateMap: function() {
            var l = this.offsets.x + this.mapOffsets.x,
            t = this.offsets.y + this.mapOffsets.y;
            if (l > -this.bufferWidth) {
                this.wrapWest();
            } else if (l + this.width - this.mapWidth < this.bufferWidth) {
                this.wrapEast();
            }
            if (t > -this.bufferHeight) {
                this.wrapNorth();
            } else if (t + this.height - this.mapHeight < this.bufferHeight) {
                this.wrapSouth();
            }
            this.calculateCenterPoint();
        },
        setOffsets: function(x, y) {
            this.offsets = {
                x: x,
                y: y
            };
        },
        positionTile: function(i) {
            var t = this.tiles[i];
            t.setSize(this.tileWidth, this.tileHeight);
            t.setLeft(((i % this.columns) * t.getWidth() + this.offsets.x) + 'px');
            t.setTop((Math.floor(i / this.columns) * t.getHeight() + this.offsets.y) + 'px');
        },
        getScale: function() {
            var p = this.getCenterPoint(),
            g = this.getGrid(),
            s = g.getScale();
            if (g.projection instanceof LMI.Mapping.MercatorMapProjection) {
                s *= Math.cos(p.latAsRad());
            }
            return s;
        },
        getCopyrightString: function() {
            return this.options.copyright;
        },
        updateTiles: function() {
            var i, len;
            for (i = 0; i < this.tiles.length; ++i) {
                this.positionTile(i);
            }
        },
        setScale: function(scale) {
            this.scale = scale;
            this.tileWidth = this.options.tileWidth * scale;
            this.tileHeight = this.options.tileHeight * scale;
        },
        previewZoomLevel: function(level) {
            var lvl = Math.round(level + 0.5),
            lvlFrac = level - lvl,
            grid = this.getGrid(),
            previewGrid = this.getGrid(lvl),
            followingGrid = this.getGrid(lvl + 1);
            ratio = (previewGrid.gridWidth + ((followingGrid.gridWidth - previewGrid.gridWidth) * lvlFrac)) / grid.gridWidth;
            this.setScale(ratio);
            this.updateTiles();
        },
        getGrid: function(zoom) {
            var z = this.getZoomLevel(zoom) - 1;
            if (!this.grids[z]) {
                this.grids[z] = this.projection.getGridCS(this.tileLevels[z], this.projectionOptions);
            }
            return this.grids[z];
        },
        setGridLeft: function(n) {
            this.gridLeft = n;
        },
        getGridLeft: function() {
            return this.gridLeft;
        },
        setGridTop: function(n) {
            this.gridTop = n;
        },
        getGridTop: function() {
            return this.gridTop;
        },
        calculateGridPosition: function() {
            var g = this.getGrid(),
            p = this.getCenterPoint(),
            xy = g.toXY(p),
            tl = g.getUpperLeftPoint(p, this.mapWidth, this.mapHeight),
            tlTile = g.grid(tl);
            this.setCenterOffset(xy.x - g.gridToX(tlTile.x), xy.y - g.gridToY(tlTile.y));
            this.setGridLeft(tlTile.x);
            this.setGridTop(tlTile.y);
        },
        loadTiles: function() {
            var i, j, gridTop, right, bottom, left, tile = 0,
            zoom = this.getZoomLevel(),
            grid = this.getGrid();
            this.setMapOffsets(0, 0);
            this.setOffsets(0, 0);
            this.calculateGridPosition();
            gridTop = this.getGridTop();
            bottom = gridTop + this.rows;
            left = this.getGridLeft();
            right = left + this.columns;
            for (i = gridTop; i < bottom; ++i) {
                for (j = left; j < right; ++j) {
                    this.tiles[tile].setSrc(this.tileUrls.getUrl(grid.restrictGridX(j), i, this.tileLevels[zoom - 1]));
                    this.positionTile(tile++);
                }
            }
        }
    };
    return TileManager;
})();
LMI.Mapping.Map = (function() {
    var Y = YAHOO.util,
    $D = Y.Dom,
    _E = LMI.Element,
    $ = _E.getOne;
    function prettifyScale(dist) {
        var ret = 1;
        while (ret * 10 < dist) {
            ret *= 10;
        }
        if (ret * 5 < dist) {
            ret *= 5;
        }
        if (ret * 2 < dist) {
            ret *= 2;
        }
        return ret;
    }
    function Map(container, options) {
        this.init(container, options);
    }
    Map.prototype = {
        setZoomLevel: function(z, p) {
            var tm = this.tileManager;
            if (z < tm.minLevel) {
                z = tm.minLevel;
            } else if (z > tm.maxLevel) {
                z = tm.maxLevel;
            }
            if (p && !p.equals(this.getCenterPoint())) {
                this.tileManager.setCenterPoint(p);
            }
            this.zoomLevel = z;
            this.tileManager.setZoomLevel(z);
            this.loadMap();
            this.triggerEvent('zoom', this.getEventObject(), this);
        },
        bestFit: function(factor, collection) {
            var width, height, points = [],
            bounds,
            zoom,
            poi,
            bb,
            it;
            if (typeof factor === 'number') {
                this.factor = factor;
            } else if (typeof this.factor === 'number') {
                factor = this.factor;
            } else {
                this.factor = factor = 0.9;
            }
            collection = collection || this.objects;
            it = new DSMapObject_Iterator(collection);
            while (it.hasNext()) {
                poi = it.next();
                if (!poi.isIncludedInBestFit()) {
                    continue;
                }
                bb = poi.getBoundingBox();
                if (bb) {
                    points.push(bb.lower, bb.upper);
                } else if (poi.getPoint()) {
                    points.push(poi.getPoint());
                }
            }
            if (points.length === 0) {
                if (this.getOption('defaultLat') && this.getOption('defaultLng') && this.getOption('emptyZoom')) {
                    this.centerAndZoom(new LMI.Mapping.Point(this.getOption('defaultLat'), this.getOption('defaultLng')), this.getOption('emptyZoom'));
                }
            } else if (points.length === 1) {
                this.centerAndZoom(points[0], this.getOption('singleZoom'));
            } else {
                width = this.width * factor;
                height = this.height * factor;
                bounds = this.tileManager.getBoundsAndCentroid(points);
                zoom = this.tileManager.getZoomByBounds(bounds, width, height);
                this.centerAndZoom(bounds.centroid, zoom);
            }
        },
        bestFitEventHandler: function() {
            this.bestFit();
        },
        centerOnPoint: function(p) {
            if (!p.equals(this.getCenterPoint())) {
                this.prepareEventObject();
                this.tileManager.setCenterPoint(new LMI.Mapping.Point(p.lat, p.lng));
                this.loadMap();
                var o = this.getEventObject();
                this.triggerEvent('recenter', o, this);
            }
        },
        centerAndZoom: function(p, z) {
            this.prepareEventObject();
            this.setZoomLevel(z, p);
            var o = this.getEventObject();
            this.triggerEvent('recenter', o, this);
        },
        init: function(cont, options) {
            var container = $(cont);
            if (!container) {
                throw new Error('Map: unable to find container: "' + cont + '"');
            }
            if (!container.id) {
                $D.generateId(container);
            }
            this.id = container.id;
            this.container = container;
            $D.addClass(container, 'dsMap');
            this.initOptions(options);
            this.decorators = new DSMapDecoratorCollection();
            this.centerPoint = null;
            this.zoomLevel = 1;
            this.locale = this.getOption('defaultLocale');
            var year = new Date().getYear();
            if (year < 1000) {
                year += 1900;
            }
            this.copyrightTxt = '\xa9' + year + ' Local Matters, Inc.';
            this.copyrightSet = DSMapCopyrightSet;
            this.initContainer();
            this.setTileManager(new LMI.Mapping.TileManager(this.tileLayer, {
                width: this.width,
                height: this.height
            }));
            this.objects = new DSMapObject_Collection();
            this.messages = [];
            this.initEvents('zoom', 'recenter', 'resize');
        },
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            Map.Defaults);
            if ('config' in Map) {
                LMI.Lang.mergeObjects(this.options, Map.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        setTileManager: function(tileManager) {
            var cp = this.getCenterPoint(),
            copyright;
            if (this.tileManager) {
                this.tileManager.remove(this);
            }
            this.tileManager = tileManager;
            if (this.tileManager) {
                this.tileManager.add(this);
                this.tileManager.setMapWidth(this.width);
                this.tileManager.setMapHeight(this.height);
                if (!this.parentMap) {
                    copyright = this.tileManager.getCopyrightString();
                    if (copyright) {
                        this.setCopyright(copyright);
                    }
                }
                if (cp) {
                    this.tileManager.setCenterPoint(cp);
                    this.setZoomLevel(this.zoomLevel);
                } else {
                    this.tileManager.setZoomLevel(this.zoomLevel);
                }
            }
        },
        getTileManager: function(tileManager) {
            return this.tileManager;
        },
        setLocale: function(locale) {
            this.locale = locale;
            this.tileManager.setLocale(locale);
        },
        setOption: function(key, value) {
            this.options[key] = value;
        },
        getOption: function(key) {
            return this.options[key] || '';
        },
        addDecorator: function(d) {
            this.decorators.push(d);
            this.decoratorLayer.appendChild(d.getElement());
        },
        removeDecorator: function(d) {
            var l = this.decorators.getLength();
            for (var i = 0; i < l; ++i) {
                if (this.decorators.getByIndex(i) === d) {
                    this.decorators.remove(i);
                    this.decoratorLayer.removeChild(d.getElement());
                    return;
                }
            }
        },
        prepareEventObject: function() {
            this.beforeEvent = {
                previousLeft: this.getMapLeft(true),
                previousTop: this.getMapTop(true),
                previousZoomLevel: this.zoomLevel,
                previousCenter: this.getCenterPoint()
            };
        },
        getEventObject: function() {
            var o = this.beforeEvent;
            this.beforeEvent = {};
            o.zoomLevel = this.zoomLevel;
            o.center = this.getCenterPoint();
            o.left = this.getMapLeft(true);
            o.top = this.getMapTop(true);
            return o;
        },
        setCopyright: function(copyrightStr) {
            this.copyright.getElement().firstChild.nodeValue = this.copyrightTxt = copyrightStr;
        },
        getGridLeft: function() {
            alert('XXX: in getGridLeft -- should fix that');
            return null;
        },
        getGridTop: function() {
            alert('XXX: in getGridTop -- should fix that');
            return null;
        },
        positionMap: function() {
            var xy = this.tileManager.getCenterOffset();
            this.mapLayer.style.left = Math.round((this.width / 2) - xy.x) + 'px';
            this.mapLayer.style.top = Math.round((this.height / 2) - xy.y) + 'px';
        },
        updateScale: function() {
            if (!this.getOption('enableScales')) {
                return;
            }
            var scaleWidth = 100,
            scale = this.tileManager.getScale(),
            dist = scale * scaleWidth,
            metricUnit = 'km',
            metricScale = dist / 1000,
            stdUnit = 'mi',
            stdScale = dist / 1609.344,
            pretty;
            if (stdScale < 1) {
                stdScale = dist * 3.2808399;
                stdUnit = 'ft';
            }
            if (metricScale < 1) {
                metricScale = dist;
                metricUnit = 'm';
            }
            pretty = prettifyScale(stdScale);
            this.stdScale.style.width = Math.round(scaleWidth * pretty / stdScale) + 'px';
            this.stdScaleText.innerHTML = pretty + ' ' + stdUnit;
            pretty = prettifyScale(metricScale);
            this.metricScale.style.width = Math.round(scaleWidth * pretty / metricScale) + 'px';
            this.metricScaleText.innerHTML = pretty + ' ' + metricUnit;
        },
        loadMap: function() {
            this.tileManager.loadTiles();
            this.positionMap();
            this.updateObjects();
            this.updateScale();
        },
        updateObjects: function() {
            for (var it = new DSMapObject_Iterator(this.objects); it.hasNext();) {
                this.positionObject(it.next());
            }
        },
        getGridCoordinates: function(p) {
            return this.tileManager.getGrid().toXY(p);
        },
        getPointByXY: function(x, y) {
            return this.tileManager.getPointByPosition(x - this.getMapLeft(true), y - this.getMapTop(true));
        },
        getCenterPoint: function() {
            return this.tileManager ? this.tileManager.getCenterPoint() : null;
        },
        getURPoint: function() {
            return this.getPointByXY(this.width, 0);
        },
        getLLPoint: function() {
            return this.getPointByXY(0, this.height);
        },
        getULPoint: function() {
            return this.getPointByXY(0, 0);
        },
        getLRPoint: function() {
            return this.getPointByXY(this.width, this.height);
        },
        positionObject: function(obj, point) {
            var xy;
            if (point) {
                obj.setPoint(point);
            }
            point = obj.getPoint();
            if (point) {
                xy = this.tileManager.getPosition(obj.point);
                if (xy) {
                    obj.element.style.left = Math.round(xy.x - obj.xOffset) + 'px';
                    obj.element.style.top = Math.round(xy.y - obj.yOffset) + 'px';
                }
            }
            obj.update(this);
        },
        addObject: function(obj) {
            var id = this.objects.add(obj);
            obj.element.style.position = 'absolute';
            obj.z = 5 + obj.zOffset;
            obj.element.style.zIndex = obj.z;
            this.positionObject(obj);
            this.mapLayer.appendChild(obj.element);
            obj.add(this);
            return id;
        },
        batchAddObjects: function(objects) {
            var i, len;
            this.viewport.removeChild(this.mapLayer);
            for (i = 0, len = objects.length; i < len; ++i) {
                this.addObject(objects[i]);
            }
            this.viewport.appendChild(this.mapLayer);
        },
        removeObject: function(o) {
            var id = -1;
            if (typeof o === 'object') {
                for (var it = new DSMapObject_Iterator(this.objects); it.hasNext();) {
                    var i = it.next();
                    if (i === o) {
                        id = it.getId();
                        break;
                    }
                }
            } else {
                id = o;
            }
            var obj = this.objects.getById(id);
            if (obj) {
                obj.remove(this);
                this.mapLayer.removeChild(obj.element);
                this.objects.remove(id);
            }
        },
        batchRemoveObjects: function(objects) {
            var i, len;
            this.viewport.removeChild(this.mapLayer);
            for (i = 0, len = objects.length; i < len; ++i) {
                this.removeObject(objects[i]);
            }
            this.viewport.appendChild(this.mapLayer);
        },
        removeAll: function() {
            var o;
            this.viewport.removeChild(this.mapLayer);
            for (var it = new DSMapObject_Iterator(this.objects); it.hasNext();) {
                o = it.next();
                o.remove(this);
                o.element.parentNode.removeChild(o.element);
            }
            this.objects.removeAll();
            this.viewport.appendChild(this.mapLayer);
        },
        updateDataCopyright: function() {
            if (!this.dataCopyright) {
                var c = _E.create('div', null, {
                    textValue: ' ',
                    className: 'dataCopyright'
                });
                var pos = {
                    zIndex: 100,
                    bottom: 0
                };
                if (this.width >= 250) {
                    pos.right = 0;
                } else {
                    pos.left = 0;
                }
                this.dataCopyright = new DSMapDecorator(this, c, pos, 'copyright', 'data copyright');
                this.addDecorator(this.dataCopyright);
            }
            this.dataCopyright.getElement().firstChild.nodeValue = this.copyrightSet.getCopyright(this.getCenterPoint(), this.zoomLevel);
        },
        addCopyright: function() {
            var t = _E.create('div', null, {
                textValue: this.copyrightTxt
            });
            $D.addClass(t, 'copyright');
            this.copyright = new DSMapDecorator(this, t, {
                bottom: this.width >= 250 ? 0 : 10
            },
            'copyright', 'main copyright');
            this.addDecorator(this.copyright);
            this.updateDataCopyright();
        },
        sizeLayers: function() {
            this.width = parseInt(this.container.clientWidth, 10);
            this.height = parseInt(this.container.clientHeight, 10);
            this.desiredRows = Math.ceil(this.height / this.getOption('tileHeight')) + 2;
            this.desiredColumns = Math.ceil(this.width / this.getOption('tileWidth')) + 2;
            this.mapLayerWidth = this.desiredColumns * this.getOption('tileWidth');
            this.mapLayerHeight = this.desiredRows * this.getOption('tileHeight');
            this.mapLayer.style.height = this.mapLayerHeight + 'px';
            this.mapLayer.style.width = this.mapLayerWidth + 'px';
            this.decoratorLayer.style.height = this.height + 'px';
            this.decoratorLayer.style.width = this.width + 'px';
        },
        initContainer: function() {
            this.decoratorLayer = _E.create('div', this.container, {
                'class': 'decLayer'
            });
            this.viewport = _E.create('div', this.decoratorLayer, {
                'class': 'viewport'
            });
            this.mapLayer = _E.create('div', this.viewport, {
                'class': 'mapLayer'
            });
            this.tileLayer = _E.create('div', this.mapLayer, {
                'class': 'tileLayer'
            });
            if (this.getOption('enableScales')) {
                this.stdScale = _E.create('div', this.decoratorLayer, {
                    'class': 'mapScale stdScale'
                });
                this.stdScaleText = _E.create('span', this.stdScale);
                this.metricScale = _E.create('div', this.decoratorLayer, {
                    'class': 'mapScale metricScale'
                });
                this.metricScaleText = _E.create('span', this.metricScale);
            }
            if (!this.getOption('controlBuffer')) {
                this.setOption('controlBuffer', 0);
            }
            this.sizeLayers();
            this.desiredRows;
            this.desiredColumns;
            this.addCopyright();
        },
        getMapLeft: function() {
            var l = parseInt($D.getStyle(this.mapLayer, 'left'), 10);
            return l;
        },
        getMapTop: function() {
            var t = parseInt($D.getStyle(this.mapLayer, 'top'), 10);
            return t;
        },
        addMessage: function(msg) {
            this.messages.push(msg);
        },
        getMessages: function(msg) {
            return this.messages;
        }
    };
    LMI.Lang.importFunctions(Map, LMI.Event);
    return Map;
})();
LMI.Mapping.Map.Defaults = {
    'singleZoom': 3,
    'emptyZoom': 14,
    'defaultLat': 39.73926,
    'defaultLng': -104.98478,
    'defaultLocale': '',
    'enableScales': true,
    'imageBase': 'images/',
    'pixelUrl': 'images/pixel_trans.gif',
    'brokenUrl': 'images/map_unavailable.gif',
    'tileBase': 'http://localhost/tiles/',
    'tileExtension': '.png',
    'tileSuffix': '',
    'tileWidth': 256,
    'tileHeight': 256,
    'tileAttempts': 1,
    'standardParallel': 40
};
LMI.Mapping.Tile = (function() {
    var Y = YAHOO.util,
    ie = YAHOO.env.ua.ie,
    $D = Y.Dom,
    _E = LMI.Element;
    var errors = {};
    function setAlphaImageLoader(img, src) {
        if (img.style.filter.match(/progid:DXImageTransform.Microsoft.AlphaImageLoader\(src=\"(.*)\"\)/)) {
            img.style.filter = img.style.filter.replace(/progid:DXImageTransform.Microsoft.AlphaImageLoader\(src=\"(.*)\"\)/, 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")');
        } else {
            img.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")' + img.style.filter;
        }
        img.src = 'images/pixel_trans.gif';
    }
    function setOpacity(el, val, transparent) {
        if (!ie || ie >= 7 || !transparent) {
            $D.setStyle(el, 'opacity', val);
        } else {
            if (el.style.filter.match(/progid:DXImageTransform.Microsoft.Alpha\(opacity=\d+\.*\d*\)/)) {
                el.style.filter = el.style.filter.replace(/progid:DXImageTransform.Microsoft.Alpha\(opacity=\d+\.*\d*\)/, 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (val * 100) + ')');
            } else {
                el.style.filter += 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (val * 100) + ')';
            }
        }
    }
    function clearOpacity(el, transparent) {
        if (ie && (ie >= 7 || !transparent)) {
            el.style.filter = '';
        } else if (ie) {
            el.style.filter = el.style.filter.replace(/progid:DXImageTransform.Microsoft.Alpha\(opacity=\d+\.*\d*\)/, '');
        } else {
            $D.setStyle(el, 'opacity', 1);
        }
    }
    function Tile(el, options) {
        this.init(el, options);
    };
    Tile.defaults = {
        defaultTile: '/images/pixel_trans.gif',
        brokenTile: '/images/map_unavailable.gif',
        maxAttempts: 1,
        width: 256,
        height: 256,
        transparent: false
    };
    Tile.prototype = {
        init: function(el, options) {
            var t = this,
            cl;
            this.parentEl = el;
            this.initOptions(options);
            cl = !this.options.transparent || navigator.platform.match(/Mac/) ? '': 'noprint';
            this.img = _E.create('img', this.parentEl, {
                src: this.options.defaultTile,
                style: 'position: absolute;',
                galleryImg: 'no',
                className: cl,
                events: {
                    load: function() {
                        t.load.apply(this, [t.options.transparent]);
                    },
                    error: {
                        fn: this.error,
                        obj: this,
                        scope: true
                    }
                }
            });
            this.setSize(this.options.width, this.options.height);
            setOpacity(this.img, 0, this.options.transparent);
        },
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            Tile.defaults);
            if ('config' in Tile) {
                LMI.Lang.mergeObjects(this.options, Tile.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        error: function() {
            var s, i = this.img;
            if (!errors[i.src]) {
                errors[i.src] = 1;
            }
            if (!i.src.match(this.options.brokenTile)) {
                if (errors[i.src]++>=this.options.maxAttempts) {
                    i.src = this.options.brokenTile;
                } else {
                    s = i.src;
                    i.src = this.options.defaultTile;
                    i.src = s;
                }
            }
        },
        load: function(transparent) {
            var a, t = this;
            if ('Anim' in Y) {
                if (!ie || ie >= 7 || !transparent) {
                    a = new Y.Anim(this, {
                        opacity: {
                            to: 1
                        }
                    },
                    0.75);
                } else {
                    a = new Y.Anim(this, {},
                    0.75);
                    a.onTween.subscribe(function(type, args) {
                        var o = args[0].currentFrame / a.totalFrames;
                        setOpacity(t, o, true);
                    });
                }
                if (ie) {
                    a.onComplete.subscribe(function() {
                        clearOpacity(t, transparent);
                    });
                }
                a.animate();
            } else {
                clearOpacity(this, transparent);
            }
        },
        removeFromDom: function() {
            _E.destroy(this.img);
        },
        setSize: function(width, height) {
            this.width = this.img.width = width;
            this.height = this.img.height = height;
        },
        getWidth: function() {
            return this.width;
        },
        getHeight: function() {
            return this.height;
        },
        setLeft: function(left) {
            this.img.style.left = left;
        },
        setTop: function(t) {
            this.img.style.top = t;
        },
        setSrc: function(url) {
            var that = this;
            this.src = url || this.options.defaultTile;
            if (this.loadTimeout) {
                window.clearTimeout(this.loadTimeout);
                this.loadTimeout = null;
            }
            if (typeof this.img.complete != 'undefined' && !this.img.complete) {
                this.loadTimeout = window.setTimeout(function() {
                    that.loadTimeout = null;
                    that.setSrc(that.src);
                },
                1000);
                return;
            }
            if (url) {
                if (this.img.src != url) {
                    setOpacity(this.img, 0, this.options.transparent);
                    this.setImgSrc();
                }
            } else {
                this.setImgSrc();
            }
        },
        setImgSrc: function() {
            var that = this;
            window.setTimeout(function() {
                var img = that.img,
                src = that.src;
                if (ie && ie < 7) {
                    if (that.options.transparent && src.match(/\.png(;|$|\?)/)) {
                        setAlphaImageLoader(img, src);
                    } else if (img.src != src) {
                        img.src = src;
                    }
                } else if (img) {
                    img.src = src;
                }
            },
            0);
        }
    };
    Tile.getErrors = function() {
        return errors;
    };
    return Tile;
})();
var DSMapCopyrightSet = new DSCopyrightSet();
(function() {
    var year = new Date().getYear(),
    P = LMI.Mapping.Point;
    if (year < 1000) {
        year += 1900;
    }
    var nt = new DSCopyright('\xa9' + year + ' NAVTEQ', [new DSBoundingBox(new P(10.0, -135.0), new P(70.0, -60.0)), new DSBoundingBox(new P(48.0, -180.0), new P(75.0, -124.0)), new DSBoundingBox(new P(16.860777, -161.283172), new P(24.219651, -153.424705)), new DSBoundingBox(new P(12.5, -78.6), new P(33.0, -50.0))]);
    var ta = new DSCopyright('\xa9' + year + ' TeleAtlas', [new DSBoundingBox(new P(48.478825, 1.322422), new P(52.521175, 7.677558)), new DSBoundingBox(new P(31.0, -10), new P(44.0, 5.0)), new DSBoundingBox(new P(48.0, -0.6), new P(56.0, 11.5)), new DSBoundingBox(new P(46.0, -20.0), new P(61.0, 4.7))]);
    var tl = '\xa9' + year + ' Terralink Intl Ltd';
    DSMapCopyrightSet.addCopyright(nt);
    DSMapCopyrightSet.addCopyright(ta);
    DSMapCopyrightSet.addCopyright(new DSCopyright(tl, new DSBoundingBox(new P( - 70.0, 133.0), new P( - 11.0, 180.0))));
})();
(function() {
    LMI.Animation = function() {
        this.init();
    };
    LMI.Animation.prototype = {
        init: function() {
            this.thread = null;
            this.currentFrame = 0;
            this.totalFrames = 0;
            this.fps = 24;
            this.duration = 1;
            this.delay = 1;
            this.initEvents('tween', 'end');
        },
        setDuration: function(d) {
            this.duration = d;
        },
        start: function() {
            if (this.thread === null) {
                this.totalFrames = Math.ceil(this.fps * this.duration);
                this.currentFrame = 0;
                this.skip = false;
                this.droppedFrames = 0;
                var o = this;
                this.thread = setInterval(function() {
                    o.run();
                },
                o.delay);
                this.start = new Date().getTime();
            }
        },
        stop: function() {
            if (this.thread !== null) {
                clearInterval(this.thread);
                this.thread = null;
                var o = this.getEventObject();
                this.triggerEvent('end', o, this);
            }
        },
        skipToEnd: function() {
            this.skip = true;
        },
        catchUp: function() {
            var time = new Date().getTime() - this.start,
            adjust = 0,
            d = this.duration * 1000,
            t = this.totalFrames,
            f = this.currentFrame;
            var expected = t * (time / d);
            if (time > d || this.skip) {
                adjust = t - f;
            } else if (expected > f) {
                adjust = Math.ceil(expected - f);
            }
            if (adjust > 0) {
                adjust = this.currentFrame + adjust < t ? adjust: t - f;
                this.droppedFrames += adjust;
                this.currentFrame += adjust;
            }
        },
        run: function() {
            if (this.currentFrame < this.totalFrames) {
                this.catchUp();
                this.doFrame();
                this.currentFrame++;
            } else {
                this.doFrame();
                this.stop();
            }
        },
        doFrame: function() {
            this.triggerEvent('tween', {
                currentFrame: this.currentFrame,
                totalFrames: this.totalFrames
            },
            this);
        },
        getEventObject: function() {
            return {
                dropped: this.droppedFrames,
                endedEarly: this.skip
            };
        }
    };
    LMI.Lang.importFunctions(LMI.Animation, LMI.Event);
})();
(function() {
    LMI.Animation.Motion = function(element, start, end) {
        this.init(element, start, end);
    };
    LMI.Lang.extend(LMI.Animation.Motion, LMI.Animation);
    var L = LMI.Animation.Motion,
    proto = L.prototype,
    superclass = L.superclass;
    proto.init = function(element, start, end) {
        superclass.init.call(this);
        this.element = element;
        this.startPos = start;
        this.endPos = end;
        this.easingMethod = LMI.Animation.Easing.easeOutStrong;
    };
    proto.setEasingMethod = function(method) {
        this.easingMethod = method;
    };
    proto.doFrame = function() {
        var t = this.easingMethod(this.currentFrame, 1, 100, this.totalFrames) / 100;
        var b = LMI.Animation.Bezier.getPosition([this.startPos, this.endPos], t);
        this.setProperties(b);
        superclass.doFrame.call(this);
    };
    proto.setProperties = function(p) {
        this.element.style.left = Math.floor(p.x) + 'px';
        this.element.style.top = Math.floor(p.y) + 'px';
    };
})();
(function() {
    LMI.Animation.Size = function(element, start, end) {
        this.init(element, start, end);
    };
    LMI.Lang.extend(LMI.Animation.Size, LMI.Animation.Motion);
    var L = LMI.Animation.Size,
    proto = L.prototype;
    proto.setProperties = function(p) {
        this.element.style.width = Math.floor(p.x) + 'px';
        this.element.style.height = Math.floor(p.y) + 'px';
    };
})();
(function() {
    LMI.Animation.Fade = function(element, start, end) {
        this.init(element, {
            x: start,
            y: 0
        },
        {
            x: end,
            y: 0
        });
    };
    LMI.Lang.extend(LMI.Animation.Fade, LMI.Animation.Motion);
    var L = LMI.Animation.Fade,
    proto = L.prototype,
    superclass = L.superclass;
    proto.setProperties = function(p) {
        YAHOO.util.Dom.setStyle(this.element, 'opacity', p.x / 100);
    };
})();
LMI.Animation.Bezier = (function() {
    return {
        getPosition: function(coords, t) {
            var i, j, n = coords.length,
            r = [];
            for (i = 0; i < n; ++i) {
                r.push({
                    x: coords[i].x,
                    y: coords[i].y
                });
            }
            for (j = 1; j < n; ++j) {
                for (i = 0; i < n - j; ++i) {
                    r[i].x = (1 - t) * r[i].x + t * r[i + 1].x;
                    r[i].y = (1 - t) * r[i].y + t * r[i + 1].y;
                }
            }
            return r[0];
        }
    };
})();
LMI.Animation.Easing = (function() {
    return {
        easeOut: function(t, b, c, d) {
            return - c * (t /= d) * (t - 2) + b;
        },
        easeOutStrong: function(t, b, c, d) {
            return - c * ((t = t / d - 1) * t * t * t - 1) + b;
        },
        easeBothStrong: function(t, b, c, d) {
            if ((t /= d / 2) < 1) {
                return c / 2 * t * t * t * t + b;
            }
            return - c / 2 * ((t -= 2) * t * t * t - 2) + b;
        },
        bounceOut: function(t, b, c, d) {
            if ((t /= d) < (1 / 2.75)) {
                return c * (7.5625 * t * t) + b;
            } else if (t < (2 / 2.75)) {
                return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
            } else if (t < (2.5 / 2.75)) {
                return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
            } else {
                return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
            }
        },
        elasticOut: function(t, b, c, d, a, p) {
            var s;
            if (t === 0) {
                return b;
            }
            if ((t /= d) == 1) {
                return b + c;
            }
            if (!p) {
                p = d * 0.5;
            }
            if (!a || a < Math.abs(c)) {
                a = c;
                s = p / 4;
            } else {
                s = p / (2 * Math.PI) * Math.asin(c / a);
            }
            return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
        }
    };
})();
YAHOO.util.Anim = function(el, attributes, duration, method) {
    if (!el) {}
    this.init(el, attributes, duration, method);
};
YAHOO.util.Anim.prototype = {
    toString: function() {
        var el = this.getEl();
        var id = el.id || el.tagName || el;
        return ("Anim " + id);
    },
    patterns: {
        noNegatives: /width|height|opacity|padding/i,
        offsetAttribute: /^((width|height)|(top|left))$/,
        defaultUnit: /width|height|top$|bottom$|left$|right$/i,
        offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i
    },
    doMethod: function(attr, start, end) {
        return this.method(this.currentFrame, start, end - start, this.totalFrames);
    },
    setAttribute: function(attr, val, unit) {
        if (this.patterns.noNegatives.test(attr)) {
            val = (val > 0) ? val: 0;
        }
        YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);
    },
    getAttribute: function(attr) {
        var el = this.getEl();
        var val = YAHOO.util.Dom.getStyle(el, attr);
        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
            return parseFloat(val);
        }
        var a = this.patterns.offsetAttribute.exec(attr) || [];
        var pos = !!(a[3]);
        var box = !!(a[2]);
        if (box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos)) {
            val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
        } else {
            val = 0;
        }
        return val;
    },
    getDefaultUnit: function(attr) {
        if (this.patterns.defaultUnit.test(attr)) {
            return 'px';
        }
        return '';
    },
    setRuntimeAttribute: function(attr) {
        var start;
        var end;
        var attributes = this.attributes;
        this.runtimeAttributes[attr] = {};
        var isset = function(prop) {
            return (typeof prop !== 'undefined');
        };
        if (!isset(attributes[attr]['to']) && !isset(attributes[attr]['by'])) {
            return false;
        }
        start = (isset(attributes[attr]['from'])) ? attributes[attr]['from'] : this.getAttribute(attr);
        if (isset(attributes[attr]['to'])) {
            end = attributes[attr]['to'];
        } else if (isset(attributes[attr]['by'])) {
            if (start.constructor == Array) {
                end = [];
                for (var i = 0, len = start.length; i < len; ++i) {
                    end[i] = start[i] + attributes[attr]['by'][i] * 1;
                }
            } else {
                end = start + attributes[attr]['by'] * 1;
            }
        }
        this.runtimeAttributes[attr].start = start;
        this.runtimeAttributes[attr].end = end;
        this.runtimeAttributes[attr].unit = (isset(attributes[attr].unit)) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);
        return true;
    },
    init: function(el, attributes, duration, method) {
        var isAnimated = false;
        var startTime = null;
        var actualFrames = 0;
        el = YAHOO.util.Dom.get(el);
        this.attributes = attributes || {};
        this.duration = !YAHOO.lang.isUndefined(duration) ? duration: 1;
        this.method = method || YAHOO.util.Easing.easeNone;
        this.useSeconds = true;
        this.currentFrame = 0;
        this.totalFrames = YAHOO.util.AnimMgr.fps;
        this.setEl = function(element) {
            el = YAHOO.util.Dom.get(element);
        };
        this.getEl = function() {
            return el;
        };
        this.isAnimated = function() {
            return isAnimated;
        };
        this.getStartTime = function() {
            return startTime;
        };
        this.runtimeAttributes = {};
        this.animate = function() {
            if (this.isAnimated()) {
                return false;
            }
            this.currentFrame = 0;
            this.totalFrames = (this.useSeconds) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
            if (this.duration === 0 && this.useSeconds) {
                this.totalFrames = 1;
            }
            YAHOO.util.AnimMgr.registerElement(this);
            return true;
        };
        this.stop = function(finish) {
            if (finish) {
                this.currentFrame = this.totalFrames;
                this._onTween.fire();
            }
            YAHOO.util.AnimMgr.stop(this);
        };
        var onStart = function() {
            this.onStart.fire();
            this.runtimeAttributes = {};
            for (var attr in this.attributes) {
                this.setRuntimeAttribute(attr);
            }
            isAnimated = true;
            actualFrames = 0;
            startTime = new Date();
        };
        var onTween = function() {
            var data = {
                duration: new Date() - this.getStartTime(),
                currentFrame: this.currentFrame
            };
            data.toString = function() {
                return ('duration: ' + data.duration + ', currentFrame: ' + data.currentFrame);
            };
            this.onTween.fire(data);
            var runtimeAttributes = this.runtimeAttributes;
            for (var attr in runtimeAttributes) {
                this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
            }
            actualFrames += 1;
        };
        var onComplete = function() {
            var actual_duration = (new Date() - startTime) / 1000;
            var data = {
                duration: actual_duration,
                frames: actualFrames,
                fps: actualFrames / actual_duration
            };
            data.toString = function() {
                return ('duration: ' + data.duration + ', frames: ' + data.frames + ', fps: ' + data.fps);
            };
            isAnimated = false;
            actualFrames = 0;
            this.onComplete.fire(data);
        };
        this._onStart = new YAHOO.util.CustomEvent('_start', this, true);
        this.onStart = new YAHOO.util.CustomEvent('start', this);
        this.onTween = new YAHOO.util.CustomEvent('tween', this);
        this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);
        this.onComplete = new YAHOO.util.CustomEvent('complete', this);
        this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);
        this._onStart.subscribe(onStart);
        this._onTween.subscribe(onTween);
        this._onComplete.subscribe(onComplete);
    }
};
YAHOO.util.AnimMgr = new
function() {
    var thread = null;
    var queue = [];
    var tweenCount = 0;
    this.fps = 1000;
    this.delay = 1;
    this.registerElement = function(tween) {
        queue[queue.length] = tween;
        tweenCount += 1;
        tween._onStart.fire();
        this.start();
    };
    this.unRegister = function(tween, index) {
        tween._onComplete.fire();
        index = index || getIndex(tween);
        if (index == -1) {
            return false;
        }
        queue.splice(index, 1);
        tweenCount -= 1;
        if (tweenCount <= 0) {
            this.stop();
        }
        return true;
    };
    this.start = function() {
        if (thread === null) {
            thread = setInterval(this.run, this.delay);
        }
    };
    this.stop = function(tween) {
        if (!tween) {
            clearInterval(thread);
            for (var i = 0, len = queue.length; i < len; ++i) {
                if (queue[0].isAnimated()) {
                    this.unRegister(queue[0], 0);
                }
            }
            queue = [];
            thread = null;
            tweenCount = 0;
        }
        else {
            this.unRegister(tween);
        }
    };
    this.run = function() {
        for (var i = 0, len = queue.length; i < len; ++i) {
            var tween = queue[i];
            if (!tween || !tween.isAnimated()) {
                continue;
            }
            if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null) {
                tween.currentFrame += 1;
                if (tween.useSeconds) {
                    correctFrame(tween);
                }
                tween._onTween.fire();
            }
            else {
                YAHOO.util.AnimMgr.stop(tween, i);
            }
        }
    };
    var getIndex = function(anim) {
        for (var i = 0, len = queue.length; i < len; ++i) {
            if (queue[i] == anim) {
                return i;
            }
        }
        return - 1;
    };
    var correctFrame = function(tween) {
        var frames = tween.totalFrames;
        var frame = tween.currentFrame;
        var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
        var elapsed = (new Date() - tween.getStartTime());
        var tweak = 0;
        if (elapsed < tween.duration * 1000) {
            tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
        } else {
            tweak = frames - (frame + 1);
        }
        if (tweak > 0 && isFinite(tweak)) {
            if (tween.currentFrame + tweak >= frames) {
                tweak = frames - (frame + 1);
            }
            tween.currentFrame += tweak;
        }
    };
};
YAHOO.util.Bezier = new
function() {
    this.getPosition = function(points, t) {
        var n = points.length;
        var tmp = [];
        for (var i = 0; i < n; ++i) {
            tmp[i] = [points[i][0], points[i][1]];
        }
        for (var j = 1; j < n; ++j) {
            for (i = 0; i < n - j; ++i) {
                tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
                tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
            }
        }
        return [tmp[0][0], tmp[0][1]];
    };
};
(function() {
    YAHOO.util.ColorAnim = function(el, attributes, duration, method) {
        YAHOO.util.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
    };
    YAHOO.extend(YAHOO.util.ColorAnim, YAHOO.util.Anim);
    var Y = YAHOO.util;
    var superclass = Y.ColorAnim.superclass;
    var proto = Y.ColorAnim.prototype;
    proto.toString = function() {
        var el = this.getEl();
        var id = el.id || el.tagName;
        return ("ColorAnim " + id);
    };
    proto.patterns.color = /color$/i;
    proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
    proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
    proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
    proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/;
    proto.parseColor = function(s) {
        if (s.length == 3) {
            return s;
        }
        var c = this.patterns.hex.exec(s);
        if (c && c.length == 4) {
            return [parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16)];
        }
        c = this.patterns.rgb.exec(s);
        if (c && c.length == 4) {
            return [parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10)];
        }
        c = this.patterns.hex3.exec(s);
        if (c && c.length == 4) {
            return [parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16)];
        }
        return null;
    };
    proto.getAttribute = function(attr) {
        var el = this.getEl();
        if (this.patterns.color.test(attr)) {
            var val = YAHOO.util.Dom.getStyle(el, attr);
            if (this.patterns.transparent.test(val)) {
                var parent = el.parentNode;
                val = Y.Dom.getStyle(parent, attr);
                while (parent && this.patterns.transparent.test(val)) {
                    parent = parent.parentNode;
                    val = Y.Dom.getStyle(parent, attr);
                    if (parent.tagName.toUpperCase() == 'HTML') {
                        val = '#fff';
                    }
                }
            }
        } else {
            val = superclass.getAttribute.call(this, attr);
        }
        return val;
    };
    proto.doMethod = function(attr, start, end) {
        var val;
        if (this.patterns.color.test(attr)) {
            val = [];
            for (var i = 0, len = start.length; i < len; ++i) {
                val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
            }
            val = 'rgb(' + Math.floor(val[0]) + ',' + Math.floor(val[1]) + ',' + Math.floor(val[2]) + ')';
        }
        else {
            val = superclass.doMethod.call(this, attr, start, end);
        }
        return val;
    };
    proto.setRuntimeAttribute = function(attr) {
        superclass.setRuntimeAttribute.call(this, attr);
        if (this.patterns.color.test(attr)) {
            var attributes = this.attributes;
            var start = this.parseColor(this.runtimeAttributes[attr].start);
            var end = this.parseColor(this.runtimeAttributes[attr].end);
            if (typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined') {
                end = this.parseColor(attributes[attr].by);
                for (var i = 0, len = start.length; i < len; ++i) {
                    end[i] = start[i] + end[i];
                }
            }
            this.runtimeAttributes[attr].start = start;
            this.runtimeAttributes[attr].end = end;
        }
    };
})();
YAHOO.util.Easing = {
    easeNone: function(t, b, c, d) {
        return c * t / d + b;
    },
    easeIn: function(t, b, c, d) {
        return c * (t /= d) * t + b;
    },
    easeOut: function(t, b, c, d) {
        return - c * (t /= d) * (t - 2) + b;
    },
    easeBoth: function(t, b, c, d) {
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t + b;
        }
        return - c / 2 * ((--t) * (t - 2) - 1) + b;
    },
    easeInStrong: function(t, b, c, d) {
        return c * (t /= d) * t * t * t + b;
    },
    easeOutStrong: function(t, b, c, d) {
        return - c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeBothStrong: function(t, b, c, d) {
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t * t * t + b;
        }
        return - c / 2 * ((t -= 2) * t * t * t - 2) + b;
    },
    elasticIn: function(t, b, c, d, a, p) {
        if (t == 0) {
            return b;
        }
        if ((t /= d) == 1) {
            return b + c;
        }
        if (!p) {
            p = d * .3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        }
        else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        return - (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    },
    elasticOut: function(t, b, c, d, a, p) {
        if (t == 0) {
            return b;
        }
        if ((t /= d) == 1) {
            return b + c;
        }
        if (!p) {
            p = d * .3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        }
        else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
    },
    elasticBoth: function(t, b, c, d, a, p) {
        if (t == 0) {
            return b;
        }
        if ((t /= d / 2) == 2) {
            return b + c;
        }
        if (!p) {
            p = d * (.3 * 1.5);
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        }
        else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        if (t < 1) {
            return - .5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        }
        return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
    },
    backIn: function(t, b, c, d, s) {
        if (typeof s == 'undefined') {
            s = 1.70158;
        }
        return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    backOut: function(t, b, c, d, s) {
        if (typeof s == 'undefined') {
            s = 1.70158;
        }
        return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    backBoth: function(t, b, c, d, s) {
        if (typeof s == 'undefined') {
            s = 1.70158;
        }
        if ((t /= d / 2) < 1) {
            return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
        }
        return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    },
    bounceIn: function(t, b, c, d) {
        return c - YAHOO.util.Easing.bounceOut(d - t, 0, c, d) + b;
    },
    bounceOut: function(t, b, c, d) {
        if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b;
        } else if (t < (2 / 2.75)) {
            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
        } else if (t < (2.5 / 2.75)) {
            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
        }
        return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
    },
    bounceBoth: function(t, b, c, d) {
        if (t < d / 2) {
            return YAHOO.util.Easing.bounceIn(t * 2, 0, c, d) * .5 + b;
        }
        return YAHOO.util.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
    }
};
(function() {
    YAHOO.util.Motion = function(el, attributes, duration, method) {
        if (el) {
            YAHOO.util.Motion.superclass.constructor.call(this, el, attributes, duration, method);
        }
    };
    YAHOO.extend(YAHOO.util.Motion, YAHOO.util.ColorAnim);
    var Y = YAHOO.util;
    var superclass = Y.Motion.superclass;
    var proto = Y.Motion.prototype;
    proto.toString = function() {
        var el = this.getEl();
        var id = el.id || el.tagName;
        return ("Motion " + id);
    };
    proto.patterns.points = /^points$/i;
    proto.setAttribute = function(attr, val, unit) {
        if (this.patterns.points.test(attr)) {
            unit = unit || 'px';
            superclass.setAttribute.call(this, 'left', val[0], unit);
            superclass.setAttribute.call(this, 'top', val[1], unit);
        } else {
            superclass.setAttribute.call(this, attr, val, unit);
        }
    };
    proto.getAttribute = function(attr) {
        if (this.patterns.points.test(attr)) {
            var val = [superclass.getAttribute.call(this, 'left'), superclass.getAttribute.call(this, 'top')];
        } else {
            val = superclass.getAttribute.call(this, attr);
        }
        return val;
    };
    proto.doMethod = function(attr, start, end) {
        var val = null;
        if (this.patterns.points.test(attr)) {
            var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
            val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
        } else {
            val = superclass.doMethod.call(this, attr, start, end);
        }
        return val;
    };
    proto.setRuntimeAttribute = function(attr) {
        if (this.patterns.points.test(attr)) {
            var el = this.getEl();
            var attributes = this.attributes;
            var start;
            var control = attributes['points']['control'] || [];
            var end;
            var i, len;
            if (control.length > 0 && !(control[0] instanceof Array)) {
                control = [control];
            } else {
                var tmp = [];
                for (i = 0, len = control.length; i < len; ++i) {
                    tmp[i] = control[i];
                }
                control = tmp;
            }
            if (Y.Dom.getStyle(el, 'position') == 'static') {
                Y.Dom.setStyle(el, 'position', 'relative');
            }
            if (isset(attributes['points']['from'])) {
                Y.Dom.setXY(el, attributes['points']['from']);
            }
            else {
                Y.Dom.setXY(el, Y.Dom.getXY(el));
            }
            start = this.getAttribute('points');
            if (isset(attributes['points']['to'])) {
                end = translateValues.call(this, attributes['points']['to'], start);
                var pageXY = Y.Dom.getXY(this.getEl());
                for (i = 0, len = control.length; i < len; ++i) {
                    control[i] = translateValues.call(this, control[i], start);
                }
            } else if (isset(attributes['points']['by'])) {
                end = [start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1]];
                for (i = 0, len = control.length; i < len; ++i) {
                    control[i] = [start[0] + control[i][0], start[1] + control[i][1]];
                }
            }
            this.runtimeAttributes[attr] = [start];
            if (control.length > 0) {
                this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
            }
            this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
        }
        else {
            superclass.setRuntimeAttribute.call(this, attr);
        }
    };
    var translateValues = function(val, start) {
        var pageXY = Y.Dom.getXY(this.getEl());
        val = [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];
        return val;
    };
    var isset = function(prop) {
        return (typeof prop !== 'undefined');
    };
})();
(function() {
    YAHOO.util.Scroll = function(el, attributes, duration, method) {
        if (el) {
            YAHOO.util.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
        }
    };
    YAHOO.extend(YAHOO.util.Scroll, YAHOO.util.ColorAnim);
    var Y = YAHOO.util;
    var superclass = Y.Scroll.superclass;
    var proto = Y.Scroll.prototype;
    proto.toString = function() {
        var el = this.getEl();
        var id = el.id || el.tagName;
        return ("Scroll " + id);
    };
    proto.doMethod = function(attr, start, end) {
        var val = null;
        if (attr == 'scroll') {
            val = [this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames), this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)];
        } else {
            val = superclass.doMethod.call(this, attr, start, end);
        }
        return val;
    };
    proto.getAttribute = function(attr) {
        var val = null;
        var el = this.getEl();
        if (attr == 'scroll') {
            val = [el.scrollLeft, el.scrollTop];
        } else {
            val = superclass.getAttribute.call(this, attr);
        }
        return val;
    };
    proto.setAttribute = function(attr, val, unit) {
        var el = this.getEl();
        if (attr == 'scroll') {
            el.scrollLeft = val[0];
            el.scrollTop = val[1];
        } else {
            superclass.setAttribute.call(this, attr, val, unit);
        }
    };
})();
YAHOO.register("animation", YAHOO.util.Anim, {
    version: "2.3.0",
    build: "442"
});
(function() {
    YAHOO.util.Config = function(owner) {
        if (owner) {
            this.init(owner);
        }
        if (!owner) {}
    };
    var Lang = YAHOO.lang,
    CustomEvent = YAHOO.util.CustomEvent,
    Config = YAHOO.util.Config;
    Config.CONFIG_CHANGED_EVENT = "configChanged";
    Config.BOOLEAN_TYPE = "boolean";
    Config.prototype = {
        owner: null,
        queueInProgress: false,
        config: null,
        initialConfig: null,
        eventQueue: null,
        configChangedEvent: null,
        init: function(owner) {
            this.owner = owner;
            this.configChangedEvent = this.createEvent(Config.CONFIG_CHANGED_EVENT);
            this.configChangedEvent.signature = CustomEvent.LIST;
            this.queueInProgress = false;
            this.config = {};
            this.initialConfig = {};
            this.eventQueue = [];
        },
        checkBoolean: function(val) {
            return (typeof val == Config.BOOLEAN_TYPE);
        },
        checkNumber: function(val) {
            return (!isNaN(val));
        },
        fireEvent: function(key, value) {
            var property = this.config[key];
            if (property && property.event) {
                property.event.fire(value);
            }
        },
        addProperty: function(key, propertyObject) {
            key = key.toLowerCase();
            this.config[key] = propertyObject;
            propertyObject.event = this.createEvent(key, {
                scope: this.owner
            });
            propertyObject.event.signature = CustomEvent.LIST;
            propertyObject.key = key;
            if (propertyObject.handler) {
                propertyObject.event.subscribe(propertyObject.handler, this.owner);
            }
            this.setProperty(key, propertyObject.value, true);
            if (!propertyObject.suppressEvent) {
                this.queueProperty(key, propertyObject.value);
            }
        },
        getConfig: function() {
            var cfg = {},
            prop, property;
            for (prop in this.config) {
                property = this.config[prop];
                if (property && property.event) {
                    cfg[prop] = property.value;
                }
            }
            return cfg;
        },
        getProperty: function(key) {
            var property = this.config[key.toLowerCase()];
            if (property && property.event) {
                return property.value;
            } else {
                return undefined;
            }
        },
        resetProperty: function(key) {
            key = key.toLowerCase();
            var property = this.config[key];
            if (property && property.event) {
                if (this.initialConfig[key] && !Lang.isUndefined(this.initialConfig[key])) {
                    this.setProperty(key, this.initialConfig[key]);
                    return true;
                }
            } else {
                return false;
            }
        },
        setProperty: function(key, value, silent) {
            var property;
            key = key.toLowerCase();
            if (this.queueInProgress && !silent) {
                this.queueProperty(key, value);
                return true;
            } else {
                property = this.config[key];
                if (property && property.event) {
                    if (property.validator && !property.validator(value)) {
                        return false;
                    } else {
                        property.value = value;
                        if (!silent) {
                            this.fireEvent(key, value);
                            this.configChangedEvent.fire([key, value]);
                        }
                        return true;
                    }
                } else {
                    return false;
                }
            }
        },
        queueProperty: function(key, value) {
            key = key.toLowerCase();
            var property = this.config[key],
            foundDuplicate = false,
            iLen,
            queueItem,
            queueItemKey,
            queueItemValue,
            sLen,
            supercedesCheck,
            qLen,
            queueItemCheck,
            queueItemCheckKey,
            queueItemCheckValue,
            i,
            s,
            q;
            if (property && property.event) {
                if (!Lang.isUndefined(value) && property.validator && !property.validator(value)) {
                    return false;
                } else {
                    if (!Lang.isUndefined(value)) {
                        property.value = value;
                    } else {
                        value = property.value;
                    }
                    foundDuplicate = false;
                    iLen = this.eventQueue.length;
                    for (i = 0; i < iLen; i++) {
                        queueItem = this.eventQueue[i];
                        if (queueItem) {
                            queueItemKey = queueItem[0];
                            queueItemValue = queueItem[1];
                            if (queueItemKey == key) {
                                this.eventQueue[i] = null;
                                this.eventQueue.push([key, (!Lang.isUndefined(value) ? value: queueItemValue)]);
                                foundDuplicate = true;
                                break;
                            }
                        }
                    }
                    if (!foundDuplicate && !Lang.isUndefined(value)) {
                        this.eventQueue.push([key, value]);
                    }
                }
                if (property.supercedes) {
                    sLen = property.supercedes.length;
                    for (s = 0; s < sLen; s++) {
                        supercedesCheck = property.supercedes[s];
                        qLen = this.eventQueue.length;
                        for (q = 0; q < qLen; q++) {
                            queueItemCheck = this.eventQueue[q];
                            if (queueItemCheck) {
                                queueItemCheckKey = queueItemCheck[0];
                                queueItemCheckValue = queueItemCheck[1];
                                if (queueItemCheckKey == supercedesCheck.toLowerCase()) {
                                    this.eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
                                    this.eventQueue[q] = null;
                                    break;
                                }
                            }
                        }
                    }
                }
                return true;
            } else {
                return false;
            }
        },
        refireEvent: function(key) {
            key = key.toLowerCase();
            var property = this.config[key];
            if (property && property.event && !Lang.isUndefined(property.value)) {
                if (this.queueInProgress) {
                    this.queueProperty(key);
                } else {
                    this.fireEvent(key, property.value);
                }
            }
        },
        applyConfig: function(userConfig, init) {
            var sKey, oValue, oConfig;
            if (init) {
                oConfig = {};
                for (sKey in userConfig) {
                    if (Lang.hasOwnProperty(userConfig, sKey)) {
                        oConfig[sKey.toLowerCase()] = userConfig[sKey];
                    }
                }
                this.initialConfig = oConfig;
            }
            for (sKey in userConfig) {
                if (Lang.hasOwnProperty(userConfig, sKey)) {
                    this.queueProperty(sKey, userConfig[sKey]);
                }
            }
        },
        refresh: function() {
            var prop;
            for (prop in this.config) {
                this.refireEvent(prop);
            }
        },
        fireQueue: function() {
            var i, queueItem, key, value, property;
            this.queueInProgress = true;
            for (i = 0; i < this.eventQueue.length; i++) {
                queueItem = this.eventQueue[i];
                if (queueItem) {
                    key = queueItem[0];
                    value = queueItem[1];
                    property = this.config[key];
                    property.value = value;
                    this.fireEvent(key, value);
                }
            }
            this.queueInProgress = false;
            this.eventQueue = [];
        },
        subscribeToConfigEvent: function(key, handler, obj, override) {
            var property = this.config[key.toLowerCase()];
            if (property && property.event) {
                if (!Config.alreadySubscribed(property.event, handler, obj)) {
                    property.event.subscribe(handler, obj, override);
                }
                return true;
            } else {
                return false;
            }
        },
        unsubscribeFromConfigEvent: function(key, handler, obj) {
            var property = this.config[key.toLowerCase()];
            if (property && property.event) {
                return property.event.unsubscribe(handler, obj);
            } else {
                return false;
            }
        },
        toString: function() {
            var output = "Config";
            if (this.owner) {
                output += " [" + this.owner.toString() + "]";
            }
            return output;
        },
        outputEventQueue: function() {
            var output = "",
            queueItem, q, nQueue = this.eventQueue.length;
            for (q = 0; q < nQueue; q++) {
                queueItem = this.eventQueue[q];
                if (queueItem) {
                    output += queueItem[0] + "=" + queueItem[1] + ", ";
                }
            }
            return output;
        },
        destroy: function() {
            var oConfig = this.config,
            sProperty, oProperty;
            for (sProperty in oConfig) {
                if (Lang.hasOwnProperty(oConfig, sProperty)) {
                    oProperty = oConfig[sProperty];
                    oProperty.event.unsubscribeAll();
                    oProperty.event = null;
                }
            }
            this.configChangedEvent.unsubscribeAll();
            this.configChangedEvent = null;
            this.owner = null;
            this.config = null;
            this.initialConfig = null;
            this.eventQueue = null;
        }
    };
    Config.alreadySubscribed = function(evt, fn, obj) {
        var nSubscribers = evt.subscribers.length,
        subsc, i;
        if (nSubscribers > 0) {
            i = nSubscribers - 1;
            do {
                subsc = evt.subscribers[i];
                if (subsc && subsc.obj == obj && subsc.fn == fn) {
                    return true;
                }
            }
            while (i--);
        }
        return false;
    };
    YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
} ());
(function() {
    YAHOO.widget.Module = function(el, userConfig) {
        if (el) {
            this.init(el, userConfig);
        } else {}
    };
    var Dom = YAHOO.util.Dom,
    Config = YAHOO.util.Config,
    Event = YAHOO.util.Event,
    CustomEvent = YAHOO.util.CustomEvent,
    Module = YAHOO.widget.Module,
    m_oModuleTemplate, m_oHeaderTemplate, m_oBodyTemplate, m_oFooterTemplate, EVENT_TYPES = {
        "BEFORE_INIT": "beforeInit",
        "INIT": "init",
        "APPEND": "append",
        "BEFORE_RENDER": "beforeRender",
        "RENDER": "render",
        "CHANGE_HEADER": "changeHeader",
        "CHANGE_BODY": "changeBody",
        "CHANGE_FOOTER": "changeFooter",
        "CHANGE_CONTENT": "changeContent",
        "DESTORY": "destroy",
        "BEFORE_SHOW": "beforeShow",
        "SHOW": "show",
        "BEFORE_HIDE": "beforeHide",
        "HIDE": "hide"
    },
    DEFAULT_CONFIG = {
        "VISIBLE": {
            key: "visible",
            value: true,
            validator: YAHOO.lang.isBoolean
        },
        "EFFECT": {
            key: "effect",
            suppressEvent: true,
            supercedes: ["visible"]
        },
        "MONITOR_RESIZE": {
            key: "monitorresize",
            value: true
        }
    };
    Module.IMG_ROOT = null;
    Module.IMG_ROOT_SSL = null;
    Module.CSS_MODULE = "yui-module";
    Module.CSS_HEADER = "hd";
    Module.CSS_BODY = "bd";
    Module.CSS_FOOTER = "ft";
    Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;";
    Module.textResizeEvent = new CustomEvent("textResize");
    function createModuleTemplate() {
        if (!m_oModuleTemplate) {
            m_oModuleTemplate = document.createElement("div");
            m_oModuleTemplate.innerHTML = ("<div class=\"" + Module.CSS_HEADER + "\"></div>" + "<div class=\"" + Module.CSS_BODY + "\"></div><div class=\"" + Module.CSS_FOOTER + "\"></div>");
            m_oHeaderTemplate = m_oModuleTemplate.firstChild;
            m_oBodyTemplate = m_oHeaderTemplate.nextSibling;
            m_oFooterTemplate = m_oBodyTemplate.nextSibling;
        }
        return m_oModuleTemplate;
    }
    function createHeader() {
        if (!m_oHeaderTemplate) {
            createModuleTemplate();
        }
        return (m_oHeaderTemplate.cloneNode(false));
    }
    function createBody() {
        if (!m_oBodyTemplate) {
            createModuleTemplate();
        }
        return (m_oBodyTemplate.cloneNode(false));
    }
    function createFooter() {
        if (!m_oFooterTemplate) {
            createModuleTemplate();
        }
        return (m_oFooterTemplate.cloneNode(false));
    }
    Module.prototype = {
        constructor: Module,
        element: null,
        header: null,
        body: null,
        footer: null,
        id: null,
        imageRoot: Module.IMG_ROOT,
        initEvents: function() {
            var SIGNATURE = CustomEvent.LIST;
            this.beforeInitEvent = this.createEvent(EVENT_TYPES.BEFORE_INIT);
            this.beforeInitEvent.signature = SIGNATURE;
            this.initEvent = this.createEvent(EVENT_TYPES.INIT);
            this.initEvent.signature = SIGNATURE;
            this.appendEvent = this.createEvent(EVENT_TYPES.APPEND);
            this.appendEvent.signature = SIGNATURE;
            this.beforeRenderEvent = this.createEvent(EVENT_TYPES.BEFORE_RENDER);
            this.beforeRenderEvent.signature = SIGNATURE;
            this.renderEvent = this.createEvent(EVENT_TYPES.RENDER);
            this.renderEvent.signature = SIGNATURE;
            this.changeHeaderEvent = this.createEvent(EVENT_TYPES.CHANGE_HEADER);
            this.changeHeaderEvent.signature = SIGNATURE;
            this.changeBodyEvent = this.createEvent(EVENT_TYPES.CHANGE_BODY);
            this.changeBodyEvent.signature = SIGNATURE;
            this.changeFooterEvent = this.createEvent(EVENT_TYPES.CHANGE_FOOTER);
            this.changeFooterEvent.signature = SIGNATURE;
            this.changeContentEvent = this.createEvent(EVENT_TYPES.CHANGE_CONTENT);
            this.changeContentEvent.signature = SIGNATURE;
            this.destroyEvent = this.createEvent(EVENT_TYPES.DESTORY);
            this.destroyEvent.signature = SIGNATURE;
            this.beforeShowEvent = this.createEvent(EVENT_TYPES.BEFORE_SHOW);
            this.beforeShowEvent.signature = SIGNATURE;
            this.showEvent = this.createEvent(EVENT_TYPES.SHOW);
            this.showEvent.signature = SIGNATURE;
            this.beforeHideEvent = this.createEvent(EVENT_TYPES.BEFORE_HIDE);
            this.beforeHideEvent.signature = SIGNATURE;
            this.hideEvent = this.createEvent(EVENT_TYPES.HIDE);
            this.hideEvent.signature = SIGNATURE;
        },
        platform: function() {
            var ua = navigator.userAgent.toLowerCase();
            if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) {
                return "windows";
            } else if (ua.indexOf("macintosh") != -1) {
                return "mac";
            } else {
                return false;
            }
        } (),
        browser: function() {
            var ua = navigator.userAgent.toLowerCase();
            if (ua.indexOf('opera') != -1) {
                return 'opera';
            } else if (ua.indexOf('msie 7') != -1) {
                return 'ie7';
            } else if (ua.indexOf('msie') != -1) {
                return 'ie';
            } else if (ua.indexOf('safari') != -1) {
                return 'safari';
            } else if (ua.indexOf('gecko') != -1) {
                return 'gecko';
            } else {
                return false;
            }
        } (),
        isSecure: function() {
            if (window.location.href.toLowerCase().indexOf("https") === 0) {
                return true;
            } else {
                return false;
            }
        } (),
        initDefaultConfig: function() {
            this.cfg.addProperty(DEFAULT_CONFIG.VISIBLE.key, {
                handler: this.configVisible,
                value: DEFAULT_CONFIG.VISIBLE.value,
                validator: DEFAULT_CONFIG.VISIBLE.validator
            });
            this.cfg.addProperty(DEFAULT_CONFIG.EFFECT.key, {
                suppressEvent: DEFAULT_CONFIG.EFFECT.suppressEvent,
                supercedes: DEFAULT_CONFIG.EFFECT.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.MONITOR_RESIZE.key, {
                handler: this.configMonitorResize,
                value: DEFAULT_CONFIG.MONITOR_RESIZE.value
            });
        },
        init: function(el, userConfig) {
            var elId, i, child;
            this.initEvents();
            this.beforeInitEvent.fire(Module);
            this.cfg = new Config(this);
            if (this.isSecure) {
                this.imageRoot = Module.IMG_ROOT_SSL;
            }
            if (typeof el == "string") {
                elId = el;
                el = document.getElementById(el);
                if (!el) {
                    el = (createModuleTemplate()).cloneNode(false);
                    el.id = elId;
                }
            }
            this.element = el;
            if (el.id) {
                this.id = el.id;
            }
            child = this.element.firstChild;
            if (child) {
                do {
                    switch (child.className) {
                    case Module.CSS_HEADER:
                        this.header = child;
                        break;
                    case Module.CSS_BODY:
                        this.body = child;
                        break;
                    case Module.CSS_FOOTER:
                        this.footer = child;
                        break;
                    }
                } while ((child = child.nextSibling));
            }
            this.initDefaultConfig();
            Dom.addClass(this.element, Module.CSS_MODULE);
            if (userConfig) {
                this.cfg.applyConfig(userConfig, true);
            }
            if (!Config.alreadySubscribed(this.renderEvent, this.cfg.fireQueue, this.cfg)) {
                this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
            }
            this.initEvent.fire(Module);
        },
        initResizeMonitor: function() {
            var oDoc, oIFrame, sHTML;
            function fireTextResize() {
                Module.textResizeEvent.fire();
            }
            if (!YAHOO.env.ua.opera) {
                oIFrame = Dom.get("_yuiResizeMonitor");
                if (!oIFrame) {
                    oIFrame = document.createElement("iframe");
                    if (this.isSecure && Module.RESIZE_MONITOR_SECURE_URL && YAHOO.env.ua.ie) {
                        oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
                    }
                    if (YAHOO.env.ua.gecko) {
                        sHTML = "<html><head><script " + "type=\"text/javascript\">" + "window.onresize=function(){window.parent." + "YAHOO.widget.Module.textResizeEvent." + "fire();};window.parent.YAHOO.widget.Module." + "textResizeEvent.fire();</script></head>" + "<body></body></html>";
                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
                    }
                    oIFrame.id = "_yuiResizeMonitor";
                    oIFrame.style.position = "absolute";
                    oIFrame.style.visibility = "hidden";
                    document.body.appendChild(oIFrame);
                    oIFrame.style.width = "10em";
                    oIFrame.style.height = "10em";
                    oIFrame.style.top = ( - 1 * oIFrame.offsetHeight) + "px";
                    oIFrame.style.left = ( - 1 * oIFrame.offsetWidth) + "px";
                    oIFrame.style.borderWidth = "0";
                    oIFrame.style.visibility = "visible";
                    if (YAHOO.env.ua.webkit) {
                        oDoc = oIFrame.contentWindow.document;
                        oDoc.open();
                        oDoc.close();
                    }
                }
                if (oIFrame && oIFrame.contentWindow) {
                    Module.textResizeEvent.subscribe(this.onDomResize, this, true);
                    if (!Module.textResizeInitialized) {
                        if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
                            Event.on(oIFrame, "resize", fireTextResize);
                        }
                        Module.textResizeInitialized = true;
                    }
                    this.resizeMonitor = oIFrame;
                }
            }
        },
        onDomResize: function(e, obj) {
            var nLeft = -1 * this.resizeMonitor.offsetWidth,
            nTop = -1 * this.resizeMonitor.offsetHeight;
            this.resizeMonitor.style.top = nTop + "px";
            this.resizeMonitor.style.left = nLeft + "px";
        },
        setHeader: function(headerContent) {
            var oHeader = this.header || (this.header = createHeader());
            if (typeof headerContent == "string") {
                oHeader.innerHTML = headerContent;
            } else {
                oHeader.innerHTML = "";
                oHeader.appendChild(headerContent);
            }
            this.changeHeaderEvent.fire(headerContent);
            this.changeContentEvent.fire();
        },
        appendToHeader: function(element) {
            var oHeader = this.header || (this.header = createHeader());
            oHeader.appendChild(element);
            this.changeHeaderEvent.fire(element);
            this.changeContentEvent.fire();
        },
        setBody: function(bodyContent) {
            var oBody = this.body || (this.body = createBody());
            if (typeof bodyContent == "string") {
                oBody.innerHTML = bodyContent;
            } else {
                oBody.innerHTML = "";
                oBody.appendChild(bodyContent);
            }
            this.changeBodyEvent.fire(bodyContent);
            this.changeContentEvent.fire();
        },
        appendToBody: function(element) {
            var oBody = this.body || (this.body = createBody());
            oBody.appendChild(element);
            this.changeBodyEvent.fire(element);
            this.changeContentEvent.fire();
        },
        setFooter: function(footerContent) {
            var oFooter = this.footer || (this.footer = createFooter());
            if (typeof footerContent == "string") {
                oFooter.innerHTML = footerContent;
            } else {
                oFooter.innerHTML = "";
                oFooter.appendChild(footerContent);
            }
            this.changeFooterEvent.fire(footerContent);
            this.changeContentEvent.fire();
        },
        appendToFooter: function(element) {
            var oFooter = this.footer || (this.footer = createFooter());
            oFooter.appendChild(element);
            this.changeFooterEvent.fire(element);
            this.changeContentEvent.fire();
        },
        render: function(appendToNode, moduleElement) {
            var me = this,
            firstChild;
            function appendTo(element) {
                if (typeof element == "string") {
                    element = document.getElementById(element);
                }
                if (element) {
                    element.appendChild(me.element);
                    me.appendEvent.fire();
                }
            }
            this.beforeRenderEvent.fire();
            if (!moduleElement) {
                moduleElement = this.element;
            }
            if (appendToNode) {
                appendTo(appendToNode);
            } else {
                if (!Dom.inDocument(this.element)) {
                    return false;
                }
            }
            if (this.header && !Dom.inDocument(this.header)) {
                firstChild = moduleElement.firstChild;
                if (firstChild) {
                    moduleElement.insertBefore(this.header, firstChild);
                } else {
                    moduleElement.appendChild(this.header);
                }
            }
            if (this.body && !Dom.inDocument(this.body)) {
                if (this.footer && Dom.isAncestor(this.moduleElement, this.footer)) {
                    moduleElement.insertBefore(this.body, this.footer);
                } else {
                    moduleElement.appendChild(this.body);
                }
            }
            if (this.footer && !Dom.inDocument(this.footer)) {
                moduleElement.appendChild(this.footer);
            }
            this.renderEvent.fire();
            return true;
        },
        destroy: function() {
            var parent, e;
            if (this.element) {
                Event.purgeElement(this.element, true);
                parent = this.element.parentNode;
            }
            if (parent) {
                parent.removeChild(this.element);
            }
            this.element = null;
            this.header = null;
            this.body = null;
            this.footer = null;
            Module.textResizeEvent.unsubscribe(this.onDomResize, this);
            this.cfg.destroy();
            this.cfg = null;
            this.destroyEvent.fire();
            for (e in this) {
                if (e instanceof CustomEvent) {
                    e.unsubscribeAll();
                }
            }
        },
        show: function() {
            this.cfg.setProperty("visible", true);
        },
        hide: function() {
            this.cfg.setProperty("visible", false);
        },
        configVisible: function(type, args, obj) {
            var visible = args[0];
            if (visible) {
                this.beforeShowEvent.fire();
                Dom.setStyle(this.element, "display", "block");
                this.showEvent.fire();
            } else {
                this.beforeHideEvent.fire();
                Dom.setStyle(this.element, "display", "none");
                this.hideEvent.fire();
            }
        },
        configMonitorResize: function(type, args, obj) {
            var monitor = args[0];
            if (monitor) {
                this.initResizeMonitor();
            } else {
                Module.textResizeEvent.unsubscribe(this.onDomResize, this, true);
                this.resizeMonitor = null;
            }
        },
        toString: function() {
            return "Module " + this.id;
        }
    };
    YAHOO.lang.augmentProto(Module, YAHOO.util.EventProvider);
} ());
(function() {
    YAHOO.widget.Overlay = function(el, userConfig) {
        YAHOO.widget.Overlay.superclass.constructor.call(this, el, userConfig);
    };
    var Lang = YAHOO.lang,
    CustomEvent = YAHOO.util.CustomEvent,
    Module = YAHOO.widget.Module,
    Event = YAHOO.util.Event,
    Dom = YAHOO.util.Dom,
    Config = YAHOO.util.Config,
    Overlay = YAHOO.widget.Overlay,
    m_oIFrameTemplate, EVENT_TYPES = {
        "BEFORE_MOVE": "beforeMove",
        "MOVE": "move"
    },
    DEFAULT_CONFIG = {
        "X": {
            key: "x",
            validator: Lang.isNumber,
            suppressEvent: true,
            supercedes: ["iframe"]
        },
        "Y": {
            key: "y",
            validator: Lang.isNumber,
            suppressEvent: true,
            supercedes: ["iframe"]
        },
        "XY": {
            key: "xy",
            suppressEvent: true,
            supercedes: ["iframe"]
        },
        "CONTEXT": {
            key: "context",
            suppressEvent: true,
            supercedes: ["iframe"]
        },
        "FIXED_CENTER": {
            key: "fixedcenter",
            value: false,
            validator: Lang.isBoolean,
            supercedes: ["iframe", "visible"]
        },
        "WIDTH": {
            key: "width",
            suppressEvent: true,
            supercedes: ["context", "fixedcenter", "iframe"]
        },
        "HEIGHT": {
            key: "height",
            suppressEvent: true,
            supercedes: ["context", "fixedcenter", "iframe"]
        },
        "ZINDEX": {
            key: "zindex",
            value: null
        },
        "CONSTRAIN_TO_VIEWPORT": {
            key: "constraintoviewport",
            value: false,
            validator: Lang.isBoolean,
            supercedes: ["iframe", "x", "y", "xy"]
        },
        "IFRAME": {
            key: "iframe",
            value: (YAHOO.env.ua.ie == 6 ? true: false),
            validator: Lang.isBoolean,
            supercedes: ["zindex"]
        }
    };
    Overlay.IFRAME_SRC = "javascript:false;";
    Overlay.IFRAME_OFFSET = 3;
    Overlay.TOP_LEFT = "tl";
    Overlay.TOP_RIGHT = "tr";
    Overlay.BOTTOM_LEFT = "bl";
    Overlay.BOTTOM_RIGHT = "br";
    Overlay.CSS_OVERLAY = "yui-overlay";
    Overlay.windowScrollEvent = new CustomEvent("windowScroll");
    Overlay.windowResizeEvent = new CustomEvent("windowResize");
    Overlay.windowScrollHandler = function(e) {
        if (YAHOO.env.ua.ie) {
            if (!window.scrollEnd) {
                window.scrollEnd = -1;
            }
            clearTimeout(window.scrollEnd);
            window.scrollEnd = setTimeout(function() {
                Overlay.windowScrollEvent.fire();
            },
            1);
        } else {
            Overlay.windowScrollEvent.fire();
        }
    };
    Overlay.windowResizeHandler = function(e) {
        if (YAHOO.env.ua.ie) {
            if (!window.resizeEnd) {
                window.resizeEnd = -1;
            }
            clearTimeout(window.resizeEnd);
            window.resizeEnd = setTimeout(function() {
                Overlay.windowResizeEvent.fire();
            },
            100);
        } else {
            Overlay.windowResizeEvent.fire();
        }
    };
    Overlay._initialized = null;
    if (Overlay._initialized === null) {
        Event.on(window, "scroll", Overlay.windowScrollHandler);
        Event.on(window, "resize", Overlay.windowResizeHandler);
        Overlay._initialized = true;
    }
    YAHOO.extend(Overlay, Module, {
        init: function(el, userConfig) {
            Overlay.superclass.init.call(this, el);
            this.beforeInitEvent.fire(Overlay);
            Dom.addClass(this.element, Overlay.CSS_OVERLAY);
            if (userConfig) {
                this.cfg.applyConfig(userConfig, true);
            }
            if (this.platform == "mac" && YAHOO.env.ua.gecko) {
                if (!Config.alreadySubscribed(this.showEvent, this.showMacGeckoScrollbars, this)) {
                    this.showEvent.subscribe(this.showMacGeckoScrollbars, this, true);
                }
                if (!Config.alreadySubscribed(this.hideEvent, this.hideMacGeckoScrollbars, this)) {
                    this.hideEvent.subscribe(this.hideMacGeckoScrollbars, this, true);
                }
            }
            this.initEvent.fire(Overlay);
        },
        initEvents: function() {
            Overlay.superclass.initEvents.call(this);
            var SIGNATURE = CustomEvent.LIST;
            this.beforeMoveEvent = this.createEvent(EVENT_TYPES.BEFORE_MOVE);
            this.beforeMoveEvent.signature = SIGNATURE;
            this.moveEvent = this.createEvent(EVENT_TYPES.MOVE);
            this.moveEvent.signature = SIGNATURE;
        },
        initDefaultConfig: function() {
            Overlay.superclass.initDefaultConfig.call(this);
            this.cfg.addProperty(DEFAULT_CONFIG.X.key, {
                handler: this.configX,
                validator: DEFAULT_CONFIG.X.validator,
                suppressEvent: DEFAULT_CONFIG.X.suppressEvent,
                supercedes: DEFAULT_CONFIG.X.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
                handler: this.configY,
                validator: DEFAULT_CONFIG.Y.validator,
                suppressEvent: DEFAULT_CONFIG.Y.suppressEvent,
                supercedes: DEFAULT_CONFIG.Y.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.XY.key, {
                handler: this.configXY,
                suppressEvent: DEFAULT_CONFIG.XY.suppressEvent,
                supercedes: DEFAULT_CONFIG.XY.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.CONTEXT.key, {
                handler: this.configContext,
                suppressEvent: DEFAULT_CONFIG.CONTEXT.suppressEvent,
                supercedes: DEFAULT_CONFIG.CONTEXT.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.FIXED_CENTER.key, {
                handler: this.configFixedCenter,
                value: DEFAULT_CONFIG.FIXED_CENTER.value,
                validator: DEFAULT_CONFIG.FIXED_CENTER.validator,
                supercedes: DEFAULT_CONFIG.FIXED_CENTER.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.WIDTH.key, {
                handler: this.configWidth,
                suppressEvent: DEFAULT_CONFIG.WIDTH.suppressEvent,
                supercedes: DEFAULT_CONFIG.WIDTH.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.HEIGHT.key, {
                handler: this.configHeight,
                suppressEvent: DEFAULT_CONFIG.HEIGHT.suppressEvent,
                supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.ZINDEX.key, {
                handler: this.configzIndex,
                value: DEFAULT_CONFIG.ZINDEX.value
            });
            this.cfg.addProperty(DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, {
                handler: this.configConstrainToViewport,
                value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value,
                validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator,
                supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
            });
            this.cfg.addProperty(DEFAULT_CONFIG.IFRAME.key, {
                handler: this.configIframe,
                value: DEFAULT_CONFIG.IFRAME.value,
                validator: DEFAULT_CONFIG.IFRAME.validator,
                supercedes: DEFAULT_CONFIG.IFRAME.supercedes
            });
        },
        moveTo: function(x, y) {
            this.cfg.setProperty("xy", [x, y]);
        },
        hideMacGeckoScrollbars: function() {
            Dom.removeClass(this.element, "show-scrollbars");
            Dom.addClass(this.element, "hide-scrollbars");
        },
        showMacGeckoScrollbars: function() {
            Dom.removeClass(this.element, "hide-scrollbars");
            Dom.addClass(this.element, "show-scrollbars");
        },
        configVisible: function(type, args, obj) {
            var visible = args[0],
            currentVis = Dom.getStyle(this.element, "visibility"),
            effect = this.cfg.getProperty("effect"),
            effectInstances = [],
            isMacGecko = (this.platform == "mac" && YAHOO.env.ua.gecko),
            alreadySubscribed = Config.alreadySubscribed,
            eff,
            ei,
            e,
            i,
            j,
            k,
            h,
            nEffects,
            nEffectInstances;
            if (currentVis == "inherit") {
                e = this.element.parentNode;
                while (e.nodeType != 9 && e.nodeType != 11) {
                    currentVis = Dom.getStyle(e, "visibility");
                    if (currentVis != "inherit") {
                        break;
                    }
                    e = e.parentNode;
                }
                if (currentVis == "inherit") {
                    currentVis = "visible";
                }
            }
            if (effect) {
                if (effect instanceof Array) {
                    nEffects = effect.length;
                    for (i = 0; i < nEffects; i++) {
                        eff = effect[i];
                        effectInstances[effectInstances.length] = eff.effect(this, eff.duration);
                    }
                } else {
                    effectInstances[effectInstances.length] = effect.effect(this, effect.duration);
                }
            }
            if (visible) {
                if (isMacGecko) {
                    this.showMacGeckoScrollbars();
                }
                if (effect) {
                    if (visible) {
                        if (currentVis != "visible" || currentVis === "") {
                            this.beforeShowEvent.fire();
                            nEffectInstances = effectInstances.length;
                            for (j = 0; j < nEffectInstances; j++) {
                                ei = effectInstances[j];
                                if (j === 0 && !alreadySubscribed(ei.animateInCompleteEvent, this.showEvent.fire, this.showEvent)) {
                                    ei.animateInCompleteEvent.subscribe(this.showEvent.fire, this.showEvent, true);
                                }
                                ei.animateIn();
                            }
                        }
                    }
                } else {
                    if (currentVis != "visible" || currentVis === "") {
                        this.beforeShowEvent.fire();
                        Dom.setStyle(this.element, "visibility", "visible");
                        this.cfg.refireEvent("iframe");
                        this.showEvent.fire();
                    }
                }
            } else {
                if (isMacGecko) {
                    this.hideMacGeckoScrollbars();
                }
                if (effect) {
                    if (currentVis == "visible") {
                        this.beforeHideEvent.fire();
                        nEffectInstances = effectInstances.length;
                        for (k = 0; k < nEffectInstances; k++) {
                            h = effectInstances[k];
                            if (k === 0 && !alreadySubscribed(h.animateOutCompleteEvent, this.hideEvent.fire, this.hideEvent)) {
                                h.animateOutCompleteEvent.subscribe(this.hideEvent.fire, this.hideEvent, true);
                            }
                            h.animateOut();
                        }
                    } else if (currentVis === "") {
                        Dom.setStyle(this.element, "visibility", "hidden");
                    }
                } else {
                    if (currentVis == "visible" || currentVis === "") {
                        this.beforeHideEvent.fire();
                        Dom.setStyle(this.element, "visibility", "hidden");
                        this.hideEvent.fire();
                    }
                }
            }
        },
        doCenterOnDOMEvent: function() {
            if (this.cfg.getProperty("visible")) {
                this.center();
            }
        },
        configFixedCenter: function(type, args, obj) {
            var val = args[0],
            alreadySubscribed = Config.alreadySubscribed,
            windowResizeEvent = Overlay.windowResizeEvent,
            windowScrollEvent = Overlay.windowScrollEvent;
            if (val) {
                this.center();
                if (!alreadySubscribed(this.beforeShowEvent, this.center, this)) {
                    this.beforeShowEvent.subscribe(this.center);
                }
                if (!alreadySubscribed(windowResizeEvent, this.doCenterOnDOMEvent, this)) {
                    windowResizeEvent.subscribe(this.doCenterOnDOMEvent, this, true);
                }
                if (!alreadySubscribed(windowScrollEvent, this.doCenterOnDOMEvent, this)) {
                    windowScrollEvent.subscribe(this.doCenterOnDOMEvent, this, true);
                }
            } else {
                this.beforeShowEvent.unsubscribe(this.center);
                windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
                windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
            }
        },
        configHeight: function(type, args, obj) {
            var height = args[0],
            el = this.element;
            Dom.setStyle(el, "height", height);
            this.cfg.refireEvent("iframe");
        },
        configWidth: function(type, args, obj) {
            var width = args[0],
            el = this.element;
            Dom.setStyle(el, "width", width);
            this.cfg.refireEvent("iframe");
        },
        configzIndex: function(type, args, obj) {
            var zIndex = args[0],
            el = this.element;
            if (!zIndex) {
                zIndex = Dom.getStyle(el, "zIndex");
                if (!zIndex || isNaN(zIndex)) {
                    zIndex = 0;
                }
            }
            if (this.iframe) {
                if (zIndex <= 0) {
                    zIndex = 1;
                }
                Dom.setStyle(this.iframe, "zIndex", (zIndex - 1));
            }
            Dom.setStyle(el, "zIndex", zIndex);
            this.cfg.setProperty("zIndex", zIndex, true);
        },
        configXY: function(type, args, obj) {
            var pos = args[0],
            x = pos[0],
            y = pos[1];
            this.cfg.setProperty("x", x);
            this.cfg.setProperty("y", y);
            this.beforeMoveEvent.fire([x, y]);
            x = this.cfg.getProperty("x");
            y = this.cfg.getProperty("y");
            this.cfg.refireEvent("iframe");
            this.moveEvent.fire([x, y]);
        },
        configX: function(type, args, obj) {
            var x = args[0],
            y = this.cfg.getProperty("y");
            this.cfg.setProperty("x", x, true);
            this.cfg.setProperty("y", y, true);
            this.beforeMoveEvent.fire([x, y]);
            x = this.cfg.getProperty("x");
            y = this.cfg.getProperty("y");
            Dom.setX(this.element, x, true);
            this.cfg.setProperty("xy", [x, y], true);
            this.cfg.refireEvent("iframe");
            this.moveEvent.fire([x, y]);
        },
        configY: function(type, args, obj) {
            var x = this.cfg.getProperty("x"),
            y = args[0];
            this.cfg.setProperty("x", x, true);
            this.cfg.setProperty("y", y, true);
            this.beforeMoveEvent.fire([x, y]);
            x = this.cfg.getProperty("x");
            y = this.cfg.getProperty("y");
            Dom.setY(this.element, y, true);
            this.cfg.setProperty("xy", [x, y], true);
            this.cfg.refireEvent("iframe");
            this.moveEvent.fire([x, y]);
        },
        showIframe: function() {
            var oIFrame = this.iframe,
            oParentNode;
            if (oIFrame) {
                oParentNode = this.element.parentNode;
                if (oParentNode != oIFrame.parentNode) {
                    oParentNode.appendChild(oIFrame);
                }
                oIFrame.style.display = "block";
            }
        },
        hideIframe: function() {
            if (this.iframe) {
                this.iframe.style.display = "none";
            }
        },
        syncIframe: function() {
            var oIFrame = this.iframe,
            oElement = this.element,
            nOffset = Overlay.IFRAME_OFFSET,
            nDimensionOffset = (nOffset * 2),
            aXY;
            if (oIFrame) {
                oIFrame.style.width = (oElement.offsetWidth + nDimensionOffset + "px");
                oIFrame.style.height = (oElement.offsetHeight + nDimensionOffset + "px");
                aXY = this.cfg.getProperty("xy");
                if (!Lang.isArray(aXY) || (isNaN(aXY[0]) || isNaN(aXY[1]))) {
                    this.syncPosition();
                    aXY = this.cfg.getProperty("xy");
                }
                Dom.setXY(oIFrame, [(aXY[0] - nOffset), (aXY[1] - nOffset)]);
            }
        },
        configIframe: function(type, args, obj) {
            var bIFrame = args[0];
            function createIFrame() {
                var oIFrame = this.iframe,
                oElement = this.element,
                oParent, aXY;
                if (!oIFrame) {
                    if (!m_oIFrameTemplate) {
                        m_oIFrameTemplate = document.createElement("iframe");
                        if (this.isSecure) {
                            m_oIFrameTemplate.src = Overlay.IFRAME_SRC;
                        }
                        if (YAHOO.env.ua.ie) {
                            m_oIFrameTemplate.style.filter = "alpha(opacity=0)";
                            m_oIFrameTemplate.frameBorder = 0;
                        }
                        else {
                            m_oIFrameTemplate.style.opacity = "0";
                        }
                        m_oIFrameTemplate.style.position = "absolute";
                        m_oIFrameTemplate.style.border = "none";
                        m_oIFrameTemplate.style.margin = "0";
                        m_oIFrameTemplate.style.padding = "0";
                        m_oIFrameTemplate.style.display = "none";
                    }
                    oIFrame = m_oIFrameTemplate.cloneNode(false);
                    oParent = oElement.parentNode;
                    if (oParent) {
                        oParent.appendChild(oIFrame);
                    } else {
                        document.body.appendChild(oIFrame);
                    }
                    this.iframe = oIFrame;
                }
                this.showIframe();
                this.syncIframe();
                if (!this._hasIframeEventListeners) {
                    this.showEvent.subscribe(this.showIframe);
                    this.hideEvent.subscribe(this.hideIframe);
                    this.changeContentEvent.subscribe(this.syncIframe);
                    this._hasIframeEventListeners = true;
                }
            }
            function onBeforeShow() {
                createIFrame.call(this);
                this.beforeShowEvent.unsubscribe(onBeforeShow);
                this._iframeDeferred = false;
            }
            if (bIFrame) {
                if (this.cfg.getProperty("visible")) {
                    createIFrame.call(this);
                }
                else {
                    if (!this._iframeDeferred) {
                        this.beforeShowEvent.subscribe(onBeforeShow);
                        this._iframeDeferred = true;
                    }
                }
            } else {
                this.hideIframe();
                if (this._hasIframeEventListeners) {
                    this.showEvent.unsubscribe(this.showIframe);
                    this.hideEvent.unsubscribe(this.hideIframe);
                    this.changeContentEvent.unsubscribe(this.syncIframe);
                    this._hasIframeEventListeners = false;
                }
            }
        },
        configConstrainToViewport: function(type, args, obj) {
            var val = args[0];
            if (val) {
                if (!Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
                    this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
                }
            } else {
                this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
            }
        },
        configContext: function(type, args, obj) {
            var contextArgs = args[0],
            contextEl,
            elementMagnetCorner,
            contextMagnetCorner;
            if (contextArgs) {
                contextEl = contextArgs[0];
                elementMagnetCorner = contextArgs[1];
                contextMagnetCorner = contextArgs[2];
                if (contextEl) {
                    if (typeof contextEl == "string") {
                        this.cfg.setProperty("context", [document.getElementById(contextEl), elementMagnetCorner, contextMagnetCorner], true);
                    }
                    if (elementMagnetCorner && contextMagnetCorner) {
                        this.align(elementMagnetCorner, contextMagnetCorner);
                    }
                }
            }
        },
        align: function(elementAlign, contextAlign) {
            var contextArgs = this.cfg.getProperty("context"),
            me = this,
            context,
            element,
            contextRegion;
            function doAlign(v, h) {
                switch (elementAlign) {
                case Overlay.TOP_LEFT:
                    me.moveTo(h, v);
                    break;
                case Overlay.TOP_RIGHT:
                    me.moveTo((h - element.offsetWidth), v);
                    break;
                case Overlay.BOTTOM_LEFT:
                    me.moveTo(h, (v - element.offsetHeight));
                    break;
                case Overlay.BOTTOM_RIGHT:
                    me.moveTo((h - element.offsetWidth), (v - element.offsetHeight));
                    break;
                }
            }
            if (contextArgs) {
                context = contextArgs[0];
                element = this.element;
                me = this;
                if (!elementAlign) {
                    elementAlign = contextArgs[1];
                }
                if (!contextAlign) {
                    contextAlign = contextArgs[2];
                }
                if (element && context) {
                    contextRegion = Dom.getRegion(context);
                    switch (contextAlign) {
                    case Overlay.TOP_LEFT:
                        doAlign(contextRegion.top, contextRegion.left);
                        break;
                    case Overlay.TOP_RIGHT:
                        doAlign(contextRegion.top, contextRegion.right);
                        break;
                    case Overlay.BOTTOM_LEFT:
                        doAlign(contextRegion.bottom, contextRegion.left);
                        break;
                    case Overlay.BOTTOM_RIGHT:
                        doAlign(contextRegion.bottom, contextRegion.right);
                        break;
                    }
                }
            }
        },
        enforceConstraints: function(type, args, obj) {
            var pos = args[0],
            x = pos[0],
            y = pos[1],
            offsetHeight = this.element.offsetHeight,
            offsetWidth = this.element.offsetWidth,
            viewPortWidth = Dom.getViewportWidth(),
            viewPortHeight = Dom.getViewportHeight(),
            scrollX = Dom.getDocumentScrollLeft(),
            scrollY = Dom.getDocumentScrollTop(),
            topConstraint = scrollY + 10,
            leftConstraint = scrollX + 10,
            bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10,
            rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
            if (x < leftConstraint) {
                x = leftConstraint;
            } else if (x > rightConstraint) {
                x = rightConstraint;
            }
            if (y < topConstraint) {
                y = topConstraint;
            } else if (y > bottomConstraint) {
                y = bottomConstraint;
            }
            this.cfg.setProperty("x", x, true);
            this.cfg.setProperty("y", y, true);
            this.cfg.setProperty("xy", [x, y], true);
        },
        center: function() {
            var scrollX = Dom.getDocumentScrollLeft(),
            scrollY = Dom.getDocumentScrollTop(),
            viewPortWidth = Dom.getClientWidth(),
            viewPortHeight = Dom.getClientHeight(),
            elementWidth = this.element.offsetWidth,
            elementHeight = this.element.offsetHeight,
            x = (viewPortWidth / 2) - (elementWidth / 2) + scrollX,
            y = (viewPortHeight / 2) - (elementHeight / 2) + scrollY;
            this.cfg.setProperty("xy", [parseInt(x, 10), parseInt(y, 10)]);
            this.cfg.refireEvent("iframe");
        },
        syncPosition: function() {
            var pos = Dom.getXY(this.element);
            this.cfg.setProperty("x", pos[0], true);
            this.cfg.setProperty("y", pos[1], true);
            this.cfg.setProperty("xy", pos, true);
        },
        onDomResize: function(e, obj) {
            var me = this;
            Overlay.superclass.onDomResize.call(this, e, obj);
            setTimeout(function() {
                me.syncPosition();
                me.cfg.refireEvent("iframe");
                me.cfg.refireEvent("context");
            },
            0);
        },
        bringToTop: function() {
            var aOverlays = [],
            oElement = this.element;
            function compareZIndexDesc(p_oOverlay1, p_oOverlay2) {
                var sZIndex1 = Dom.getStyle(p_oOverlay1, "zIndex"),
                sZIndex2 = Dom.getStyle(p_oOverlay2, "zIndex"),
                nZIndex1 = (!sZIndex1 || isNaN(sZIndex1)) ? 0 : parseInt(sZIndex1, 10),
                nZIndex2 = (!sZIndex2 || isNaN(sZIndex2)) ? 0 : parseInt(sZIndex2, 10);
                if (nZIndex1 > nZIndex2) {
                    return - 1;
                } else if (nZIndex1 < nZIndex2) {
                    return 1;
                } else {
                    return 0;
                }
            }
            function isOverlayElement(p_oElement) {
                var oOverlay = Dom.hasClass(p_oElement, Overlay.CSS_OVERLAY),
                Panel = YAHOO.widget.Panel;
                if (oOverlay && !Dom.isAncestor(oElement, oOverlay)) {
                    if (Panel && Dom.hasClass(p_oElement, Panel.CSS_PANEL)) {
                        aOverlays[aOverlays.length] = p_oElement.parentNode;
                    }
                    else {
                        aOverlays[aOverlays.length] = p_oElement;
                    }
                }
            }
            Dom.getElementsBy(isOverlayElement, "DIV", document.body);
            aOverlays.sort(compareZIndexDesc);
            var oTopOverlay = aOverlays[0],
            nTopZIndex;
            if (oTopOverlay) {
                nTopZIndex = Dom.getStyle(oTopOverlay, "zIndex");
                if (!isNaN(nTopZIndex) && oTopOverlay != oElement) {
                    this.cfg.setProperty("zindex", (parseInt(nTopZIndex, 10) + 2));
                }
            }
        },
        destroy: function() {
            if (this.iframe) {
                this.iframe.parentNode.removeChild(this.iframe);
            }
            this.iframe = null;
            Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
            Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
            Overlay.superclass.destroy.call(this);
        },
        toString: function() {
            return "Overlay " + this.id;
        }
    });
} ());
(function() {
    YAHOO.widget.OverlayManager = function(userConfig) {
        this.init(userConfig);
    };
    var Overlay = YAHOO.widget.Overlay,
    Event = YAHOO.util.Event,
    Dom = YAHOO.util.Dom,
    Config = YAHOO.util.Config,
    CustomEvent = YAHOO.util.CustomEvent,
    OverlayManager = YAHOO.widget.OverlayManager;
    OverlayManager.CSS_FOCUSED = "focused";
    OverlayManager.prototype = {
        constructor: OverlayManager,
        overlays: null,
        initDefaultConfig: function() {
            this.cfg.addProperty("overlays", {
                suppressEvent: true
            });
            this.cfg.addProperty("focusevent", {
                value: "mousedown"
            });
        },
        init: function(userConfig) {
            this.cfg = new Config(this);
            this.initDefaultConfig();
            if (userConfig) {
                this.cfg.applyConfig(userConfig, true);
            }
            this.cfg.fireQueue();
            var activeOverlay = null;
            this.getActive = function() {
                return activeOverlay;
            };
            this.focus = function(overlay) {
                var o = this.find(overlay);
                if (o) {
                    if (activeOverlay != o) {
                        if (activeOverlay) {
                            activeOverlay.blur();
                        }
                        this.bringToTop(o);
                        activeOverlay = o;
                        Dom.addClass(activeOverlay.element, OverlayManager.CSS_FOCUSED);
                        o.focusEvent.fire();
                    }
                }
            };
            this.remove = function(overlay) {
                var o = this.find(overlay),
                originalZ;
                if (o) {
                    if (activeOverlay == o) {
                        activeOverlay = null;
                    }
                    originalZ = Dom.getStyle(o.element, "zIndex");
                    o.cfg.setProperty("zIndex", -1000, true);
                    this.overlays.sort(this.compareZIndexDesc);
                    this.overlays = this.overlays.slice(0, (this.overlays.length - 1));
                    o.hideEvent.unsubscribe(o.blur);
                    o.destroyEvent.unsubscribe(this._onOverlayDestroy, o);
                    if (o.element) {
                        Event.removeListener(o.element, this.cfg.getProperty("focusevent"), this._onOverlayElementFocus);
                    }
                    o.cfg.setProperty("zIndex", originalZ, true);
                    o.cfg.setProperty("manager", null);
                    o.focusEvent.unsubscribeAll();
                    o.blurEvent.unsubscribeAll();
                    o.focusEvent = null;
                    o.blurEvent = null;
                    o.focus = null;
                    o.blur = null;
                }
            };
            this.blurAll = function() {
                var nOverlays = this.overlays.length,
                i;
                if (nOverlays > 0) {
                    i = nOverlays - 1;
                    do {
                        this.overlays[i].blur();
                    }
                    while (i--);
                }
            };
            this._onOverlayBlur = function(p_sType, p_aArgs) {
                activeOverlay = null;
            };
            var overlays = this.cfg.getProperty("overlays");
            if (!this.overlays) {
                this.overlays = [];
            }
            if (overlays) {
                this.register(overlays);
                this.overlays.sort(this.compareZIndexDesc);
            }
        },
        _onOverlayElementFocus: function(p_oEvent) {
            var oTarget = Event.getTarget(p_oEvent),
            oClose = this.close;
            if (oClose && (oTarget == oClose || Dom.isAncestor(oClose, oTarget))) {
                this.blur();
            }
            else {
                this.focus();
            }
        },
        _onOverlayDestroy: function(p_sType, p_aArgs, p_oOverlay) {
            this.remove(p_oOverlay);
        },
        register: function(overlay) {
            var mgr = this,
            zIndex, regcount, i, nOverlays;
            if (overlay instanceof Overlay) {
                overlay.cfg.addProperty("manager", {
                    value: this
                });
                overlay.focusEvent = overlay.createEvent("focus");
                overlay.focusEvent.signature = CustomEvent.LIST;
                overlay.blurEvent = overlay.createEvent("blur");
                overlay.blurEvent.signature = CustomEvent.LIST;
                overlay.focus = function() {
                    mgr.focus(this);
                };
                overlay.blur = function() {
                    if (mgr.getActive() == this) {
                        Dom.removeClass(this.element, OverlayManager.CSS_FOCUSED);
                        this.blurEvent.fire();
                    }
                };
                overlay.blurEvent.subscribe(mgr._onOverlayBlur);
                overlay.hideEvent.subscribe(overlay.blur);
                overlay.destroyEvent.subscribe(this._onOverlayDestroy, overlay, this);
                Event.on(overlay.element, this.cfg.getProperty("focusevent"), this._onOverlayElementFocus, null, overlay);
                zIndex = Dom.getStyle(overlay.element, "zIndex");
                if (!isNaN(zIndex)) {
                    overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
                } else {
                    overlay.cfg.setProperty("zIndex", 0);
                }
                this.overlays.push(overlay);
                this.bringToTop(overlay);
                return true;
            } else if (overlay instanceof Array) {
                regcount = 0;
                nOverlays = overlay.length;
                for (i = 0; i < nOverlays; i++) {
                    if (this.register(overlay[i])) {
                        regcount++;
                    }
                }
                if (regcount > 0) {
                    return true;
                }
            } else {
                return false;
            }
        },
        bringToTop: function(p_oOverlay) {
            var oOverlay = this.find(p_oOverlay),
            nTopZIndex,
            oTopOverlay,
            aOverlays;
            if (oOverlay) {
                aOverlays = this.overlays;
                aOverlays.sort(this.compareZIndexDesc);
                oTopOverlay = aOverlays[0];
                if (oTopOverlay) {
                    nTopZIndex = Dom.getStyle(oTopOverlay.element, "zIndex");
                    if (!isNaN(nTopZIndex) && oTopOverlay != oOverlay) {
                        oOverlay.cfg.setProperty("zIndex", (parseInt(nTopZIndex, 10) + 2));
                    }
                    aOverlays.sort(this.compareZIndexDesc);
                }
            }
        },
        find: function(overlay) {
            var aOverlays = this.overlays,
            nOverlays = aOverlays.length,
            i;
            if (nOverlays > 0) {
                i = nOverlays - 1;
                if (overlay instanceof Overlay) {
                    do {
                        if (aOverlays[i] == overlay) {
                            return aOverlays[i];
                        }
                    }
                    while (i--);
                } else if (typeof overlay == "string") {
                    do {
                        if (aOverlays[i].id == overlay) {
                            return aOverlays[i];
                        }
                    }
                    while (i--);
                }
                return null;
            }
        },
        compareZIndexDesc: function(o1, o2) {
            var zIndex1 = o1.cfg.getProperty("zIndex"),
            zIndex2 = o2.cfg.getProperty("zIndex");
            if (zIndex1 > zIndex2) {
                return - 1;
            } else if (zIndex1 < zIndex2) {
                return 1;
            } else {
                return 0;
            }
        },
        showAll: function() {
            var aOverlays = this.overlays,
            nOverlays = aOverlays.length,
            i;
            if (nOverlays > 0) {
                i = nOverlays - 1;
                do {
                    aOverlays[i].show();
                }
                while (i--);
            }
        },
        hideAll: function() {
            var aOverlays = this.overlays,
            nOverlays = aOverlays.length,
            i;
            if (nOverlays > 0) {
                i = nOverlays - 1;
                do {
                    aOverlays[i].hide();
                }
                while (i--);
            }
        },
        toString: function() {
            return "OverlayManager";
        }
    };
} ());
(function() {
    YAHOO.widget.ContainerEffect = function(overlay, attrIn, attrOut, targetElement, animClass) {
        if (!animClass) {
            animClass = YAHOO.util.Anim;
        }
        this.overlay = overlay;
        this.attrIn = attrIn;
        this.attrOut = attrOut;
        this.targetElement = targetElement || overlay.element;
        this.animClass = animClass;
    };
    var Dom = YAHOO.util.Dom,
    CustomEvent = YAHOO.util.CustomEvent,
    Easing = YAHOO.util.Easing,
    ContainerEffect = YAHOO.widget.ContainerEffect;
    ContainerEffect.FADE = function(overlay, dur) {
        var fade = new ContainerEffect(overlay, {
            attributes: {
                opacity: {
                    from: 0,
                    to: 1
                }
            },
            duration: dur,
            method: Easing.easeIn
        },
        {
            attributes: {
                opacity: {
                    to: 0
                }
            },
            duration: dur,
            method: Easing.easeOut
        },
        overlay.element);
        fade.handleStartAnimateIn = function(type, args, obj) {
            Dom.addClass(obj.overlay.element, "hide-select");
            if (!obj.overlay.underlay) {
                obj.overlay.cfg.refireEvent("underlay");
            }
            if (obj.overlay.underlay) {
                obj.initialUnderlayOpacity = Dom.getStyle(obj.overlay.underlay, "opacity");
                obj.overlay.underlay.style.filter = null;
            }
            Dom.setStyle(obj.overlay.element, "visibility", "visible");
            Dom.setStyle(obj.overlay.element, "opacity", 0);
        };
        fade.handleCompleteAnimateIn = function(type, args, obj) {
            Dom.removeClass(obj.overlay.element, "hide-select");
            if (obj.overlay.element.style.filter) {
                obj.overlay.element.style.filter = null;
            }
            if (obj.overlay.underlay) {
                Dom.setStyle(obj.overlay.underlay, "opacity", obj.initialUnderlayOpacity);
            }
            obj.overlay.cfg.refireEvent("iframe");
            obj.animateInCompleteEvent.fire();
        };
        fade.handleStartAnimateOut = function(type, args, obj) {
            Dom.addClass(obj.overlay.element, "hide-select");
            if (obj.overlay.underlay) {
                obj.overlay.underlay.style.filter = null;
            }
        };
        fade.handleCompleteAnimateOut = function(type, args, obj) {
            Dom.removeClass(obj.overlay.element, "hide-select");
            if (obj.overlay.element.style.filter) {
                obj.overlay.element.style.filter = null;
            }
            Dom.setStyle(obj.overlay.element, "visibility", "hidden");
            Dom.setStyle(obj.overlay.element, "opacity", 1);
            obj.overlay.cfg.refireEvent("iframe");
            obj.animateOutCompleteEvent.fire();
        };
        fade.init();
        return fade;
    };
    ContainerEffect.SLIDE = function(overlay, dur) {
        var x = overlay.cfg.getProperty("x") || Dom.getX(overlay.element),
        y = overlay.cfg.getProperty("y") || Dom.getY(overlay.element),
        clientWidth = Dom.getClientWidth(),
        offsetWidth = overlay.element.offsetWidth,
        slide = new ContainerEffect(overlay, {
            attributes: {
                points: {
                    to: [x, y]
                }
            },
            duration: dur,
            method: Easing.easeIn
        },
        {
            attributes: {
                points: {
                    to: [(clientWidth + 25), y]
                }
            },
            duration: dur,
            method: Easing.easeOut
        },
        overlay.element, YAHOO.util.Motion);
        slide.handleStartAnimateIn = function(type, args, obj) {
            obj.overlay.element.style.left = (( - 25) - offsetWidth) + "px";
            obj.overlay.element.style.top = y + "px";
        };
        slide.handleTweenAnimateIn = function(type, args, obj) {
            var pos = Dom.getXY(obj.overlay.element),
            currentX = pos[0],
            currentY = pos[1];
            if (Dom.getStyle(obj.overlay.element, "visibility") == "hidden" && currentX < x) {
                Dom.setStyle(obj.overlay.element, "visibility", "visible");
            }
            obj.overlay.cfg.setProperty("xy", [currentX, currentY], true);
            obj.overlay.cfg.refireEvent("iframe");
        };
        slide.handleCompleteAnimateIn = function(type, args, obj) {
            obj.overlay.cfg.setProperty("xy", [x, y], true);
            obj.startX = x;
            obj.startY = y;
            obj.overlay.cfg.refireEvent("iframe");
            obj.animateInCompleteEvent.fire();
        };
        slide.handleStartAnimateOut = function(type, args, obj) {
            var vw = Dom.getViewportWidth(),
            pos = Dom.getXY(obj.overlay.element),
            yso = pos[1],
            currentTo = obj.animOut.attributes.points.to;
            obj.animOut.attributes.points.to = [(vw + 25), yso];
        };
        slide.handleTweenAnimateOut = function(type, args, obj) {
            var pos = Dom.getXY(obj.overlay.element),
            xto = pos[0],
            yto = pos[1];
            obj.overlay.cfg.setProperty("xy", [xto, yto], true);
            obj.overlay.cfg.refireEvent("iframe");
        };
        slide.handleCompleteAnimateOut = function(type, args, obj) {
            Dom.setStyle(obj.overlay.element, "visibility", "hidden");
            obj.overlay.cfg.setProperty("xy", [x, y]);
            obj.animateOutCompleteEvent.fire();
        };
        slide.init();
        return slide;
    };
    ContainerEffect.prototype = {
        init: function() {
            this.beforeAnimateInEvent = this.createEvent("beforeAnimateIn");
            this.beforeAnimateInEvent.signature = CustomEvent.LIST;
            this.beforeAnimateOutEvent = this.createEvent("beforeAnimateOut");
            this.beforeAnimateOutEvent.signature = CustomEvent.LIST;
            this.animateInCompleteEvent = this.createEvent("animateInComplete");
            this.animateInCompleteEvent.signature = CustomEvent.LIST;
            this.animateOutCompleteEvent = this.createEvent("animateOutComplete");
            this.animateOutCompleteEvent.signature = CustomEvent.LIST;
            this.animIn = new this.animClass(this.targetElement, this.attrIn.attributes, this.attrIn.duration, this.attrIn.method);
            this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
            this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
            this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, this);
            this.animOut = new this.animClass(this.targetElement, this.attrOut.attributes, this.attrOut.duration, this.attrOut.method);
            this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
            this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
            this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, this);
        },
        animateIn: function() {
            this.beforeAnimateInEvent.fire();
            this.animIn.animate();
        },
        animateOut: function() {
            this.beforeAnimateOutEvent.fire();
            this.animOut.animate();
        },
        handleStartAnimateIn: function(type, args, obj) {},
        handleTweenAnimateIn: function(type, args, obj) {},
        handleCompleteAnimateIn: function(type, args, obj) {},
        handleStartAnimateOut: function(type, args, obj) {},
        handleTweenAnimateOut: function(type, args, obj) {},
        handleCompleteAnimateOut: function(type, args, obj) {},
        toString: function() {
            var output = "ContainerEffect";
            if (this.overlay) {
                output += " [" + this.overlay.toString() + "]";
            }
            return output;
        }
    };
    YAHOO.lang.augmentProto(ContainerEffect, YAHOO.util.EventProvider);
})();
YAHOO.register("container_core", YAHOO.widget.Module, {
    version: "2.3.0",
    build: "442"
});
(function() {
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event;
    YAHOO.widget.MenuManager = function() {
        var m_bInitializedEventHandlers = false,
        m_oMenus = {},
        m_oVisibleMenus = {},
        m_oItems = {},
        m_oEventTypes = {
            "click": "clickEvent",
            "mousedown": "mouseDownEvent",
            "mouseup": "mouseUpEvent",
            "mouseover": "mouseOverEvent",
            "mouseout": "mouseOutEvent",
            "keydown": "keyDownEvent",
            "keyup": "keyUpEvent",
            "keypress": "keyPressEvent"
        },
        m_oFocusedMenuItem = null;
        function getMenuRootElement(p_oElement) {
            var oParentNode;
            if (p_oElement && p_oElement.tagName) {
                switch (p_oElement.tagName.toUpperCase()) {
                case "DIV":
                    oParentNode = p_oElement.parentNode;
                    if ((Dom.hasClass(p_oElement, "hd") || Dom.hasClass(p_oElement, "bd") || Dom.hasClass(p_oElement, "ft")) && oParentNode && oParentNode.tagName && oParentNode.tagName.toUpperCase() == "DIV") {
                        return oParentNode;
                    }
                    else {
                        return p_oElement;
                    }
                    break;
                case "LI":
                    return p_oElement;
                default:
                    oParentNode = p_oElement.parentNode;
                    if (oParentNode) {
                        return getMenuRootElement(oParentNode);
                    }
                    break;
                }
            }
        }
        function onDOMEvent(p_oEvent) {
            var oTarget = Event.getTarget(p_oEvent),
            oElement = getMenuRootElement(oTarget),
            sCustomEventType,
            sTagName,
            sId,
            oMenuItem,
            oMenu;
            if (oElement) {
                sTagName = oElement.tagName.toUpperCase();
                if (sTagName == "LI") {
                    sId = oElement.id;
                    if (sId && m_oItems[sId]) {
                        oMenuItem = m_oItems[sId];
                        oMenu = oMenuItem.parent;
                    }
                }
                else if (sTagName == "DIV") {
                    if (oElement.id) {
                        oMenu = m_oMenus[oElement.id];
                    }
                }
            }
            if (oMenu) {
                sCustomEventType = m_oEventTypes[p_oEvent.type];
                if (oMenuItem && !oMenuItem.cfg.getProperty("disabled")) {
                    oMenuItem[sCustomEventType].fire(p_oEvent);
                    if (p_oEvent.type == "keyup" || p_oEvent.type == "mousedown") {
                        if (m_oFocusedMenuItem != oMenuItem) {
                            if (m_oFocusedMenuItem) {
                                m_oFocusedMenuItem.blurEvent.fire();
                            }
                            oMenuItem.focusEvent.fire();
                        }
                    }
                }
                oMenu[sCustomEventType].fire(p_oEvent, oMenuItem);
            }
            else if (p_oEvent.type == "mousedown") {
                if (m_oFocusedMenuItem) {
                    m_oFocusedMenuItem.blurEvent.fire();
                    m_oFocusedMenuItem = null;
                }
                for (var i in m_oMenus) {
                    if (YAHOO.lang.hasOwnProperty(m_oMenus, i)) {
                        oMenu = m_oMenus[i];
                        if (oMenu.cfg.getProperty("clicktohide") && !(oMenu instanceof YAHOO.widget.MenuBar) && oMenu.cfg.getProperty("position") == "dynamic") {
                            oMenu.hide();
                        }
                        else {
                            oMenu.clearActiveItem(true);
                        }
                    }
                }
            }
            else if (p_oEvent.type == "keyup") {
                if (m_oFocusedMenuItem) {
                    m_oFocusedMenuItem.blurEvent.fire();
                    m_oFocusedMenuItem = null;
                }
            }
        }
        function onMenuDestroy(p_sType, p_aArgs, p_oMenu) {
            if (m_oMenus[p_oMenu.id]) {
                this.removeMenu(p_oMenu);
            }
        }
        function onMenuFocus(p_sType, p_aArgs) {
            var oItem = p_aArgs[0];
            if (oItem) {
                m_oFocusedMenuItem = oItem;
            }
        }
        function onMenuBlur(p_sType, p_aArgs) {
            m_oFocusedMenuItem = null;
        }
        function onMenuVisibleConfigChange(p_sType, p_aArgs) {
            var bVisible = p_aArgs[0],
            sId = this.id;
            if (bVisible) {
                m_oVisibleMenus[sId] = this;
            }
            else if (m_oVisibleMenus[sId]) {
                delete m_oVisibleMenus[sId];
            }
        }
        function onItemDestroy(p_sType, p_aArgs) {
            var sId = this.id;
            if (sId && m_oItems[sId]) {
                if (m_oFocusedMenuItem == this) {
                    m_oFocusedMenuItem = null;
                }
                delete m_oItems[sId];
            }
        }
        function onItemAdded(p_sType, p_aArgs) {
            var oItem = p_aArgs[0],
            sId;
            if (oItem instanceof YAHOO.widget.MenuItem) {
                sId = oItem.id;
                if (!m_oItems[sId]) {
                    m_oItems[sId] = oItem;
                    oItem.destroyEvent.subscribe(onItemDestroy);
                }
            }
        }
        return {
            addMenu: function(p_oMenu) {
                var oDoc;
                if (p_oMenu instanceof YAHOO.widget.Menu && p_oMenu.id && !m_oMenus[p_oMenu.id]) {
                    m_oMenus[p_oMenu.id] = p_oMenu;
                    if (!m_bInitializedEventHandlers) {
                        oDoc = document;
                        Event.on(oDoc, "mouseover", onDOMEvent, this, true);
                        Event.on(oDoc, "mouseout", onDOMEvent, this, true);
                        Event.on(oDoc, "mousedown", onDOMEvent, this, true);
                        Event.on(oDoc, "mouseup", onDOMEvent, this, true);
                        Event.on(oDoc, "click", onDOMEvent, this, true);
                        Event.on(oDoc, "keydown", onDOMEvent, this, true);
                        Event.on(oDoc, "keyup", onDOMEvent, this, true);
                        Event.on(oDoc, "keypress", onDOMEvent, this, true);
                        m_bInitializedEventHandlers = true;
                    }
                    p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, this);
                    p_oMenu.cfg.subscribeToConfigEvent("visible", onMenuVisibleConfigChange);
                    p_oMenu.itemAddedEvent.subscribe(onItemAdded);
                    p_oMenu.focusEvent.subscribe(onMenuFocus);
                    p_oMenu.blurEvent.subscribe(onMenuBlur);
                }
            },
            removeMenu: function(p_oMenu) {
                var sId;
                if (p_oMenu) {
                    sId = p_oMenu.id;
                    if (m_oMenus[sId] == p_oMenu) {
                        delete m_oMenus[sId];
                        if (m_oVisibleMenus[sId] == p_oMenu) {
                            delete m_oVisibleMenus[sId];
                        }
                    }
                }
            },
            hideVisible: function() {
                var oMenu;
                for (var i in m_oVisibleMenus) {
                    if (YAHOO.lang.hasOwnProperty(m_oVisibleMenus, i)) {
                        oMenu = m_oVisibleMenus[i];
                        if (! (oMenu instanceof YAHOO.widget.MenuBar) && oMenu.cfg.getProperty("position") == "dynamic") {
                            oMenu.hide();
                        }
                    }
                }
            },
            getMenus: function() {
                return m_oMenus;
            },
            getMenu: function(p_sId) {
                var oMenu = m_oMenus[p_sId];
                if (oMenu) {
                    return oMenu;
                }
            },
            getMenuItem: function(p_sId) {
                var oItem = m_oItems[p_sId];
                if (oItem) {
                    return oItem;
                }
            },
            getMenuItemGroup: function(p_sId) {
                var oUL = Dom.get(p_sId),
                aItems,
                oNode,
                oItem,
                sId;
                if (oUL && oUL.tagName && oUL.tagName.toUpperCase() == "UL") {
                    oNode = oUL.firstChild;
                    if (oNode) {
                        aItems = [];
                        do {
                            sId = oNode.id;
                            if (sId) {
                                oItem = this.getMenuItem(sId);
                                if (oItem) {
                                    aItems[aItems.length] = oItem;
                                }
                            }
                        }
                        while ((oNode = oNode.nextSibling));
                        if (aItems.length > 0) {
                            return aItems;
                        }
                    }
                }
            },
            getFocusedMenuItem: function() {
                return m_oFocusedMenuItem;
            },
            getFocusedMenu: function() {
                if (m_oFocusedMenuItem) {
                    return (m_oFocusedMenuItem.parent.getRoot());
                }
            },
            toString: function() {
                return "MenuManager";
            }
        };
    } ();
})();
(function() {
    YAHOO.widget.Menu = function(p_oElement, p_oConfig) {
        if (p_oConfig) {
            this.parent = p_oConfig.parent;
            this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
            this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
        }
        YAHOO.widget.Menu.superclass.constructor.call(this, p_oElement, p_oConfig);
    };
    function checkPosition(p_sPosition) {
        if (typeof p_sPosition == "string") {
            return ("dynamic,static".indexOf((p_sPosition.toLowerCase())) != -1);
        }
    }
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event,
    Module = YAHOO.widget.Module,
    Overlay = YAHOO.widget.Overlay,
    Menu = YAHOO.widget.Menu,
    MenuManager = YAHOO.widget.MenuManager,
    CustomEvent = YAHOO.util.CustomEvent,
    Lang = YAHOO.lang,
    m_oShadowTemplate, EVENT_TYPES = {
        "MOUSE_OVER": "mouseover",
        "MOUSE_OUT": "mouseout",
        "MOUSE_DOWN": "mousedown",
        "MOUSE_UP": "mouseup",
        "CLICK": "click",
        "KEY_PRESS": "keypress",
        "KEY_DOWN": "keydown",
        "KEY_UP": "keyup",
        "FOCUS": "focus",
        "BLUR": "blur",
        "ITEM_ADDED": "itemAdded",
        "ITEM_REMOVED": "itemRemoved"
    },
    DEFAULT_CONFIG = {
        "VISIBLE": {
            key: "visible",
            value: false,
            validator: Lang.isBoolean
        },
        "CONSTRAIN_TO_VIEWPORT": {
            key: "constraintoviewport",
            value: true,
            validator: Lang.isBoolean,
            supercedes: ["iframe", "x", "y", "xy"]
        },
        "POSITION": {
            key: "position",
            value: "dynamic",
            validator: checkPosition,
            supercedes: ["visible", "iframe"]
        },
        "SUBMENU_ALIGNMENT": {
            key: "submenualignment",
            value: ["tl", "tr"]
        },
        "AUTO_SUBMENU_DISPLAY": {
            key: "autosubmenudisplay",
            value: true,
            validator: Lang.isBoolean
        },
        "SHOW_DELAY": {
            key: "showdelay",
            value: 250,
            validator: Lang.isNumber
        },
        "HIDE_DELAY": {
            key: "hidedelay",
            value: 0,
            validator: Lang.isNumber,
            suppressEvent: true
        },
        "SUBMENU_HIDE_DELAY": {
            key: "submenuhidedelay",
            value: 250,
            validator: Lang.isNumber
        },
        "CLICK_TO_HIDE": {
            key: "clicktohide",
            value: true,
            validator: Lang.isBoolean
        },
        "CONTAINER": {
            key: "container"
        },
        "MAX_HEIGHT": {
            key: "maxheight",
            value: 0,
            validator: Lang.isNumber,
            supercedes: ["iframe"]
        },
        "CLASS_NAME": {
            key: "classname",
            value: null,
            validator: Lang.isString
        },
        "DISABLED": {
            key: "disabled",
            value: false,
            validator: Lang.isBoolean
        }
    };
    YAHOO.lang.extend(Menu, Overlay, {
        CSS_CLASS_NAME: "yuimenu",
        ITEM_TYPE: null,
        GROUP_TITLE_TAG_NAME: "h6",
        _nHideDelayId: null,
        _nShowDelayId: null,
        _nSubmenuHideDelayId: null,
        _nBodyScrollId: null,
        _bHideDelayEventHandlersAssigned: false,
        _bHandledMouseOverEvent: false,
        _bHandledMouseOutEvent: false,
        _aGroupTitleElements: null,
        _aItemGroups: null,
        _aListElements: null,
        _nCurrentMouseX: 0,
        _nMaxHeight: -1,
        _bStopMouseEventHandlers: false,
        _sClassName: null,
        _bDisabled: false,
        lazyLoad: false,
        itemData: null,
        activeItem: null,
        parent: null,
        srcElement: null,
        mouseOverEvent: null,
        mouseOutEvent: null,
        mouseDownEvent: null,
        mouseUpEvent: null,
        clickEvent: null,
        keyPressEvent: null,
        keyDownEvent: null,
        keyUpEvent: null,
        itemAddedEvent: null,
        itemRemovedEvent: null,
        init: function(p_oElement, p_oConfig) {
            this._aItemGroups = [];
            this._aListElements = [];
            this._aGroupTitleElements = [];
            if (!this.ITEM_TYPE) {
                this.ITEM_TYPE = YAHOO.widget.MenuItem;
            }
            var oElement;
            if (typeof p_oElement == "string") {
                oElement = document.getElementById(p_oElement);
            }
            else if (p_oElement.tagName) {
                oElement = p_oElement;
            }
            if (oElement && oElement.tagName) {
                switch (oElement.tagName.toUpperCase()) {
                case "DIV":
                    this.srcElement = oElement;
                    if (!oElement.id) {
                        oElement.setAttribute("id", Dom.generateId());
                    }
                    Menu.superclass.init.call(this, oElement);
                    this.beforeInitEvent.fire(Menu);
                    break;
                case "SELECT":
                    this.srcElement = oElement;
                    Menu.superclass.init.call(this, Dom.generateId());
                    this.beforeInitEvent.fire(Menu);
                    break;
                }
            }
            else {
                Menu.superclass.init.call(this, p_oElement);
                this.beforeInitEvent.fire(Menu);
            }
            if (this.element) {
                Dom.addClass(this.element, this.CSS_CLASS_NAME);
                this.initEvent.subscribe(this._onInit);
                this.beforeRenderEvent.subscribe(this._onBeforeRender);
                this.renderEvent.subscribe(this._onRender);
                this.renderEvent.subscribe(this.onRender);
                this.beforeShowEvent.subscribe(this._onBeforeShow);
                this.showEvent.subscribe(this._onShow);
                this.beforeHideEvent.subscribe(this._onBeforeHide);
                this.hideEvent.subscribe(this._onHide);
                this.mouseOverEvent.subscribe(this._onMouseOver);
                this.mouseOutEvent.subscribe(this._onMouseOut);
                this.clickEvent.subscribe(this._onClick);
                this.keyDownEvent.subscribe(this._onKeyDown);
                this.keyPressEvent.subscribe(this._onKeyPress);
                Module.textResizeEvent.subscribe(this._onTextResize, this, true);
                if (p_oConfig) {
                    this.cfg.applyConfig(p_oConfig, true);
                }
                MenuManager.addMenu(this);
                this.initEvent.fire(Menu);
            }
        },
        _initSubTree: function() {
            var oSrcElement = this.srcElement,
            sSrcElementTagName, nGroup, sGroupTitleTagName, oNode, aListElements, nListElements, i;
            if (oSrcElement) {
                sSrcElementTagName = (oSrcElement.tagName && oSrcElement.tagName.toUpperCase());
                if (sSrcElementTagName == "DIV") {
                    oNode = this.body.firstChild;
                    if (oNode) {
                        nGroup = 0;
                        sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
                        do {
                            if (oNode && oNode.tagName) {
                                switch (oNode.tagName.toUpperCase()) {
                                case sGroupTitleTagName:
                                    this._aGroupTitleElements[nGroup] = oNode;
                                    break;
                                case "UL":
                                    this._aListElements[nGroup] = oNode;
                                    this._aItemGroups[nGroup] = [];
                                    nGroup++;
                                    break;
                                }
                            }
                        }
                        while ((oNode = oNode.nextSibling));
                        if (this._aListElements[0]) {
                            Dom.addClass(this._aListElements[0], "first-of-type");
                        }
                    }
                }
                oNode = null;
                if (sSrcElementTagName) {
                    switch (sSrcElementTagName) {
                    case "DIV":
                        aListElements = this._aListElements;
                        nListElements = aListElements.length;
                        if (nListElements > 0) {
                            i = nListElements - 1;
                            do {
                                oNode = aListElements[i].firstChild;
                                if (oNode) {
                                    do {
                                        if (oNode && oNode.tagName && oNode.tagName.toUpperCase() == "LI") {
                                            this.addItem(new this.ITEM_TYPE(oNode, {
                                                parent: this
                                            }), i);
                                        }
                                    }
                                    while ((oNode = oNode.nextSibling));
                                }
                            }
                            while (i--);
                        }
                        break;
                    case "SELECT":
                        oNode = oSrcElement.firstChild;
                        do {
                            if (oNode && oNode.tagName) {
                                switch (oNode.tagName.toUpperCase()) {
                                case "OPTGROUP":
                                case "OPTION":
                                    this.addItem(new this.ITEM_TYPE(oNode, {
                                        parent: this
                                    }));
                                    break;
                                }
                            }
                        }
                        while ((oNode = oNode.nextSibling));
                        break;
                    }
                }
            }
        },
        _getFirstEnabledItem: function() {
            var aItems = this.getItems(),
            nItems = aItems.length,
            oItem;
            for (var i = 0; i < nItems; i++) {
                oItem = aItems[i];
                if (oItem && !oItem.cfg.getProperty("disabled") && oItem.element.style.display != "none") {
                    return oItem;
                }
            }
        },
        _addItemToGroup: function(p_nGroupIndex, p_oItem, p_nItemIndex) {
            var oItem, bDisabled = this.cfg.getProperty("disabled"),
            nGroupIndex,
            aGroup,
            oGroupItem,
            bAppend,
            oNextItemSibling,
            nItemIndex;
            function getNextItemSibling(p_aArray, p_nStartIndex) {
                return (p_aArray[p_nStartIndex] || getNextItemSibling(p_aArray, (p_nStartIndex + 1)));
            }
            if (p_oItem instanceof this.ITEM_TYPE) {
                oItem = p_oItem;
                oItem.parent = this;
            }
            else if (typeof p_oItem == "string") {
                oItem = new this.ITEM_TYPE(p_oItem, {
                    parent: this
                });
            }
            else if (typeof p_oItem == "object") {
                p_oItem.parent = this;
                oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem);
            }
            if (oItem) {
                if (oItem.cfg.getProperty("selected")) {
                    this.activeItem = oItem;
                }
                nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex: 0;
                aGroup = this._getItemGroup(nGroupIndex);
                if (!aGroup) {
                    aGroup = this._createItemGroup(nGroupIndex);
                }
                if (typeof p_nItemIndex == "number") {
                    bAppend = (p_nItemIndex >= aGroup.length);
                    if (aGroup[p_nItemIndex]) {
                        aGroup.splice(p_nItemIndex, 0, oItem);
                    }
                    else {
                        aGroup[p_nItemIndex] = oItem;
                    }
                    oGroupItem = aGroup[p_nItemIndex];
                    if (oGroupItem) {
                        if (bAppend && (!oGroupItem.element.parentNode || oGroupItem.element.parentNode.nodeType == 11)) {
                            this._aListElements[nGroupIndex].appendChild(oGroupItem.element);
                        }
                        else {
                            oNextItemSibling = getNextItemSibling(aGroup, (p_nItemIndex + 1));
                            if (oNextItemSibling && (!oGroupItem.element.parentNode || oGroupItem.element.parentNode.nodeType == 11)) {
                                this._aListElements[nGroupIndex].insertBefore(oGroupItem.element, oNextItemSibling.element);
                            }
                        }
                        oGroupItem.parent = this;
                        this._subscribeToItemEvents(oGroupItem);
                        this._configureSubmenu(oGroupItem);
                        this._updateItemProperties(nGroupIndex);
                        this.itemAddedEvent.fire(oGroupItem);
                        this.changeContentEvent.fire();
                        return oGroupItem;
                    }
                }
                else {
                    nItemIndex = aGroup.length;
                    aGroup[nItemIndex] = oItem;
                    oGroupItem = aGroup[nItemIndex];
                    if (oGroupItem) {
                        if (!Dom.isAncestor(this._aListElements[nGroupIndex], oGroupItem.element)) {
                            this._aListElements[nGroupIndex].appendChild(oGroupItem.element);
                        }
                        oGroupItem.element.setAttribute("groupindex", nGroupIndex);
                        oGroupItem.element.setAttribute("index", nItemIndex);
                        oGroupItem.parent = this;
                        oGroupItem.index = nItemIndex;
                        oGroupItem.groupIndex = nGroupIndex;
                        this._subscribeToItemEvents(oGroupItem);
                        this._configureSubmenu(oGroupItem);
                        if (nItemIndex === 0) {
                            Dom.addClass(oGroupItem.element, "first-of-type");
                        }
                        this.itemAddedEvent.fire(oGroupItem);
                        this.changeContentEvent.fire();
                        return oGroupItem;
                    }
                }
            }
        },
        _removeItemFromGroupByIndex: function(p_nGroupIndex, p_nItemIndex) {
            var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex: 0,
            aGroup = this._getItemGroup(nGroupIndex),
            aArray,
            oItem,
            oUL;
            if (aGroup) {
                aArray = aGroup.splice(p_nItemIndex, 1);
                oItem = aArray[0];
                if (oItem) {
                    this._updateItemProperties(nGroupIndex);
                    if (aGroup.length === 0) {
                        oUL = this._aListElements[nGroupIndex];
                        if (this.body && oUL) {
                            this.body.removeChild(oUL);
                        }
                        this._aItemGroups.splice(nGroupIndex, 1);
                        this._aListElements.splice(nGroupIndex, 1);
                        oUL = this._aListElements[0];
                        if (oUL) {
                            Dom.addClass(oUL, "first-of-type");
                        }
                    }
                    this.itemRemovedEvent.fire(oItem);
                    this.changeContentEvent.fire();
                    return oItem;
                }
            }
        },
        _removeItemFromGroupByValue: function(p_nGroupIndex, p_oItem) {
            var aGroup = this._getItemGroup(p_nGroupIndex),
            nItems,
            nItemIndex,
            i;
            if (aGroup) {
                nItems = aGroup.length;
                nItemIndex = -1;
                if (nItems > 0) {
                    i = nItems - 1;
                    do {
                        if (aGroup[i] == p_oItem) {
                            nItemIndex = i;
                            break;
                        }
                    }
                    while (i--);
                    if (nItemIndex > -1) {
                        return (this._removeItemFromGroupByIndex(p_nGroupIndex, nItemIndex));
                    }
                }
            }
        },
        _updateItemProperties: function(p_nGroupIndex) {
            var aGroup = this._getItemGroup(p_nGroupIndex),
            nItems = aGroup.length,
            oItem,
            oLI,
            i;
            if (nItems > 0) {
                i = nItems - 1;
                do {
                    oItem = aGroup[i];
                    if (oItem) {
                        oLI = oItem.element;
                        oItem.index = i;
                        oItem.groupIndex = p_nGroupIndex;
                        oLI.setAttribute("groupindex", p_nGroupIndex);
                        oLI.setAttribute("index", i);
                        Dom.removeClass(oLI, "first-of-type");
                    }
                }
                while (i--);
                if (oLI) {
                    Dom.addClass(oLI, "first-of-type");
                }
            }
        },
        _createItemGroup: function(p_nIndex) {
            var oUL;
            if (!this._aItemGroups[p_nIndex]) {
                this._aItemGroups[p_nIndex] = [];
                oUL = document.createElement("ul");
                this._aListElements[p_nIndex] = oUL;
                return this._aItemGroups[p_nIndex];
            }
        },
        _getItemGroup: function(p_nIndex) {
            var nIndex = ((typeof p_nIndex == "number") ? p_nIndex: 0);
            return this._aItemGroups[nIndex];
        },
        _configureSubmenu: function(p_oItem) {
            var oSubmenu = p_oItem.cfg.getProperty("submenu");
            if (oSubmenu) {
                this.cfg.configChangedEvent.subscribe(this._onParentMenuConfigChange, oSubmenu, true);
                this.renderEvent.subscribe(this._onParentMenuRender, oSubmenu, true);
                oSubmenu.beforeShowEvent.subscribe(this._onSubmenuBeforeShow, null, oSubmenu);
                oSubmenu.showEvent.subscribe(this._onSubmenuShow, null, p_oItem);
                oSubmenu.hideEvent.subscribe(this._onSubmenuHide, null, p_oItem);
            }
        },
        _subscribeToItemEvents: function(p_oItem) {
            p_oItem.focusEvent.subscribe(this._onMenuItemFocus);
            p_oItem.blurEvent.subscribe(this._onMenuItemBlur);
            p_oItem.cfg.configChangedEvent.subscribe(this._onMenuItemConfigChange, p_oItem, this);
        },
        _getOffsetWidth: function() {
            var oClone = this.element.cloneNode(true);
            Dom.removeClass(oClone, "visible");
            Dom.setStyle(oClone, "width", "");
            document.body.appendChild(oClone);
            var sWidth = oClone.offsetWidth;
            document.body.removeChild(oClone);
            return sWidth;
        },
        _setWidth: function() {
            var oElement = this.element,
            bVisible = false,
            sWidth;
            if (oElement.parentNode.tagName.toUpperCase() == "BODY") {
                if (YAHOO.env.ua.opera) {
                    sWidth = this._getOffsetWidth();
                }
                else {
                    if (Dom.hasClass(oElement, "visible")) {
                        bVisible = true;
                        Dom.removeClass(oElement, "visible");
                    }
                    Dom.setStyle(oElement, "width", "auto");
                    sWidth = oElement.offsetWidth;
                }
            }
            else {
                sWidth = this._getOffsetWidth();
            }
            this.cfg.setProperty("width", (sWidth + "px"));
            if (bVisible) {
                Dom.addClass(oElement, "visible");
            }
        },
        _onWidthChange: function(p_sType, p_aArgs) {
            var sWidth = p_aArgs[0];
            if (sWidth && !this._hasSetWidthHandlers) {
                this.itemAddedEvent.subscribe(this._setWidth);
                this.itemRemovedEvent.subscribe(this._setWidth);
                this._hasSetWidthHandlers = true;
            }
            else if (this._hasSetWidthHandlers) {
                this.itemAddedEvent.unsubscribe(this._setWidth);
                this.itemRemovedEvent.unsubscribe(this._setWidth);
                this._hasSetWidthHandlers = false;
            }
        },
        _onVisibleChange: function(p_sType, p_aArgs) {
            var bVisible = p_aArgs[0];
            if (bVisible) {
                Dom.addClass(this.element, "visible");
            }
            else {
                Dom.removeClass(this.element, "visible");
            }
        },
        _cancelHideDelay: function() {
            var oRoot = this.getRoot();
            if (oRoot._nHideDelayId) {
                window.clearTimeout(oRoot._nHideDelayId);
            }
        },
        _execHideDelay: function() {
            this._cancelHideDelay();
            var oRoot = this.getRoot(),
            me = this;
            function hideMenu() {
                if (oRoot.activeItem) {
                    oRoot.clearActiveItem();
                }
                if (oRoot == me && !(me instanceof YAHOO.widget.MenuBar) && me.cfg.getProperty("position") == "dynamic") {
                    me.hide();
                }
            }
            oRoot._nHideDelayId = window.setTimeout(hideMenu, oRoot.cfg.getProperty("hidedelay"));
        },
        _cancelShowDelay: function() {
            var oRoot = this.getRoot();
            if (oRoot._nShowDelayId) {
                window.clearTimeout(oRoot._nShowDelayId);
            }
        },
        _execShowDelay: function(p_oMenu) {
            var oRoot = this.getRoot();
            function showMenu() {
                if (p_oMenu.parent.cfg.getProperty("selected")) {
                    p_oMenu.show();
                }
            }
            oRoot._nShowDelayId = window.setTimeout(showMenu, oRoot.cfg.getProperty("showdelay"));
        },
        _execSubmenuHideDelay: function(p_oSubmenu, p_nMouseX, p_nHideDelay) {
            var me = this;
            p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function() {
                if (me._nCurrentMouseX > (p_nMouseX + 10)) {
                    p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function() {
                        p_oSubmenu.hide();
                    },
                    p_nHideDelay);
                }
                else {
                    p_oSubmenu.hide();
                }
            },
            50);
        },
        _disableScrollHeader: function() {
            if (!this._bHeaderDisabled) {
                Dom.addClass(this.header, "topscrollbar_disabled");
                this._bHeaderDisabled = true;
            }
        },
        _disableScrollFooter: function() {
            if (!this._bFooterDisabled) {
                Dom.addClass(this.footer, "bottomscrollbar_disabled");
                this._bFooterDisabled = true;
            }
        },
        _enableScrollHeader: function() {
            if (this._bHeaderDisabled) {
                Dom.removeClass(this.header, "topscrollbar_disabled");
                this._bHeaderDisabled = false;
            }
        },
        _enableScrollFooter: function() {
            if (this._bFooterDisabled) {
                Dom.removeClass(this.footer, "bottomscrollbar_disabled");
                this._bFooterDisabled = false;
            }
        },
        _onMouseOver: function(p_sType, p_aArgs) {
            if (this._bStopMouseEventHandlers) {
                return false;
            }
            var oEvent = p_aArgs[0],
            oItem = p_aArgs[1],
            oTarget = Event.getTarget(oEvent),
            oParentMenu,
            nShowDelay,
            bShowDelay,
            oActiveItem,
            oItemCfg,
            oSubmenu;
            if (!this._bHandledMouseOverEvent && (oTarget == this.element || Dom.isAncestor(this.element, oTarget))) {
                this._nCurrentMouseX = 0;
                Event.on(this.element, "mousemove", this._onMouseMove, this, true);
                this.clearActiveItem();
                if (this.parent && this._nSubmenuHideDelayId) {
                    window.clearTimeout(this._nSubmenuHideDelayId);
                    this.parent.cfg.setProperty("selected", true);
                    oParentMenu = this.parent.parent;
                    oParentMenu._bHandledMouseOutEvent = true;
                    oParentMenu._bHandledMouseOverEvent = false;
                }
                this._bHandledMouseOverEvent = true;
                this._bHandledMouseOutEvent = false;
            }
            if (oItem && !oItem.handledMouseOverEvent && !oItem.cfg.getProperty("disabled") && (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))) {
                nShowDelay = this.cfg.getProperty("showdelay");
                bShowDelay = (nShowDelay > 0);
                if (bShowDelay) {
                    this._cancelShowDelay();
                }
                oActiveItem = this.activeItem;
                if (oActiveItem) {
                    oActiveItem.cfg.setProperty("selected", false);
                }
                oItemCfg = oItem.cfg;
                oItemCfg.setProperty("selected", true);
                if (this.hasFocus()) {
                    oItem.focus();
                }
                if (this.cfg.getProperty("autosubmenudisplay")) {
                    oSubmenu = oItemCfg.getProperty("submenu");
                    if (oSubmenu) {
                        if (bShowDelay) {
                            this._execShowDelay(oSubmenu);
                        }
                        else {
                            oSubmenu.show();
                        }
                    }
                }
                oItem.handledMouseOverEvent = true;
                oItem.handledMouseOutEvent = false;
            }
        },
        _onMouseOut: function(p_sType, p_aArgs) {
            if (this._bStopMouseEventHandlers) {
                return false;
            }
            var oEvent = p_aArgs[0],
            oItem = p_aArgs[1],
            oRelatedTarget = Event.getRelatedTarget(oEvent),
            bMovingToSubmenu = false,
            oItemCfg,
            oSubmenu,
            nSubmenuHideDelay,
            nShowDelay;
            if (oItem && !oItem.cfg.getProperty("disabled")) {
                oItemCfg = oItem.cfg;
                oSubmenu = oItemCfg.getProperty("submenu");
                if (oSubmenu && (oRelatedTarget == oSubmenu.element || Dom.isAncestor(oSubmenu.element, oRelatedTarget))) {
                    bMovingToSubmenu = true;
                }
                if (!oItem.handledMouseOutEvent && ((oRelatedTarget != oItem.element && !Dom.isAncestor(oItem.element, oRelatedTarget)) || bMovingToSubmenu)) {
                    if (!bMovingToSubmenu) {
                        oItem.cfg.setProperty("selected", false);
                        if (oSubmenu) {
                            nSubmenuHideDelay = this.cfg.getProperty("submenuhidedelay");
                            nShowDelay = this.cfg.getProperty("showdelay");
                            if (! (this instanceof YAHOO.widget.MenuBar) && nSubmenuHideDelay > 0 && nShowDelay >= nSubmenuHideDelay) {
                                this._execSubmenuHideDelay(oSubmenu, Event.getPageX(oEvent), nSubmenuHideDelay);
                            }
                            else {
                                oSubmenu.hide();
                            }
                        }
                    }
                    oItem.handledMouseOutEvent = true;
                    oItem.handledMouseOverEvent = false;
                }
            }
            if (!this._bHandledMouseOutEvent && ((oRelatedTarget != this.element && !Dom.isAncestor(this.element, oRelatedTarget)) || bMovingToSubmenu)) {
                Event.removeListener(this.element, "mousemove", this._onMouseMove);
                this._nCurrentMouseX = Event.getPageX(oEvent);
                this._bHandledMouseOutEvent = true;
                this._bHandledMouseOverEvent = false;
            }
        },
        _onMouseMove: function(p_oEvent, p_oMenu) {
            if (this._bStopMouseEventHandlers) {
                return false;
            }
            this._nCurrentMouseX = Event.getPageX(p_oEvent);
        },
        _onClick: function(p_sType, p_aArgs) {
            var oEvent = p_aArgs[0],
            oItem = p_aArgs[1],
            oTarget,
            oItemCfg,
            oSubmenu,
            sURL,
            oRoot;
            if (oItem && !oItem.cfg.getProperty("disabled")) {
                oTarget = Event.getTarget(oEvent);
                oItemCfg = oItem.cfg;
                oSubmenu = oItemCfg.getProperty("submenu");
                if (oTarget == oItem.submenuIndicator && oSubmenu) {
                    if (oSubmenu.cfg.getProperty("visible")) {
                        oSubmenu.hide();
                        oSubmenu.parent.focus();
                    }
                    else {
                        this.clearActiveItem();
                        oItemCfg.setProperty("selected", true);
                        oSubmenu.show();
                        oSubmenu.setInitialFocus();
                    }
                    Event.preventDefault(oEvent);
                }
                else {
                    sURL = oItemCfg.getProperty("url");
                    if ((sURL.substr((sURL.length - 1), 1) == "#")) {
                        Event.preventDefault(oEvent);
                        oItem.focus();
                    }
                    if (!oSubmenu) {
                        oRoot = this.getRoot();
                        if (oRoot instanceof YAHOO.widget.MenuBar || oRoot.cfg.getProperty("position") == "static") {
                            oRoot.clearActiveItem();
                        }
                        else if (oRoot.cfg.getProperty("clicktohide")) {
                            oRoot.hide();
                        }
                    }
                }
            }
        },
        _onKeyDown: function(p_sType, p_aArgs) {
            var oEvent = p_aArgs[0],
            oItem = p_aArgs[1],
            me = this,
            oSubmenu,
            oItemCfg,
            oParentItem,
            oRoot,
            oNextItem,
            oBody,
            nBodyScrollTop,
            nBodyOffsetHeight,
            aItems,
            nItems,
            nNextItemOffsetTop,
            nScrollTarget,
            oParentMenu;
            function stopMouseEventHandlers() {
                me._bStopMouseEventHandlers = true;
                window.setTimeout(function() {
                    me._bStopMouseEventHandlers = false;
                },
                10);
            }
            if (oItem && !oItem.cfg.getProperty("disabled")) {
                oItemCfg = oItem.cfg;
                oParentItem = this.parent;
                switch (oEvent.keyCode) {
                case 38:
                case 40:
                    oNextItem = (oEvent.keyCode == 38) ? oItem.getPreviousEnabledSibling() : oItem.getNextEnabledSibling();
                    if (oNextItem) {
                        this.clearActiveItem();
                        oNextItem.cfg.setProperty("selected", true);
                        oNextItem.focus();
                        if (this.cfg.getProperty("maxheight") > 0) {
                            oBody = this.body;
                            nBodyScrollTop = oBody.scrollTop;
                            nBodyOffsetHeight = oBody.offsetHeight;
                            aItems = this.getItems();
                            nItems = aItems.length - 1;
                            nNextItemOffsetTop = oNextItem.element.offsetTop;
                            if (oEvent.keyCode == 40) {
                                if (nNextItemOffsetTop >= (nBodyOffsetHeight + nBodyScrollTop)) {
                                    oBody.scrollTop = nNextItemOffsetTop - nBodyOffsetHeight;
                                }
                                else if (nNextItemOffsetTop <= nBodyScrollTop) {
                                    oBody.scrollTop = 0;
                                }
                                if (oNextItem == aItems[nItems]) {
                                    oBody.scrollTop = oNextItem.element.offsetTop;
                                }
                            }
                            else {
                                if (nNextItemOffsetTop <= nBodyScrollTop) {
                                    oBody.scrollTop = nNextItemOffsetTop - oNextItem.element.offsetHeight;
                                }
                                else if (nNextItemOffsetTop >= (nBodyScrollTop + nBodyOffsetHeight)) {
                                    oBody.scrollTop = nNextItemOffsetTop;
                                }
                                if (oNextItem == aItems[0]) {
                                    oBody.scrollTop = 0;
                                }
                            }
                            nBodyScrollTop = oBody.scrollTop;
                            nScrollTarget = oBody.scrollHeight - oBody.offsetHeight;
                            if (nBodyScrollTop === 0) {
                                this._disableScrollHeader();
                                this._enableScrollFooter();
                            }
                            else if (nBodyScrollTop == nScrollTarget) {
                                this._enableScrollHeader();
                                this._disableScrollFooter();
                            }
                            else {
                                this._enableScrollHeader();
                                this._enableScrollFooter();
                            }
                        }
                    }
                    Event.preventDefault(oEvent);
                    stopMouseEventHandlers();
                    break;
                case 39:
                    oSubmenu = oItemCfg.getProperty("submenu");
                    if (oSubmenu) {
                        if (!oItemCfg.getProperty("selected")) {
                            oItemCfg.setProperty("selected", true);
                        }
                        oSubmenu.show();
                        oSubmenu.setInitialFocus();
                        oSubmenu.setInitialSelection();
                    }
                    else {
                        oRoot = this.getRoot();
                        if (oRoot instanceof YAHOO.widget.MenuBar) {
                            oNextItem = oRoot.activeItem.getNextEnabledSibling();
                            if (oNextItem) {
                                oRoot.clearActiveItem();
                                oNextItem.cfg.setProperty("selected", true);
                                oSubmenu = oNextItem.cfg.getProperty("submenu");
                                if (oSubmenu) {
                                    oSubmenu.show();
                                }
                                oNextItem.focus();
                            }
                        }
                    }
                    Event.preventDefault(oEvent);
                    stopMouseEventHandlers();
                    break;
                case 37:
                    if (oParentItem) {
                        oParentMenu = oParentItem.parent;
                        if (oParentMenu instanceof YAHOO.widget.MenuBar) {
                            oNextItem = oParentMenu.activeItem.getPreviousEnabledSibling();
                            if (oNextItem) {
                                oParentMenu.clearActiveItem();
                                oNextItem.cfg.setProperty("selected", true);
                                oSubmenu = oNextItem.cfg.getProperty("submenu");
                                if (oSubmenu) {
                                    oSubmenu.show();
                                }
                                oNextItem.focus();
                            }
                        }
                        else {
                            this.hide();
                            oParentItem.focus();
                        }
                    }
                    Event.preventDefault(oEvent);
                    stopMouseEventHandlers();
                    break;
                }
            }
            if (oEvent.keyCode == 27) {
                if (this.cfg.getProperty("position") == "dynamic") {
                    this.hide();
                    if (this.parent) {
                        this.parent.focus();
                    }
                }
                else if (this.activeItem) {
                    oSubmenu = this.activeItem.cfg.getProperty("submenu");
                    if (oSubmenu && oSubmenu.cfg.getProperty("visible")) {
                        oSubmenu.hide();
                        this.activeItem.focus();
                    }
                    else {
                        this.activeItem.blur();
                        this.activeItem.cfg.setProperty("selected", false);
                    }
                }
                Event.preventDefault(oEvent);
            }
        },
        _onKeyPress: function(p_sType, p_aArgs) {
            var oEvent = p_aArgs[0];
            if (oEvent.keyCode == 40 || oEvent.keyCode == 38) {
                Event.preventDefault(oEvent);
            }
        },
        _onTextResize: function(p_sType, p_aArgs, p_oMenu) {
            if (YAHOO.env.ua.gecko && !this._handleResize) {
                this._handleResize = true;
                return;
            }
            var oConfig = this.cfg;
            if (oConfig.getProperty("position") == "dynamic") {
                oConfig.setProperty("width", (this._getOffsetWidth() + "px"));
            }
        },
        _onScrollTargetMouseOver: function(p_oEvent, p_oMenu) {
            this._cancelHideDelay();
            var oTarget = Event.getTarget(p_oEvent),
            oBody = this.body,
            me = this,
            nScrollTarget,
            fnScrollFunction;
            function scrollBodyDown() {
                var nScrollTop = oBody.scrollTop;
                if (nScrollTop < nScrollTarget) {
                    oBody.scrollTop = (nScrollTop + 1);
                    me._enableScrollHeader();
                }
                else {
                    oBody.scrollTop = nScrollTarget;
                    window.clearInterval(me._nBodyScrollId);
                    me._disableScrollFooter();
                }
            }
            function scrollBodyUp() {
                var nScrollTop = oBody.scrollTop;
                if (nScrollTop > 0) {
                    oBody.scrollTop = (nScrollTop - 1);
                    me._enableScrollFooter();
                }
                else {
                    oBody.scrollTop = 0;
                    window.clearInterval(me._nBodyScrollId);
                    me._disableScrollHeader();
                }
            }
            if (Dom.hasClass(oTarget, "hd")) {
                fnScrollFunction = scrollBodyUp;
            }
            else {
                nScrollTarget = oBody.scrollHeight - oBody.offsetHeight;
                fnScrollFunction = scrollBodyDown;
            }
            this._nBodyScrollId = window.setInterval(fnScrollFunction, 10);
        },
        _onScrollTargetMouseOut: function(p_oEvent, p_oMenu) {
            window.clearInterval(this._nBodyScrollId);
            this._cancelHideDelay();
        },
        _onInit: function(p_sType, p_aArgs) {
            this.cfg.subscribeToConfigEvent("width", this._onWidthChange);
            this.cfg.subscribeToConfigEvent("visible", this._onVisibleChange);
            var bRootMenu = !this.parent,
            bLazyLoad = this.lazyLoad;
            if (((bRootMenu && !bLazyLoad) || (bRootMenu && (this.cfg.getProperty("visible") || this.cfg.getProperty("position") == "static")) || (!bRootMenu && !bLazyLoad)) && this.getItemGroups().length === 0) {
                if (this.srcElement) {
                    this._initSubTree();
                }
                if (this.itemData) {
                    this.addItems(this.itemData);
                }
            }
            else if (bLazyLoad) {
                this.cfg.fireQueue();
            }
        },
        _onBeforeRender: function(p_sType, p_aArgs) {
            var oConfig = this.cfg,
            oEl = this.element,
            nListElements = this._aListElements.length,
            bFirstList = true,
            i = 0,
            oUL, oGroupTitle;
            if (nListElements > 0) {
                do {
                    oUL = this._aListElements[i];
                    if (oUL) {
                        if (bFirstList) {
                            Dom.addClass(oUL, "first-of-type");
                            bFirstList = false;
                        }
                        if (!Dom.isAncestor(oEl, oUL)) {
                            this.appendToBody(oUL);
                        }
                        oGroupTitle = this._aGroupTitleElements[i];
                        if (oGroupTitle) {
                            if (!Dom.isAncestor(oEl, oGroupTitle)) {
                                oUL.parentNode.insertBefore(oGroupTitle, oUL);
                            }
                            Dom.addClass(oUL, "hastitle");
                        }
                    }
                    i++;
                }
                while (i < nListElements);
            }
        },
        _onRender: function(p_sType, p_aArgs) {
            if (this.cfg.getProperty("position") == "dynamic" && !this.cfg.getProperty("width")) {
                this._setWidth();
            }
        },
        _onBeforeShow: function(p_sType, p_aArgs) {
            var nOptions, n, nViewportHeight, oRegion, nMaxHeight, oBody, oSrcElement;
            if (this.lazyLoad && this.getItemGroups().length === 0) {
                if (this.srcElement) {
                    this._initSubTree();
                }
                if (this.itemData) {
                    if (this.parent && this.parent.parent && this.parent.parent.srcElement && this.parent.parent.srcElement.tagName.toUpperCase() == "SELECT") {
                        nOptions = this.itemData.length;
                        for (n = 0; n < nOptions; n++) {
                            if (this.itemData[n].tagName) {
                                this.addItem((new this.ITEM_TYPE(this.itemData[n])));
                            }
                        }
                    }
                    else {
                        this.addItems(this.itemData);
                    }
                }
                oSrcElement = this.srcElement;
                if (oSrcElement) {
                    if (oSrcElement.tagName.toUpperCase() == "SELECT") {
                        if (Dom.inDocument(oSrcElement)) {
                            this.render(oSrcElement.parentNode);
                        }
                        else {
                            this.render(this.cfg.getProperty("container"));
                        }
                    }
                    else {
                        this.render();
                    }
                }
                else {
                    if (this.parent) {
                        this.render(this.parent.element);
                    }
                    else {
                        this.render(this.cfg.getProperty("container"));
                        this.cfg.refireEvent("xy");
                    }
                }
            }
            if (! (this instanceof YAHOO.widget.MenuBar) && this.cfg.getProperty("position") == "dynamic") {
                nViewportHeight = Dom.getViewportHeight();
                if (this.parent && this.parent.parent instanceof YAHOO.widget.MenuBar) {
                    oRegion = YAHOO.util.Region.getRegion(this.parent.element);
                    nViewportHeight = (nViewportHeight - oRegion.bottom);
                }
                if (this.element.offsetHeight >= nViewportHeight) {
                    nMaxHeight = this.cfg.getProperty("maxheight");
                    this._nMaxHeight = nMaxHeight;
                    this.cfg.setProperty("maxheight", (nViewportHeight - 20));
                }
                if (this.cfg.getProperty("maxheight") > 0) {
                    oBody = this.body;
                    if (oBody.scrollTop > 0) {
                        oBody.scrollTop = 0;
                    }
                    this._disableScrollHeader();
                    this._enableScrollFooter();
                }
            }
        },
        _onShow: function(p_sType, p_aArgs) {
            var oParent = this.parent,
            oParentMenu, aParentAlignment, aAlignment;
            function disableAutoSubmenuDisplay(p_oEvent) {
                var oTarget;
                if (p_oEvent.type == "mousedown" || (p_oEvent.type == "keydown" && p_oEvent.keyCode == 27)) {
                    oTarget = Event.getTarget(p_oEvent);
                    if (oTarget != oParentMenu.element || !Dom.isAncestor(oParentMenu.element, oTarget)) {
                        oParentMenu.cfg.setProperty("autosubmenudisplay", false);
                        Event.removeListener(document, "mousedown", disableAutoSubmenuDisplay);
                        Event.removeListener(document, "keydown", disableAutoSubmenuDisplay);
                    }
                }
            }
            if (oParent) {
                oParentMenu = oParent.parent;
                aParentAlignment = oParentMenu.cfg.getProperty("submenualignment");
                aAlignment = this.cfg.getProperty("submenualignment");
                if ((aParentAlignment[0] != aAlignment[0]) && (aParentAlignment[1] != aAlignment[1])) {
                    this.cfg.setProperty("submenualignment", [aParentAlignment[0], aParentAlignment[1]]);
                }
                if (!oParentMenu.cfg.getProperty("autosubmenudisplay") && (oParentMenu instanceof YAHOO.widget.MenuBar || oParentMenu.cfg.getProperty("position") == "static")) {
                    oParentMenu.cfg.setProperty("autosubmenudisplay", true);
                    Event.on(document, "mousedown", disableAutoSubmenuDisplay);
                    Event.on(document, "keydown", disableAutoSubmenuDisplay);
                }
            }
        },
        _onBeforeHide: function(p_sType, p_aArgs) {
            var oActiveItem = this.activeItem,
            oConfig, oSubmenu;
            if (oActiveItem) {
                oConfig = oActiveItem.cfg;
                oConfig.setProperty("selected", false);
                oSubmenu = oConfig.getProperty("submenu");
                if (oSubmenu) {
                    oSubmenu.hide();
                }
            }
            if (this.getRoot() == this) {
                this.blur();
            }
        },
        _onHide: function(p_sType, p_aArgs) {
            if (this._nMaxHeight != -1) {
                this.cfg.setProperty("maxheight", this._nMaxHeight);
                this._nMaxHeight = -1;
            }
        },
        _onParentMenuConfigChange: function(p_sType, p_aArgs, p_oSubmenu) {
            var sPropertyName = p_aArgs[0][0],
            oPropertyValue = p_aArgs[0][1];
            switch (sPropertyName) {
            case "iframe":
            case "constraintoviewport":
            case "hidedelay":
            case "showdelay":
            case "submenuhidedelay":
            case "clicktohide":
            case "effect":
            case "classname":
                p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
                break;
            }
        },
        _onParentMenuRender: function(p_sType, p_aArgs, p_oSubmenu) {
            var oParentMenu = p_oSubmenu.parent.parent,
            oConfig = {
                constraintoviewport: oParentMenu.cfg.getProperty("constraintoviewport"),
                xy: [0, 0],
                clicktohide: oParentMenu.cfg.getProperty("clicktohide"),
                effect: oParentMenu.cfg.getProperty("effect"),
                showdelay: oParentMenu.cfg.getProperty("showdelay"),
                hidedelay: oParentMenu.cfg.getProperty("hidedelay"),
                submenuhidedelay: oParentMenu.cfg.getProperty("submenuhidedelay"),
                classname: oParentMenu.cfg.getProperty("classname")
            },
            oLI;
            if (this.cfg.getProperty("position") == oParentMenu.cfg.getProperty("position")) {
                oConfig.iframe = oParentMenu.cfg.getProperty("iframe");
            }
            p_oSubmenu.cfg.applyConfig(oConfig);
            if (!this.lazyLoad) {
                oLI = this.parent.element;
                if (this.element.parentNode == oLI) {
                    this.render();
                }
                else {
                    this.render(oLI);
                }
            }
        },
        _onSubmenuBeforeShow: function(p_sType, p_aArgs) {
            var oParent = this.parent,
            aAlignment = oParent.parent.cfg.getProperty("submenualignment");
            this.cfg.setProperty("context", [oParent.element, aAlignment[0], aAlignment[1]]);
            var nScrollTop = oParent.parent.body.scrollTop;
            if ((YAHOO.env.ua.gecko || YAHOO.env.ua.webkit) && nScrollTop > 0) {
                this.cfg.setProperty("y", (this.cfg.getProperty("y") - nScrollTop));
            }
        },
        _onSubmenuShow: function(p_sType, p_aArgs) {
            this.submenuIndicator.innerHTML = this.EXPANDED_SUBMENU_INDICATOR_TEXT;
        },
        _onSubmenuHide: function(p_sType, p_aArgs) {
            this.submenuIndicator.innerHTML = this.COLLAPSED_SUBMENU_INDICATOR_TEXT;
        },
        _onMenuItemFocus: function(p_sType, p_aArgs) {
            this.parent.focusEvent.fire(this);
        },
        _onMenuItemBlur: function(p_sType, p_aArgs) {
            this.parent.blurEvent.fire(this);
        },
        _onMenuItemConfigChange: function(p_sType, p_aArgs, p_oItem) {
            var sPropertyName = p_aArgs[0][0],
            oPropertyValue = p_aArgs[0][1],
            sWidth,
            oSubmenu;
            switch (sPropertyName) {
            case "selected":
                if (oPropertyValue === true) {
                    this.activeItem = p_oItem;
                }
                break;
            case "submenu":
                oSubmenu = p_aArgs[0][1];
                if (oSubmenu) {
                    this._configureSubmenu(p_oItem);
                }
                break;
            case "text":
            case "helptext":
                if (this.element.style.width) {
                    sWidth = this._getOffsetWidth() + "px";
                    Dom.setStyle(this.element, "width", sWidth);
                }
                break;
            }
        },
        enforceConstraints: function(type, args, obj) {
            var oParentMenuItem = this.parent,
            oElement, oConfig, pos, x, y, offsetHeight, offsetWidth, viewPortWidth, viewPortHeight, scrollX, scrollY, nPadding, topConstraint, leftConstraint, bottomConstraint, rightConstraint, aContext, oContextElement;
            if (oParentMenuItem && !(oParentMenuItem.parent instanceof YAHOO.widget.MenuBar)) {
                oElement = this.element;
                oConfig = this.cfg;
                pos = args[0];
                x = pos[0];
                y = pos[1];
                offsetHeight = oElement.offsetHeight;
                offsetWidth = oElement.offsetWidth;
                viewPortWidth = Dom.getViewportWidth();
                viewPortHeight = Dom.getViewportHeight();
                scrollX = Dom.getDocumentScrollLeft();
                scrollY = Dom.getDocumentScrollTop();
                nPadding = (oParentMenuItem.parent instanceof YAHOO.widget.MenuBar) ? 0 : 10;
                topConstraint = scrollY + nPadding;
                leftConstraint = scrollX + nPadding;
                bottomConstraint = scrollY + viewPortHeight - offsetHeight - nPadding;
                rightConstraint = scrollX + viewPortWidth - offsetWidth - nPadding;
                aContext = oConfig.getProperty("context");
                oContextElement = aContext ? aContext[0] : null;
                if (x < 10) {
                    x = leftConstraint;
                } else if ((x + offsetWidth) > viewPortWidth) {
                    if (oContextElement && ((x - oContextElement.offsetWidth) > offsetWidth)) {
                        x = (x - (oContextElement.offsetWidth + offsetWidth));
                    }
                    else {
                        x = rightConstraint;
                    }
                }
                if (y < 10) {
                    y = topConstraint;
                } else if (y > bottomConstraint) {
                    if (oContextElement && (y > offsetHeight)) {
                        y = ((y + oContextElement.offsetHeight) - offsetHeight);
                    }
                    else {
                        y = bottomConstraint;
                    }
                }
                oConfig.setProperty("x", x, true);
                oConfig.setProperty("y", y, true);
                oConfig.setProperty("xy", [x, y], true);
            }
            else if (this == this.getRoot() && this.cfg.getProperty("position") == "dynamic") {
                Menu.superclass.enforceConstraints.call(this, type, args, obj);
            }
        },
        configVisible: function(p_sType, p_aArgs, p_oMenu) {
            var bVisible, sDisplay;
            if (this.cfg.getProperty("position") == "dynamic") {
                Menu.superclass.configVisible.call(this, p_sType, p_aArgs, p_oMenu);
            }
            else {
                bVisible = p_aArgs[0];
                sDisplay = Dom.getStyle(this.element, "display");
                if (bVisible) {
                    if (sDisplay != "block") {
                        this.beforeShowEvent.fire();
                        Dom.setStyle(this.element, "display", "block");
                        this.showEvent.fire();
                    }
                }
                else {
                    if (sDisplay == "block") {
                        this.beforeHideEvent.fire();
                        Dom.setStyle(this.element, "display", "none");
                        this.hideEvent.fire();
                    }
                }
            }
        },
        configPosition: function(p_sType, p_aArgs, p_oMenu) {
            var oElement = this.element,
            sCSSPosition = p_aArgs[0] == "static" ? "static": "absolute",
            sCurrentPosition = Dom.getStyle(oElement, "position"),
            oCfg = this.cfg,
            nZIndex;
            Dom.setStyle(this.element, "position", sCSSPosition);
            if (sCSSPosition == "static") {
                oCfg.setProperty("iframe", false);
                Dom.setStyle(this.element, "display", "block");
                oCfg.setProperty("visible", true);
            }
            else {
                if (sCurrentPosition != "absolute") {
                    oCfg.setProperty("iframe", (YAHOO.env.ua.ie == 6 ? true: false));
                }
                Dom.setStyle(this.element, "visibility", "hidden");
            }
            if (sCSSPosition == "absolute") {
                nZIndex = oCfg.getProperty("zindex");
                if (!nZIndex || nZIndex === 0) {
                    nZIndex = this.parent ? (this.parent.parent.cfg.getProperty("zindex") + 1) : 1;
                    oCfg.setProperty("zindex", nZIndex);
                }
            }
        },
        configIframe: function(p_sType, p_aArgs, p_oMenu) {
            if (this.cfg.getProperty("position") == "dynamic") {
                Menu.superclass.configIframe.call(this, p_sType, p_aArgs, p_oMenu);
            }
        },
        configHideDelay: function(p_sType, p_aArgs, p_oMenu) {
            var nHideDelay = p_aArgs[0],
            oMouseOutEvent = this.mouseOutEvent,
            oMouseOverEvent = this.mouseOverEvent,
            oKeyDownEvent = this.keyDownEvent;
            if (nHideDelay > 0) {
                if (!this._bHideDelayEventHandlersAssigned) {
                    oMouseOutEvent.subscribe(this._execHideDelay);
                    oMouseOverEvent.subscribe(this._cancelHideDelay);
                    oKeyDownEvent.subscribe(this._cancelHideDelay);
                    this._bHideDelayEventHandlersAssigned = true;
                }
            }
            else {
                oMouseOutEvent.unsubscribe(this._execHideDelay);
                oMouseOverEvent.unsubscribe(this._cancelHideDelay);
                oKeyDownEvent.unsubscribe(this._cancelHideDelay);
                this._bHideDelayEventHandlersAssigned = false;
            }
        },
        configContainer: function(p_sType, p_aArgs, p_oMenu) {
            var oElement = p_aArgs[0];
            if (typeof oElement == 'string') {
                this.cfg.setProperty("container", document.getElementById(oElement), true);
            }
        },
        _setMaxHeight: function(p_sType, p_aArgs, p_nMaxHeight) {
            this.cfg.setProperty("maxheight", p_nMaxHeight);
            this.renderEvent.unsubscribe(this._setMaxHeight);
        },
        configMaxHeight: function(p_sType, p_aArgs, p_oMenu) {
            var nMaxHeight = p_aArgs[0],
            oBody = this.body,
            oHeader = this.header,
            oFooter = this.footer,
            fnMouseOver = this._onScrollTargetMouseOver,
            fnMouseOut = this._onScrollTargetMouseOut,
            nHeight;
            if (this.lazyLoad && !oBody) {
                this.renderEvent.unsubscribe(this._setMaxHeight);
                if (nMaxHeight > 0) {
                    this.renderEvent.subscribe(this._setMaxHeight, nMaxHeight, this);
                }
                return;
            }
            Dom.setStyle(oBody, "height", "auto");
            Dom.setStyle(oBody, "overflow", "visible");
            if ((nMaxHeight > 0) && (oBody.offsetHeight > nMaxHeight)) {
                if (!this.cfg.getProperty("width")) {
                    this._setWidth();
                }
                if (!oHeader && !oFooter) {
                    this.setHeader("&#32;");
                    this.setFooter("&#32;");
                    oHeader = this.header;
                    oFooter = this.footer;
                    Dom.addClass(oHeader, "topscrollbar");
                    Dom.addClass(oFooter, "bottomscrollbar");
                    this.element.insertBefore(oHeader, oBody);
                    this.element.appendChild(oFooter);
                    Event.on(oHeader, "mouseover", fnMouseOver, this, true);
                    Event.on(oHeader, "mouseout", fnMouseOut, this, true);
                    Event.on(oFooter, "mouseover", fnMouseOver, this, true);
                    Event.on(oFooter, "mouseout", fnMouseOut, this, true);
                }
                nHeight = (nMaxHeight - (this.footer.offsetHeight + this.header.offsetHeight));
                Dom.setStyle(oBody, "height", (nHeight + "px"));
                Dom.setStyle(oBody, "overflow", "hidden");
            }
            else if (oHeader && oFooter) {
                Dom.setStyle(oBody, "height", "auto");
                Dom.setStyle(oBody, "overflow", "visible");
                Event.removeListener(oHeader, "mouseover", fnMouseOver);
                Event.removeListener(oHeader, "mouseout", fnMouseOut);
                Event.removeListener(oFooter, "mouseover", fnMouseOver);
                Event.removeListener(oFooter, "mouseout", fnMouseOut);
                this.element.removeChild(oHeader);
                this.element.removeChild(oFooter);
                this.header = null;
                this.footer = null;
            }
            this.cfg.refireEvent("iframe");
        },
        configClassName: function(p_sType, p_aArgs, p_oMenu) {
            var sClassName = p_aArgs[0];
            if (this._sClassName) {
                Dom.removeClass(this.element, this._sClassName);
            }
            Dom.addClass(this.element, sClassName);
            this._sClassName = sClassName;
        },
        _onItemAdded: function(p_sType, p_aArgs) {
            var oItem = p_aArgs[0];
            if (oItem) {
                oItem.cfg.setProperty("disabled", true);
            }
        },
        configDisabled: function(p_sType, p_aArgs, p_oMenu) {
            var bDisabled = p_aArgs[0],
            aItems,
            nItems,
            i;
            if (this._bDisabled != bDisabled) {
                aItems = this.getItems();
                nItems = aItems.length;
                if (nItems > 0) {
                    i = nItems - 1;
                    do {
                        aItems[i].cfg.setProperty("disabled", bDisabled);
                    }
                    while (i--);
                }
                Dom[(bDisabled ? "addClass": "removeClass")](this.element, "disabled");
                this.itemAddedEvent[(bDisabled ? "subscribe": "unsubscribe")](this._onItemAdded);
                this._bDisabled = bDisabled;
            }
        },
        onRender: function(p_sType, p_aArgs) {
            function sizeShadow() {
                var oElement = this.element,
                oShadow = this._shadow;
                if (oShadow) {
                    oShadow.style.width = (oElement.offsetWidth + 6) + "px";
                    oShadow.style.height = (oElement.offsetHeight + 1) + "px";
                }
            }
            function addShadowVisibleClass() {
                Dom.addClass(this._shadow, "yui-menu-shadow-visible");
            }
            function removeShadowVisibleClass() {
                Dom.removeClass(this._shadow, "yui-menu-shadow-visible");
            }
            function createShadow() {
                var oShadow = this._shadow,
                oElement, me;
                if (!oShadow) {
                    oElement = this.element;
                    me = this;
                    if (!m_oShadowTemplate) {
                        m_oShadowTemplate = document.createElement("div");
                        m_oShadowTemplate.className = "yui-menu-shadow";
                    }
                    oShadow = m_oShadowTemplate.cloneNode(false);
                    oElement.appendChild(oShadow);
                    this._shadow = oShadow;
                    addShadowVisibleClass.call(this);
                    this.beforeShowEvent.subscribe(addShadowVisibleClass);
                    this.beforeHideEvent.subscribe(removeShadowVisibleClass);
                    if (YAHOO.env.ua.ie) {
                        window.setTimeout(function() {
                            sizeShadow.call(me);
                            me.syncIframe();
                        },
                        0);
                        this.cfg.subscribeToConfigEvent("width", sizeShadow);
                        this.cfg.subscribeToConfigEvent("height", sizeShadow);
                        this.changeContentEvent.subscribe(sizeShadow);
                        Module.textResizeEvent.subscribe(sizeShadow, me, true);
                        this.destroyEvent.subscribe(function() {
                            Module.textResizeEvent.unsubscribe(sizeShadow, me);
                        });
                    }
                }
            }
            function onBeforeShow() {
                createShadow.call(this);
                this.beforeShowEvent.unsubscribe(onBeforeShow);
            }
            if (this.cfg.getProperty("position") == "dynamic") {
                if (this.cfg.getProperty("visible")) {
                    createShadow.call(this);
                }
                else {
                    this.beforeShowEvent.subscribe(onBeforeShow);
                }
            }
        },
        initEvents: function() {
            Menu.superclass.initEvents.call(this);
            var SIGNATURE = CustomEvent.LIST;
            this.mouseOverEvent = this.createEvent(EVENT_TYPES.MOUSE_OVER);
            this.mouseOverEvent.signature = SIGNATURE;
            this.mouseOutEvent = this.createEvent(EVENT_TYPES.MOUSE_OUT);
            this.mouseOutEvent.signature = SIGNATURE;
            this.mouseDownEvent = this.createEvent(EVENT_TYPES.MOUSE_DOWN);
            this.mouseDownEvent.signature = SIGNATURE;
            this.mouseUpEvent = this.createEvent(EVENT_TYPES.MOUSE_UP);
            this.mouseUpEvent.signature = SIGNATURE;
            this.clickEvent = this.createEvent(EVENT_TYPES.CLICK);
            this.clickEvent.signature = SIGNATURE;
            this.keyPressEvent = this.createEvent(EVENT_TYPES.KEY_PRESS);
            this.keyPressEvent.signature = SIGNATURE;
            this.keyDownEvent = this.createEvent(EVENT_TYPES.KEY_DOWN);
            this.keyDownEvent.signature = SIGNATURE;
            this.keyUpEvent = this.createEvent(EVENT_TYPES.KEY_UP);
            this.keyUpEvent.signature = SIGNATURE;
            this.focusEvent = this.createEvent(EVENT_TYPES.FOCUS);
            this.focusEvent.signature = SIGNATURE;
            this.blurEvent = this.createEvent(EVENT_TYPES.BLUR);
            this.blurEvent.signature = SIGNATURE;
            this.itemAddedEvent = this.createEvent(EVENT_TYPES.ITEM_ADDED);
            this.itemAddedEvent.signature = SIGNATURE;
            this.itemRemovedEvent = this.createEvent(EVENT_TYPES.ITEM_REMOVED);
            this.itemRemovedEvent.signature = SIGNATURE;
        },
        getRoot: function() {
            var oItem = this.parent,
            oParentMenu;
            if (oItem) {
                oParentMenu = oItem.parent;
                return oParentMenu ? oParentMenu.getRoot() : this;
            }
            else {
                return this;
            }
        },
        toString: function() {
            var sReturnVal = "Menu",
            sId = this.id;
            if (sId) {
                sReturnVal += (" " + sId);
            }
            return sReturnVal;
        },
        setItemGroupTitle: function(p_sGroupTitle, p_nGroupIndex) {
            var nGroupIndex, oTitle, i, nFirstIndex;
            if (typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) {
                nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex: 0;
                oTitle = this._aGroupTitleElements[nGroupIndex];
                if (oTitle) {
                    oTitle.innerHTML = p_sGroupTitle;
                }
                else {
                    oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME);
                    oTitle.innerHTML = p_sGroupTitle;
                    this._aGroupTitleElements[nGroupIndex] = oTitle;
                }
                i = this._aGroupTitleElements.length - 1;
                do {
                    if (this._aGroupTitleElements[i]) {
                        Dom.removeClass(this._aGroupTitleElements[i], "first-of-type");
                        nFirstIndex = i;
                    }
                }
                while (i--);
                if (nFirstIndex !== null) {
                    Dom.addClass(this._aGroupTitleElements[nFirstIndex], "first-of-type");
                }
                this.changeContentEvent.fire();
            }
        },
        addItem: function(p_oItem, p_nGroupIndex) {
            if (p_oItem) {
                return this._addItemToGroup(p_nGroupIndex, p_oItem);
            }
        },
        addItems: function(p_aItems, p_nGroupIndex) {
            var nItems, aItems, oItem, i;
            if (Lang.isArray(p_aItems)) {
                nItems = p_aItems.length;
                aItems = [];
                for (i = 0; i < nItems; i++) {
                    oItem = p_aItems[i];
                    if (oItem) {
                        if (Lang.isArray(oItem)) {
                            aItems[aItems.length] = this.addItems(oItem, i);
                        }
                        else {
                            aItems[aItems.length] = this._addItemToGroup(p_nGroupIndex, oItem);
                        }
                    }
                }
                if (aItems.length) {
                    return aItems;
                }
            }
        },
        insertItem: function(p_oItem, p_nItemIndex, p_nGroupIndex) {
            if (p_oItem) {
                return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
            }
        },
        removeItem: function(p_oObject, p_nGroupIndex) {
            var oItem;
            if (typeof p_oObject != "undefined") {
                if (p_oObject instanceof YAHOO.widget.MenuItem) {
                    oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject);
                }
                else if (typeof p_oObject == "number") {
                    oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject);
                }
                if (oItem) {
                    oItem.destroy();
                    return oItem;
                }
            }
        },
        getItems: function() {
            var aGroups = this._aItemGroups,
            nGroups = aGroups.length;
            return ((nGroups == 1) ? aGroups[0] : (Array.prototype.concat.apply([], aGroups)));
        },
        getItemGroups: function() {
            return this._aItemGroups;
        },
        getItem: function(p_nItemIndex, p_nGroupIndex) {
            var aGroup;
            if (typeof p_nItemIndex == "number") {
                aGroup = this._getItemGroup(p_nGroupIndex);
                if (aGroup) {
                    return aGroup[p_nItemIndex];
                }
            }
        },
        getSubmenus: function() {
            var aItems = this.getItems(),
            nItems = aItems.length,
            aSubmenus,
            oSubmenu,
            oItem,
            i;
            if (nItems > 0) {
                aSubmenus = [];
                for (i = 0; i < nItems; i++) {
                    oItem = aItems[i];
                    if (oItem) {
                        oSubmenu = oItem.cfg.getProperty("submenu");
                        if (oSubmenu) {
                            aSubmenus[aSubmenus.length] = oSubmenu;
                        }
                    }
                }
            }
            return aSubmenus;
        },
        clearContent: function() {
            var aItems = this.getItems(),
            nItems = aItems.length,
            oElement = this.element,
            oBody = this.body,
            oHeader = this.header,
            oFooter = this.footer,
            oItem,
            oSubmenu,
            i;
            if (nItems > 0) {
                i = nItems - 1;
                do {
                    oItem = aItems[i];
                    if (oItem) {
                        oSubmenu = oItem.cfg.getProperty("submenu");
                        if (oSubmenu) {
                            this.cfg.configChangedEvent.unsubscribe(this._onParentMenuConfigChange, oSubmenu);
                            this.renderEvent.unsubscribe(this._onParentMenuRender, oSubmenu);
                        }
                        this.removeItem(oItem);
                    }
                }
                while (i--);
            }
            if (oHeader) {
                Event.purgeElement(oHeader);
                oElement.removeChild(oHeader);
            }
            if (oFooter) {
                Event.purgeElement(oFooter);
                oElement.removeChild(oFooter);
            }
            if (oBody) {
                Event.purgeElement(oBody);
                oBody.innerHTML = "";
            }
            this._aItemGroups = [];
            this._aListElements = [];
            this._aGroupTitleElements = [];
            this.cfg.setProperty("width", null);
        },
        destroy: function() {
            Module.textResizeEvent.unsubscribe(this._onTextResize, this);
            this.clearContent();
            this._aItemGroups = null;
            this._aListElements = null;
            this._aGroupTitleElements = null;
            Menu.superclass.destroy.call(this);
        },
        setInitialFocus: function() {
            var oItem = this._getFirstEnabledItem();
            if (oItem) {
                oItem.focus();
            }
        },
        setInitialSelection: function() {
            var oItem = this._getFirstEnabledItem();
            if (oItem) {
                oItem.cfg.setProperty("selected", true);
            }
        },
        clearActiveItem: function(p_bBlur) {
            if (this.cfg.getProperty("showdelay") > 0) {
                this._cancelShowDelay();
            }
            var oActiveItem = this.activeItem,
            oConfig, oSubmenu;
            if (oActiveItem) {
                oConfig = oActiveItem.cfg;
                if (p_bBlur) {
                    oActiveItem.blur();
                }
                oConfig.setProperty("selected", false);
                oSubmenu = oConfig.getProperty("submenu");
                if (oSubmenu) {
                    oSubmenu.hide();
                }
                this.activeItem = null;
            }
        },
        focus: function() {
            if (!this.hasFocus()) {
                this.setInitialFocus();
            }
        },
        blur: function() {
            var oItem;
            if (this.hasFocus()) {
                oItem = MenuManager.getFocusedMenuItem();
                if (oItem) {
                    oItem.blur();
                }
            }
        },
        hasFocus: function() {
            return (MenuManager.getFocusedMenu() == this.getRoot());
        },
        subscribe: function() {
            function onItemAdded(p_sType, p_aArgs, p_oObject) {
                var oItem = p_aArgs[0],
                oSubmenu = oItem.cfg.getProperty("submenu");
                if (oSubmenu) {
                    oSubmenu.subscribe.apply(oSubmenu, p_oObject);
                }
            }
            Menu.superclass.subscribe.apply(this, arguments);
            Menu.superclass.subscribe.call(this, "itemAdded", onItemAdded, arguments);
            var aSubmenus = this.getSubmenus(),
            nSubmenus,
            oSubmenu,
            i;
            if (aSubmenus) {
                nSubmenus = aSubmenus.length;
                if (nSubmenus > 0) {
                    i = nSubmenus - 1;
                    do {
                        oSubmenu = aSubmenus[i];
                        oSubmenu.subscribe.apply(oSubmenu, arguments);
                    }
                    while (i--);
                }
            }
        },
        initDefaultConfig: function() {
            Menu.superclass.initDefaultConfig.call(this);
            var oConfig = this.cfg;
            oConfig.addProperty(DEFAULT_CONFIG.VISIBLE.key, {
                handler: this.configVisible,
                value: DEFAULT_CONFIG.VISIBLE.value,
                validator: DEFAULT_CONFIG.VISIBLE.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, {
                handler: this.configConstrainToViewport,
                value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value,
                validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator,
                supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
            });
            oConfig.addProperty(DEFAULT_CONFIG.POSITION.key, {
                handler: this.configPosition,
                value: DEFAULT_CONFIG.POSITION.value,
                validator: DEFAULT_CONFIG.POSITION.validator,
                supercedes: DEFAULT_CONFIG.POSITION.supercedes
            });
            oConfig.addProperty(DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, {
                value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value
            });
            oConfig.addProperty(DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, {
                value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value,
                validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.SHOW_DELAY.key, {
                value: DEFAULT_CONFIG.SHOW_DELAY.value,
                validator: DEFAULT_CONFIG.SHOW_DELAY.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.HIDE_DELAY.key, {
                handler: this.configHideDelay,
                value: DEFAULT_CONFIG.HIDE_DELAY.value,
                validator: DEFAULT_CONFIG.HIDE_DELAY.validator,
                suppressEvent: DEFAULT_CONFIG.HIDE_DELAY.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.key, {
                value: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.value,
                validator: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.CLICK_TO_HIDE.key, {
                value: DEFAULT_CONFIG.CLICK_TO_HIDE.value,
                validator: DEFAULT_CONFIG.CLICK_TO_HIDE.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.CONTAINER.key, {
                handler: this.configContainer,
                value: document.body
            });
            oConfig.addProperty(DEFAULT_CONFIG.MAX_HEIGHT.key, {
                handler: this.configMaxHeight,
                value: DEFAULT_CONFIG.MAX_HEIGHT.value,
                validator: DEFAULT_CONFIG.MAX_HEIGHT.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.CLASS_NAME.key, {
                handler: this.configClassName,
                value: DEFAULT_CONFIG.CLASS_NAME.value,
                validator: DEFAULT_CONFIG.CLASS_NAME.validator
            });
            oConfig.addProperty(DEFAULT_CONFIG.DISABLED.key, {
                handler: this.configDisabled,
                value: DEFAULT_CONFIG.DISABLED.value,
                validator: DEFAULT_CONFIG.DISABLED.validator
            });
        }
    });
})();
(function() {
    YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) {
        if (p_oObject) {
            if (p_oConfig) {
                this.parent = p_oConfig.parent;
                this.value = p_oConfig.value;
                this.id = p_oConfig.id;
            }
            this.init(p_oObject, p_oConfig);
        }
    };
    var Dom = YAHOO.util.Dom,
    Module = YAHOO.widget.Module,
    Menu = YAHOO.widget.Menu,
    MenuItem = YAHOO.widget.MenuItem,
    CustomEvent = YAHOO.util.CustomEvent,
    Lang = YAHOO.lang,
    m_oMenuItemTemplate, EVENT_TYPES = {
        "MOUSE_OVER": "mouseover",
        "MOUSE_OUT": "mouseout",
        "MOUSE_DOWN": "mousedown",
        "MOUSE_UP": "mouseup",
        "CLICK": "click",
        "KEY_PRESS": "keypress",
        "KEY_DOWN": "keydown",
        "KEY_UP": "keyup",
        "ITEM_ADDED": "itemAdded",
        "ITEM_REMOVED": "itemRemoved",
        "FOCUS": "focus",
        "BLUR": "blur",
        "DESTROY": "destroy"
    },
    DEFAULT_CONFIG = {
        "TEXT": {
            key: "text",
            value: "",
            validator: Lang.isString,
            suppressEvent: true
        },
        "HELP_TEXT": {
            key: "helptext",
            supercedes: ["text"]
        },
        "URL": {
            key: "url",
            value: "#",
            suppressEvent: true
        },
        "TARGET": {
            key: "target",
            suppressEvent: true
        },
        "EMPHASIS": {
            key: "emphasis",
            value: false,
            validator: Lang.isBoolean,
            suppressEvent: true,
            supercedes: ["text"]
        },
        "STRONG_EMPHASIS": {
            key: "strongemphasis",
            value: false,
            validator: Lang.isBoolean,
            suppressEvent: true,
            supercedes: ["text"]
        },
        "CHECKED": {
            key: "checked",
            value: false,
            validator: Lang.isBoolean,
            suppressEvent: true,
            supercedes: ["text"]
        },
        "DISABLED": {
            key: "disabled",
            value: false,
            validator: Lang.isBoolean,
            suppressEvent: true,
            supercedes: ["text"]
        },
        "SELECTED": {
            key: "selected",
            value: false,
            validator: Lang.isBoolean,
            suppressEvent: true
        },
        "SUBMENU": {
            key: "submenu",
            supercedes: ["text"]
        },
        "ONCLICK": {
            key: "onclick"
        },
        "CLASS_NAME": {
            key: "classname",
            value: null,
            validator: Lang.isString
        }
    };
    MenuItem.prototype = {
        COLLAPSED_SUBMENU_INDICATOR_TEXT: "Submenu collapsed.  Click to expand submenu.",
        EXPANDED_SUBMENU_INDICATOR_TEXT: "Submenu expanded.  Click to collapse submenu.",
        DISABLED_SUBMENU_INDICATOR_TEXT: "Submenu collapsed.  (Item disabled.)",
        CHECKED_TEXT: "Menu item checked.",
        DISABLED_CHECKED_TEXT: "Checked. (Item disabled.)",
        CSS_CLASS_NAME: "yuimenuitem",
        CSS_LABEL_CLASS_NAME: "yuimenuitemlabel",
        SUBMENU_TYPE: null,
        _oAnchor: null,
        _oHelpTextEM: null,
        _oSubmenu: null,
        _oCheckedIndicator: null,
        _oOnclickAttributeValue: null,
        _sClassName: null,
        constructor: MenuItem,
        index: null,
        groupIndex: null,
        parent: null,
        element: null,
        srcElement: null,
        value: null,
        submenuIndicator: null,
        browser: Module.prototype.browser,
        id: null,
        destroyEvent: null,
        mouseOverEvent: null,
        mouseOutEvent: null,
        mouseDownEvent: null,
        mouseUpEvent: null,
        clickEvent: null,
        keyPressEvent: null,
        keyDownEvent: null,
        keyUpEvent: null,
        focusEvent: null,
        blurEvent: null,
        init: function(p_oObject, p_oConfig) {
            if (!this.SUBMENU_TYPE) {
                this.SUBMENU_TYPE = Menu;
            }
            this.cfg = new YAHOO.util.Config(this);
            this.initDefaultConfig();
            var SIGNATURE = CustomEvent.LIST,
            oConfig = this.cfg,
            sURL = "#",
            oAnchor, sTarget, sText, sId;
            if (Lang.isString(p_oObject)) {
                this._createRootNodeStructure();
                oConfig.queueProperty("text", p_oObject);
            }
            else if (p_oObject && p_oObject.tagName) {
                switch (p_oObject.tagName.toUpperCase()) {
                case "OPTION":
                    this._createRootNodeStructure();
                    oConfig.queueProperty("text", p_oObject.text);
                    this.srcElement = p_oObject;
                    break;
                case "OPTGROUP":
                    this._createRootNodeStructure();
                    oConfig.queueProperty("text", p_oObject.label);
                    this.srcElement = p_oObject;
                    this._initSubTree();
                    break;
                case "LI":
                    oAnchor = Dom.getFirstChild(p_oObject);
                    if (oAnchor) {
                        sURL = oAnchor.getAttribute("href");
                        sTarget = oAnchor.getAttribute("target");
                        sText = oAnchor.innerHTML;
                    }
                    this.srcElement = p_oObject;
                    this.element = p_oObject;
                    this._oAnchor = oAnchor;
                    oConfig.setProperty("text", sText, true);
                    oConfig.setProperty("url", sURL, true);
                    oConfig.setProperty("target", sTarget, true);
                    this._initSubTree();
                    break;
                }
            }
            if (this.element) {
                sId = this.element.id;
                if (!sId) {
                    sId = this.id || Dom.generateId();
                    this.element.id = sId;
                }
                this.id = sId;
                Dom.addClass(this.element, this.CSS_CLASS_NAME);
                Dom.addClass(this._oAnchor, this.CSS_LABEL_CLASS_NAME);
                this.mouseOverEvent = this.createEvent(EVENT_TYPES.MOUSE_OVER);
                this.mouseOverEvent.signature = SIGNATURE;
                this.mouseOutEvent = this.createEvent(EVENT_TYPES.MOUSE_OUT);
                this.mouseOutEvent.signature = SIGNATURE;
                this.mouseDownEvent = this.createEvent(EVENT_TYPES.MOUSE_DOWN);
                this.mouseDownEvent.signature = SIGNATURE;
                this.mouseUpEvent = this.createEvent(EVENT_TYPES.MOUSE_UP);
                this.mouseUpEvent.signature = SIGNATURE;
                this.clickEvent = this.createEvent(EVENT_TYPES.CLICK);
                this.clickEvent.signature = SIGNATURE;
                this.keyPressEvent = this.createEvent(EVENT_TYPES.KEY_PRESS);
                this.keyPressEvent.signature = SIGNATURE;
                this.keyDownEvent = this.createEvent(EVENT_TYPES.KEY_DOWN);
                this.keyDownEvent.signature = SIGNATURE;
                this.keyUpEvent = this.createEvent(EVENT_TYPES.KEY_UP);
                this.keyUpEvent.signature = SIGNATURE;
                this.focusEvent = this.createEvent(EVENT_TYPES.FOCUS);
                this.focusEvent.signature = SIGNATURE;
                this.blurEvent = this.createEvent(EVENT_TYPES.BLUR);
                this.blurEvent.signature = SIGNATURE;
                this.destroyEvent = this.createEvent(EVENT_TYPES.DESTROY);
                this.destroyEvent.signature = SIGNATURE;
                if (p_oConfig) {
                    oConfig.applyConfig(p_oConfig);
                }
                oConfig.fireQueue();
            }
        },
        _createRootNodeStructure: function() {
            var oElement, oAnchor;
            if (!m_oMenuItemTemplate) {
                m_oMenuItemTemplate = document.createElement("li");
                m_oMenuItemTemplate.innerHTML = "<a href=\"#\"></a>";
            }
            oElement = m_oMenuItemTemplate.cloneNode(true);
            oElement.className = this.CSS_CLASS_NAME;
            oAnchor = oElement.firstChild;
            oAnchor.className = this.CSS_LABEL_CLASS_NAME;
            this.element = oElement;
            this._oAnchor = oAnchor;
        },
        _initSubTree: function() {
            var oSrcEl = this.srcElement,
            oConfig = this.cfg,
            oNode, aOptions, nOptions, oMenu, n;
            if (oSrcEl.childNodes.length > 0) {
                if (this.parent.lazyLoad && this.parent.srcElement && this.parent.srcElement.tagName.toUpperCase() == "SELECT") {
                    oConfig.setProperty("submenu", {
                        id: Dom.generateId(),
                        itemdata: oSrcEl.childNodes
                    });
                }
                else {
                    oNode = oSrcEl.firstChild;
                    aOptions = [];
                    do {
                        if (oNode && oNode.tagName) {
                            switch (oNode.tagName.toUpperCase()) {
                            case "DIV":
                                oConfig.setProperty("submenu", oNode);
                                break;
                            case "OPTION":
                                aOptions[aOptions.length] = oNode;
                                break;
                            }
                        }
                    }
                    while ((oNode = oNode.nextSibling));
                    nOptions = aOptions.length;
                    if (nOptions > 0) {
                        oMenu = new this.SUBMENU_TYPE(Dom.generateId());
                        oConfig.setProperty("submenu", oMenu);
                        for (n = 0; n < nOptions; n++) {
                            oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n])));
                        }
                    }
                }
            }
        },
        configText: function(p_sType, p_aArgs, p_oItem) {
            var sText = p_aArgs[0],
            oConfig = this.cfg,
            oAnchor = this._oAnchor,
            sHelpText = oConfig.getProperty("helptext"),
            sHelpTextHTML = "",
            sCheckHTML = "",
            oSubmenu = oConfig.getProperty("submenu"),
            sSubmenuIndicatorHTML = "",
            sEmphasisStartTag = "",
            sEmphasisEndTag = "";
            if (sText) {
                if (sHelpText) {
                    sHelpTextHTML = "<em class=\"helptext\">" + sHelpText + "</em>";
                }
                if (oConfig.getProperty("checked")) {
                    sCheckHTML = "<em class=\"checkedindicator\">" + this.CHECKED_TEXT + "</em>";
                }
                if (oSubmenu) {
                    sSubmenuIndicatorHTML = "<em class=\"submenuindicator\">" + ((oSubmenu instanceof Menu && oSubmenu.cfg.getProperty("visible")) ? this.EXPANDED_SUBMENU_INDICATOR_TEXT: this.COLLAPSED_SUBMENU_INDICATOR_TEXT) + "</em>";
                }
                if (oConfig.getProperty("emphasis")) {
                    sEmphasisStartTag = "<em>";
                    sEmphasisEndTag = "</em>";
                }
                if (oConfig.getProperty("strongemphasis")) {
                    sEmphasisStartTag = "<strong>";
                    sEmphasisEndTag = "</strong>";
                }
                oAnchor.innerHTML = (sEmphasisStartTag + sText + sEmphasisEndTag + sHelpTextHTML + sCheckHTML + sSubmenuIndicatorHTML);
                if (oSubmenu) {
                    this.submenuIndicator = oAnchor.lastChild;
                }
            }
        },
        configHelpText: function(p_sType, p_aArgs, p_oItem) {
            var sHelpText = p_aArgs[0],
            oAnchor = this._oAnchor;
            if (sHelpText) {
                Dom.addClass(oAnchor, "hashelptext");
            }
            else {
                Dom.removeClass(oAnchor, "hashelptext");
            }
            this.cfg.refireEvent("text");
        },
        configURL: function(p_sType, p_aArgs, p_oItem) {
            var sURL = p_aArgs[0];
            if (!sURL) {
                sURL = "#";
            }
            this._oAnchor.setAttribute("href", sURL);
        },
        configTarget: function(p_sType, p_aArgs, p_oItem) {
            var sTarget = p_aArgs[0],
            oAnchor = this._oAnchor;
            if (sTarget && sTarget.length > 0) {
                oAnchor.setAttribute("target", sTarget);
            }
            else {
                oAnchor.removeAttribute("target");
            }
        },
        configEmphasis: function(p_sType, p_aArgs, p_oItem) {
            var bEmphasis = p_aArgs[0],
            oConfig = this.cfg;
            if (bEmphasis && oConfig.getProperty("strongemphasis")) {
                oConfig.setProperty("strongemphasis", false);
            }
            oConfig.refireEvent("text");
        },
        configStrongEmphasis: function(p_sType, p_aArgs, p_oItem) {
            var bStrongEmphasis = p_aArgs[0],
            oConfig = this.cfg;
            if (bStrongEmphasis && oConfig.getProperty("emphasis")) {
                oConfig.setProperty("emphasis", false);
            }
            oConfig.refireEvent("text");
        },
        configChecked: function(p_sType, p_aArgs, p_oItem) {
            var bChecked = p_aArgs[0],
            oAnchor = this._oAnchor;
            if (bChecked) {
                Dom.addClass(oAnchor, "checked");
            }
            else {
                Dom.removeClass(oAnchor, "checked");
            }
            this.cfg.refireEvent("text");
        },
        configDisabled: function(p_sType, p_aArgs, p_oItem) {
            var bDisabled = p_aArgs[0],
            oConfig = this.cfg,
            oAnchor = this._oAnchor;
            if (bDisabled) {
                if (oConfig.getProperty("selected")) {
                    oConfig.setProperty("selected", false);
                }
                oAnchor.removeAttribute("href");
                Dom.addClass(oAnchor, "disabled");
            }
            else {
                oAnchor.setAttribute("href", oConfig.getProperty("url"));
                Dom.removeClass(oAnchor, "disabled");
            }
        },
        configSelected: function(p_sType, p_aArgs, p_oItem) {
            var bSelected, oAnchor;
            if (!this.cfg.getProperty("disabled")) {
                bSelected = p_aArgs[0];
                oAnchor = this._oAnchor;
                if (bSelected) {
                    Dom.addClass(oAnchor, "selected");
                }
                else {
                    Dom.removeClass(oAnchor, "selected");
                }
            }
        },
        configSubmenu: function(p_sType, p_aArgs, p_oItem) {
            var oAnchor = this._oAnchor,
            oSubmenu = p_aArgs[0],
            oSubmenuIndicator = this.submenuIndicator,
            oConfig = this.cfg,
            bLazyLoad = this.parent && this.parent.lazyLoad,
            oMenu,
            sSubmenuId,
            oSubmenuConfig;
            if (oSubmenu) {
                if (oSubmenu instanceof Menu) {
                    oMenu = oSubmenu;
                    oMenu.parent = this;
                    oMenu.lazyLoad = bLazyLoad;
                }
                else if (typeof oSubmenu == "object" && oSubmenu.id && !oSubmenu.nodeType) {
                    sSubmenuId = oSubmenu.id;
                    oSubmenuConfig = oSubmenu;
                    oSubmenuConfig.lazyload = bLazyLoad;
                    oSubmenuConfig.parent = this;
                    oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig);
                    this.cfg.setProperty("submenu", oMenu, true);
                }
                else {
                    oMenu = new this.SUBMENU_TYPE(oSubmenu, {
                        lazyload: bLazyLoad,
                        parent: this
                    });
                    this.cfg.setProperty("submenu", oMenu, true);
                }
                if (oMenu) {
                    Dom.addClass(oAnchor, "hassubmenu");
                    this._oSubmenu = oMenu;
                }
            }
            else {
                Dom.removeClass(oAnchor, "hassubmenu");
                if (oSubmenuIndicator) {
                    oAnchor.removeChild(oSubmenuIndicator);
                }
                if (this._oSubmenu) {
                    this._oSubmenu.destroy();
                }
            }
            oConfig.refireEvent("text");
        },
        configOnClick: function(p_sType, p_aArgs, p_oItem) {
            var oObject = p_aArgs[0];
            if (this._oOnclickAttributeValue && (this._oOnclickAttributeValue != oObject)) {
                this.clickEvent.unsubscribe(this._oOnclickAttributeValue.fn, this._oOnclickAttributeValue.obj);
                this._oOnclickAttributeValue = null;
            }
            if (!this._oOnclickAttributeValue && typeof oObject == "object" && typeof oObject.fn == "function") {
                this.clickEvent.subscribe(oObject.fn, ((!YAHOO.lang.isUndefined(oObject.obj)) ? oObject.obj: this), oObject.scope);
                this._oOnclickAttributeValue = oObject;
            }
        },
        configClassName: function(p_sType, p_aArgs, p_oItem) {
            var sClassName = p_aArgs[0];
            if (this._sClassName) {
                Dom.removeClass(this.element, this._sClassName);
            }
            Dom.addClass(this.element, sClassName);
            this._sClassName = sClassName;
        },
        initDefaultConfig: function() {
            var oConfig = this.cfg;
            oConfig.addProperty(DEFAULT_CONFIG.TEXT.key, {
                handler: this.configText,
                value: DEFAULT_CONFIG.TEXT.value,
                validator: DEFAULT_CONFIG.TEXT.validator,
                suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.HELP_TEXT.key, {
                handler: this.configHelpText
            });
            oConfig.addProperty(DEFAULT_CONFIG.URL.key, {
                handler: this.configURL,
                value: DEFAULT_CONFIG.URL.value,
                suppressEvent: DEFAULT_CONFIG.URL.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.TARGET.key, {
                handler: this.configTarget,
                suppressEvent: DEFAULT_CONFIG.TARGET.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.EMPHASIS.key, {
                handler: this.configEmphasis,
                value: DEFAULT_CONFIG.EMPHASIS.value,
                validator: DEFAULT_CONFIG.EMPHASIS.validator,
                suppressEvent: DEFAULT_CONFIG.EMPHASIS.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.STRONG_EMPHASIS.key, {
                handler: this.configStrongEmphasis,
                value: DEFAULT_CONFIG.STRONG_EMPHASIS.value,
                validator: DEFAULT_CONFIG.STRONG_EMPHASIS.validator,
                suppressEvent: DEFAULT_CONFIG.STRONG_EMPHASIS.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.CHECKED.key, {
                handler: this.configChecked,
                value: DEFAULT_CONFIG.CHECKED.value,
                validator: DEFAULT_CONFIG.CHECKED.validator,
                suppressEvent: DEFAULT_CONFIG.CHECKED.suppressEvent,
                supercedes: DEFAULT_CONFIG.CHECKED.supercedes
            });
            oConfig.addProperty(DEFAULT_CONFIG.DISABLED.key, {
                handler: this.configDisabled,
                value: DEFAULT_CONFIG.DISABLED.value,
                validator: DEFAULT_CONFIG.DISABLED.validator,
                suppressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.SELECTED.key, {
                handler: this.configSelected,
                value: DEFAULT_CONFIG.SELECTED.value,
                validator: DEFAULT_CONFIG.SELECTED.validator,
                suppressEvent: DEFAULT_CONFIG.SELECTED.suppressEvent
            });
            oConfig.addProperty(DEFAULT_CONFIG.SUBMENU.key, {
                handler: this.configSubmenu
            });
            oConfig.addProperty(DEFAULT_CONFIG.ONCLICK.key, {
                handler: this.configOnClick
            });
            oConfig.addProperty(DEFAULT_CONFIG.CLASS_NAME.key, {
                handler: this.configClassName,
                value: DEFAULT_CONFIG.CLASS_NAME.value,
                validator: DEFAULT_CONFIG.CLASS_NAME.validator
            });
        },
        getNextEnabledSibling: function() {
            var nGroupIndex, aItemGroups, oNextItem, nNextGroupIndex, aNextGroup;
            function getNextArrayItem(p_aArray, p_nStartIndex) {
                return p_aArray[p_nStartIndex] || getNextArrayItem(p_aArray, (p_nStartIndex + 1));
            }
            if (this.parent instanceof Menu) {
                nGroupIndex = this.groupIndex;
                aItemGroups = this.parent.getItemGroups();
                if (this.index < (aItemGroups[nGroupIndex].length - 1)) {
                    oNextItem = getNextArrayItem(aItemGroups[nGroupIndex], (this.index + 1));
                }
                else {
                    if (nGroupIndex < (aItemGroups.length - 1)) {
                        nNextGroupIndex = nGroupIndex + 1;
                    }
                    else {
                        nNextGroupIndex = 0;
                    }
                    aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex);
                    oNextItem = getNextArrayItem(aNextGroup, 0);
                }
                return (oNextItem.cfg.getProperty("disabled") || oNextItem.element.style.display == "none") ? oNextItem.getNextEnabledSibling() : oNextItem;
            }
        },
        getPreviousEnabledSibling: function() {
            var nGroupIndex, aItemGroups, oPreviousItem, nPreviousGroupIndex, aPreviousGroup;
            function getPreviousArrayItem(p_aArray, p_nStartIndex) {
                return p_aArray[p_nStartIndex] || getPreviousArrayItem(p_aArray, (p_nStartIndex - 1));
            }
            function getFirstItemIndex(p_aArray, p_nStartIndex) {
                return p_aArray[p_nStartIndex] ? p_nStartIndex: getFirstItemIndex(p_aArray, (p_nStartIndex + 1));
            }
            if (this.parent instanceof Menu) {
                nGroupIndex = this.groupIndex;
                aItemGroups = this.parent.getItemGroups();
                if (this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0)) {
                    oPreviousItem = getPreviousArrayItem(aItemGroups[nGroupIndex], (this.index - 1));
                }
                else {
                    if (nGroupIndex > getFirstItemIndex(aItemGroups, 0)) {
                        nPreviousGroupIndex = nGroupIndex - 1;
                    }
                    else {
                        nPreviousGroupIndex = aItemGroups.length - 1;
                    }
                    aPreviousGroup = getPreviousArrayItem(aItemGroups, nPreviousGroupIndex);
                    oPreviousItem = getPreviousArrayItem(aPreviousGroup, (aPreviousGroup.length - 1));
                }
                return (oPreviousItem.cfg.getProperty("disabled") || oPreviousItem.element.style.display == "none") ? oPreviousItem.getPreviousEnabledSibling() : oPreviousItem;
            }
        },
        focus: function() {
            var oParent = this.parent,
            oAnchor = this._oAnchor,
            oActiveItem = oParent.activeItem,
            me = this;
            function setFocus() {
                try {
                    if (YAHOO.env.ua.ie && !document.hasFocus()) {
                        return;
                    }
                    oAnchor.focus();
                }
                catch(e) {}
            }
            if (!this.cfg.getProperty("disabled") && oParent && oParent.cfg.getProperty("visible") && this.element.style.display != "none") {
                if (oActiveItem) {
                    oActiveItem.blur();
                }
                window.setTimeout(setFocus, 0);
                this.focusEvent.fire();
            }
        },
        blur: function() {
            var oParent = this.parent;
            if (!this.cfg.getProperty("disabled") && oParent && oParent.cfg.getProperty("visible")) {
                this._oAnchor.blur();
                this.blurEvent.fire();
            }
        },
        hasFocus: function() {
            return (YAHOO.widget.MenuManager.getFocusedMenuItem() == this);
        },
        destroy: function() {
            var oEl = this.element,
            oSubmenu, oParentNode;
            if (oEl) {
                oSubmenu = this.cfg.getProperty("submenu");
                if (oSubmenu) {
                    oSubmenu.destroy();
                }
                this.mouseOverEvent.unsubscribeAll();
                this.mouseOutEvent.unsubscribeAll();
                this.mouseDownEvent.unsubscribeAll();
                this.mouseUpEvent.unsubscribeAll();
                this.clickEvent.unsubscribeAll();
                this.keyPressEvent.unsubscribeAll();
                this.keyDownEvent.unsubscribeAll();
                this.keyUpEvent.unsubscribeAll();
                this.focusEvent.unsubscribeAll();
                this.blurEvent.unsubscribeAll();
                this.cfg.configChangedEvent.unsubscribeAll();
                oParentNode = oEl.parentNode;
                if (oParentNode) {
                    oParentNode.removeChild(oEl);
                    this.destroyEvent.fire();
                }
                this.destroyEvent.unsubscribeAll();
            }
        },
        toString: function() {
            var sReturnVal = "MenuItem",
            sId = this.id;
            if (sId) {
                sReturnVal += (" " + sId);
            }
            return sReturnVal;
        }
    };
    Lang.augmentProto(MenuItem, YAHOO.util.EventProvider);
})();
(function() {
    YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) {
        YAHOO.widget.ContextMenu.superclass.constructor.call(this, p_oElement, p_oConfig);
    };
    var Event = YAHOO.util.Event,
    ContextMenu = YAHOO.widget.ContextMenu,
    EVENT_TYPES = {
        "TRIGGER_CONTEXT_MENU": "triggerContextMenu",
        "CONTEXT_MENU": (YAHOO.env.ua.opera ? "mousedown": "contextmenu"),
        "CLICK": "click"
    },
    DEFAULT_CONFIG = {
        "TRIGGER": {
            key: "trigger"
        }
    };
    YAHOO.lang.extend(ContextMenu, YAHOO.widget.Menu, {
        _oTrigger: null,
        _bCancelled: false,
        contextEventTarget: null,
        triggerContextMenuEvent: null,
        init: function(p_oElement, p_oConfig) {
            if (!this.ITEM_TYPE) {
                this.ITEM_TYPE = YAHOO.widget.ContextMenuItem;
            }
            ContextMenu.superclass.init.call(this, p_oElement);
            this.beforeInitEvent.fire(ContextMenu);
            if (p_oConfig) {
                this.cfg.applyConfig(p_oConfig, true);
            }
            this.initEvent.fire(ContextMenu);
        },
        initEvents: function() {
            ContextMenu.superclass.initEvents.call(this);
            this.triggerContextMenuEvent = this.createEvent(EVENT_TYPES.TRIGGER_CONTEXT_MENU);
            this.triggerContextMenuEvent.signature = YAHOO.util.CustomEvent.LIST;
        },
        cancel: function() {
            this._bCancelled = true;
        },
        _removeEventHandlers: function() {
            var oTrigger = this._oTrigger;
            if (oTrigger) {
                Event.removeListener(oTrigger, EVENT_TYPES.CONTEXT_MENU, this._onTriggerContextMenu);
                if (YAHOO.env.ua.opera) {
                    Event.removeListener(oTrigger, EVENT_TYPES.CLICK, this._onTriggerClick);
                }
            }
        },
        _onTriggerClick: function(p_oEvent, p_oMenu) {
            if (p_oEvent.ctrlKey) {
                Event.stopEvent(p_oEvent);
            }
        },
        _onTriggerContextMenu: function(p_oEvent, p_oMenu) {
            if (p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) {
                return;
            }
            Event.stopEvent(p_oEvent);
            YAHOO.widget.MenuManager.hideVisible();
            this.contextEventTarget = Event.getTarget(p_oEvent);
            this.triggerContextMenuEvent.fire(p_oEvent);
            if (!this._bCancelled) {
                this.cfg.setProperty("xy", Event.getXY(p_oEvent));
                this.show();
            }
            this._bCancelled = false;
        },
        toString: function() {
            var sReturnVal = "ContextMenu",
            sId = this.id;
            if (sId) {
                sReturnVal += (" " + sId);
            }
            return sReturnVal;
        },
        initDefaultConfig: function() {
            ContextMenu.superclass.initDefaultConfig.call(this);
            this.cfg.addProperty(DEFAULT_CONFIG.TRIGGER.key, {
                handler: this.configTrigger
            });
        },
        destroy: function() {
            this._removeEventHandlers();
            ContextMenu.superclass.destroy.call(this);
        },
        configTrigger: function(p_sType, p_aArgs, p_oMenu) {
            var oTrigger = p_aArgs[0];
            if (oTrigger) {
                if (this._oTrigger) {
                    this._removeEventHandlers();
                }
                this._oTrigger = oTrigger;
                Event.on(oTrigger, EVENT_TYPES.CONTEXT_MENU, this._onTriggerContextMenu, this, true);
                if (YAHOO.env.ua.opera) {
                    Event.on(oTrigger, EVENT_TYPES.CLICK, this._onTriggerClick, this, true);
                }
            }
            else {
                this._removeEventHandlers();
            }
        }
    });
} ());
YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) {
    YAHOO.widget.ContextMenuItem.superclass.constructor.call(this, p_oObject, p_oConfig);
};
YAHOO.lang.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem, {
    init: function(p_oObject, p_oConfig) {
        if (!this.SUBMENU_TYPE) {
            this.SUBMENU_TYPE = YAHOO.widget.ContextMenu;
        }
        YAHOO.widget.ContextMenuItem.superclass.init.call(this, p_oObject);
        var oConfig = this.cfg;
        if (p_oConfig) {
            oConfig.applyConfig(p_oConfig, true);
        }
        oConfig.fireQueue();
    },
    toString: function() {
        var sReturnVal = "ContextMenuItem";
        if (this.cfg && this.cfg.getProperty("text")) {
            sReturnVal += (": " + this.cfg.getProperty("text"));
        }
        return sReturnVal;
    }
});
(function() {
    YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) {
        YAHOO.widget.MenuBar.superclass.constructor.call(this, p_oElement, p_oConfig);
    };
    function checkPosition(p_sPosition) {
        if (typeof p_sPosition == "string") {
            return ("dynamic,static".indexOf((p_sPosition.toLowerCase())) != -1);
        }
    }
    var Event = YAHOO.util.Event,
    Dom = YAHOO.util.Dom,
    MenuBar = YAHOO.widget.MenuBar,
    DEFAULT_CONFIG = {
        "POSITION": {
            key: "position",
            value: "static",
            validator: checkPosition,
            supercedes: ["visible"]
        },
        "SUBMENU_ALIGNMENT": {
            key: "submenualignment",
            value: ["tl", "bl"]
        },
        "AUTO_SUBMENU_DISPLAY": {
            key: "autosubmenudisplay",
            value: false,
            validator: YAHOO.lang.isBoolean
        }
    };
    YAHOO.lang.extend(MenuBar, YAHOO.widget.Menu, {
        init: function(p_oElement, p_oConfig) {
            if (!this.ITEM_TYPE) {
                this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
            }
            MenuBar.superclass.init.call(this, p_oElement);
            this.beforeInitEvent.fire(MenuBar);
            if (p_oConfig) {
                this.cfg.applyConfig(p_oConfig, true);
            }
            this.initEvent.fire(MenuBar);
        },
        CSS_CLASS_NAME: "yuimenubar",
        _onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) {
            var oEvent = p_aArgs[0],
            oItem = p_aArgs[1],
            oSubmenu,
            oItemCfg,
            oNextItem;
            if (oItem && !oItem.cfg.getProperty("disabled")) {
                oItemCfg = oItem.cfg;
                switch (oEvent.keyCode) {
                case 37:
                case 39:
                    if (oItem == this.activeItem && !oItemCfg.getProperty("selected")) {
                        oItemCfg.setProperty("selected", true);
                    }
                    else {
                        oNextItem = (oEvent.keyCode == 37) ? oItem.getPreviousEnabledSibling() : oItem.getNextEnabledSibling();
                        if (oNextItem) {
                            this.clearActiveItem();
                            oNextItem.cfg.setProperty("selected", true);
                            if (this.cfg.getProperty("autosubmenudisplay")) {
                                oSubmenu = oNextItem.cfg.getProperty("submenu");
                                if (oSubmenu) {
                                    oSubmenu.show();
                                }
                            }
                            oNextItem.focus();
                        }
                    }
                    Event.preventDefault(oEvent);
                    break;
                case 40:
                    if (this.activeItem != oItem) {
                        this.clearActiveItem();
                        oItemCfg.setProperty("selected", true);
                        oItem.focus();
                    }
                    oSubmenu = oItemCfg.getProperty("submenu");
                    if (oSubmenu) {
                        if (oSubmenu.cfg.getProperty("visible")) {
                            oSubmenu.setInitialSelection();
                            oSubmenu.setInitialFocus();
                        }
                        else {
                            oSubmenu.show();
                        }
                    }
                    Event.preventDefault(oEvent);
                    break;
                }
            }
            if (oEvent.keyCode == 27 && this.activeItem) {
                oSubmenu = this.activeItem.cfg.getProperty("submenu");
                if (oSubmenu && oSubmenu.cfg.getProperty("visible")) {
                    oSubmenu.hide();
                    this.activeItem.focus();
                }
                else {
                    this.activeItem.cfg.setProperty("selected", false);
                    this.activeItem.blur();
                }
                Event.preventDefault(oEvent);
            }
        },
        _onClick: function(p_sType, p_aArgs, p_oMenuBar) {
            MenuBar.superclass._onClick.call(this, p_sType, p_aArgs, p_oMenuBar);
            var oItem = p_aArgs[1],
            oEvent,
            oTarget,
            oActiveItem,
            oConfig,
            oSubmenu;
            if (oItem && !oItem.cfg.getProperty("disabled")) {
                oEvent = p_aArgs[0];
                oTarget = Event.getTarget(oEvent);
                oActiveItem = this.activeItem;
                oConfig = this.cfg;
                if (oActiveItem && oActiveItem != oItem) {
                    this.clearActiveItem();
                }
                oItem.cfg.setProperty("selected", true);
                oSubmenu = oItem.cfg.getProperty("submenu");
                if (oSubmenu && oTarget != oItem.submenuIndicator) {
                    if (oSubmenu.cfg.getProperty("visible")) {
                        oSubmenu.hide();
                    }
                    else {
                        oSubmenu.show();
                    }
                }
            }
        },
        toString: function() {
            var sReturnVal = "MenuBar",
            sId = this.id;
            if (sId) {
                sReturnVal += (" " + sId);
            }
            return sReturnVal;
        },
        initDefaultConfig: function() {
            MenuBar.superclass.initDefaultConfig.call(this);
            var oConfig = this.cfg;
            oConfig.addProperty(DEFAULT_CONFIG.POSITION.key, {
                handler: this.configPosition,
                value: DEFAULT_CONFIG.POSITION.value,
                validator: DEFAULT_CONFIG.POSITION.validator,
                supercedes: DEFAULT_CONFIG.POSITION.supercedes
            });
            oConfig.addProperty(DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, {
                value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value
            });
            oConfig.addProperty(DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, {
                value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value,
                validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator
            });
        }
    });
} ());
YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) {
    YAHOO.widget.MenuBarItem.superclass.constructor.call(this, p_oObject, p_oConfig);
};
YAHOO.lang.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, {
    init: function(p_oObject, p_oConfig) {
        if (!this.SUBMENU_TYPE) {
            this.SUBMENU_TYPE = YAHOO.widget.Menu;
        }
        YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject);
        var oConfig = this.cfg;
        if (p_oConfig) {
            oConfig.applyConfig(p_oConfig, true);
        }
        oConfig.fireQueue();
    },
    CSS_CLASS_NAME: "yuimenubaritem",
    CSS_LABEL_CLASS_NAME: "yuimenubaritemlabel",
    toString: function() {
        var sReturnVal = "MenuBarItem";
        if (this.cfg && this.cfg.getProperty("text")) {
            sReturnVal += (": " + this.cfg.getProperty("text"));
        }
        return sReturnVal;
    }
});
YAHOO.register("menu", YAHOO.widget.Menu, {
    version: "2.3.0",
    build: "442"
});
if (!YAHOO.util.DragDropMgr) {
    YAHOO.util.DragDropMgr = function() {
        var Event = YAHOO.util.Event;
        return {
            ids: {},
            handleIds: {},
            dragCurrent: null,
            dragOvers: {},
            deltaX: 0,
            deltaY: 0,
            preventDefault: true,
            stopPropagation: true,
            initialized: false,
            locked: false,
            interactionInfo: null,
            init: function() {
                this.initialized = true;
            },
            POINT: 0,
            INTERSECT: 1,
            STRICT_INTERSECT: 2,
            mode: 0,
            _execOnAll: function(sMethod, args) {
                for (var i in this.ids) {
                    for (var j in this.ids[i]) {
                        var oDD = this.ids[i][j];
                        if (!this.isTypeOfDD(oDD)) {
                            continue;
                        }
                        oDD[sMethod].apply(oDD, args);
                    }
                }
            },
            _onLoad: function() {
                this.init();
                Event.on(document, "mouseup", this.handleMouseUp, this, true);
                Event.on(document, "mousemove", this.handleMouseMove, this, true);
                Event.on(window, "unload", this._onUnload, this, true);
                Event.on(window, "resize", this._onResize, this, true);
            },
            _onResize: function(e) {
                this._execOnAll("resetConstraints", []);
            },
            lock: function() {
                this.locked = true;
            },
            unlock: function() {
                this.locked = false;
            },
            isLocked: function() {
                return this.locked;
            },
            locationCache: {},
            useCache: true,
            clickPixelThresh: 3,
            clickTimeThresh: 1000,
            dragThreshMet: false,
            clickTimeout: null,
            startX: 0,
            startY: 0,
            regDragDrop: function(oDD, sGroup) {
                if (!this.initialized) {
                    this.init();
                }
                if (!this.ids[sGroup]) {
                    this.ids[sGroup] = {};
                }
                this.ids[sGroup][oDD.id] = oDD;
            },
            removeDDFromGroup: function(oDD, sGroup) {
                if (!this.ids[sGroup]) {
                    this.ids[sGroup] = {};
                }
                var obj = this.ids[sGroup];
                if (obj && obj[oDD.id]) {
                    delete obj[oDD.id];
                }
            },
            _remove: function(oDD) {
                for (var g in oDD.groups) {
                    if (g && this.ids[g][oDD.id]) {
                        delete this.ids[g][oDD.id];
                    }
                }
                delete this.handleIds[oDD.id];
            },
            regHandle: function(sDDId, sHandleId) {
                if (!this.handleIds[sDDId]) {
                    this.handleIds[sDDId] = {};
                }
                this.handleIds[sDDId][sHandleId] = sHandleId;
            },
            isDragDrop: function(id) {
                return (this.getDDById(id)) ? true: false;
            },
            getRelated: function(p_oDD, bTargetsOnly) {
                var oDDs = [];
                for (var i in p_oDD.groups) {
                    for (j in this.ids[i]) {
                        var dd = this.ids[i][j];
                        if (!this.isTypeOfDD(dd)) {
                            continue;
                        }
                        if (!bTargetsOnly || dd.isTarget) {
                            oDDs[oDDs.length] = dd;
                        }
                    }
                }
                return oDDs;
            },
            isLegalTarget: function(oDD, oTargetDD) {
                var targets = this.getRelated(oDD, true);
                for (var i = 0, len = targets.length; i < len; ++i) {
                    if (targets[i].id == oTargetDD.id) {
                        return true;
                    }
                }
                return false;
            },
            isTypeOfDD: function(oDD) {
                return (oDD && oDD.__ygDragDrop);
            },
            isHandle: function(sDDId, sHandleId) {
                return (this.handleIds[sDDId] && this.handleIds[sDDId][sHandleId]);
            },
            getDDById: function(id) {
                for (var i in this.ids) {
                    if (this.ids[i][id]) {
                        return this.ids[i][id];
                    }
                }
                return null;
            },
            handleMouseDown: function(e, oDD) {
                this.currentTarget = YAHOO.util.Event.getTarget(e);
                this.dragCurrent = oDD;
                var el = oDD.getEl();
                this.startX = YAHOO.util.Event.getPageX(e);
                this.startY = YAHOO.util.Event.getPageY(e);
                this.deltaX = this.startX - el.offsetLeft;
                this.deltaY = this.startY - el.offsetTop;
                this.dragThreshMet = false;
                this.clickTimeout = setTimeout(function() {
                    var DDM = YAHOO.util.DDM;
                    DDM.startDrag(DDM.startX, DDM.startY);
                },
                this.clickTimeThresh);
            },
            startDrag: function(x, y) {
                clearTimeout(this.clickTimeout);
                var dc = this.dragCurrent;
                if (dc) {
                    dc.b4StartDrag(x, y);
                }
                if (dc) {
                    dc.startDrag(x, y);
                }
                this.dragThreshMet = true;
            },
            handleMouseUp: function(e) {
                if (this.dragCurrent) {
                    clearTimeout(this.clickTimeout);
                    if (this.dragThreshMet) {
                        this.fireEvents(e, true);
                    } else {}
                    this.stopDrag(e);
                    this.stopEvent(e);
                }
            },
            stopEvent: function(e) {
                if (this.stopPropagation) {
                    YAHOO.util.Event.stopPropagation(e);
                }
                if (this.preventDefault) {
                    YAHOO.util.Event.preventDefault(e);
                }
            },
            stopDrag: function(e, silent) {
                if (this.dragCurrent && !silent) {
                    if (this.dragThreshMet) {
                        this.dragCurrent.b4EndDrag(e);
                        this.dragCurrent.endDrag(e);
                    }
                    this.dragCurrent.onMouseUp(e);
                }
                this.dragCurrent = null;
                this.dragOvers = {};
            },
            handleMouseMove: function(e) {
                var dc = this.dragCurrent;
                if (dc) {
                    if (YAHOO.util.Event.isIE && !e.button) {
                        this.stopEvent(e);
                        return this.handleMouseUp(e);
                    }
                    if (!this.dragThreshMet) {
                        var diffX = Math.abs(this.startX - YAHOO.util.Event.getPageX(e));
                        var diffY = Math.abs(this.startY - YAHOO.util.Event.getPageY(e));
                        if (diffX > this.clickPixelThresh || diffY > this.clickPixelThresh) {
                            this.startDrag(this.startX, this.startY);
                        }
                    }
                    if (this.dragThreshMet) {
                        dc.b4Drag(e);
                        if (dc) {
                            dc.onDrag(e);
                        }
                        if (dc) {
                            this.fireEvents(e, false);
                        }
                    }
                    this.stopEvent(e);
                }
            },
            fireEvents: function(e, isDrop) {
                var dc = this.dragCurrent;
                if (!dc || dc.isLocked()) {
                    return;
                }
                var x = YAHOO.util.Event.getPageX(e);
                var y = YAHOO.util.Event.getPageY(e);
                var pt = new YAHOO.util.Point(x, y);
                var pos = dc.getTargetCoord(pt.x, pt.y);
                var el = dc.getDragEl();
                curRegion = new YAHOO.util.Region(pos.y, pos.x + el.offsetWidth, pos.y + el.offsetHeight, pos.x);
                var oldOvers = [];
                var outEvts = [];
                var overEvts = [];
                var dropEvts = [];
                var enterEvts = [];
                for (var i in this.dragOvers) {
                    var ddo = this.dragOvers[i];
                    if (!this.isTypeOfDD(ddo)) {
                        continue;
                    }
                    if (!this.isOverTarget(pt, ddo, this.mode, curRegion)) {
                        outEvts.push(ddo);
                    }
                    oldOvers[i] = true;
                    delete this.dragOvers[i];
                }
                for (var sGroup in dc.groups) {
                    if ("string" != typeof sGroup) {
                        continue;
                    }
                    for (i in this.ids[sGroup]) {
                        var oDD = this.ids[sGroup][i];
                        if (!this.isTypeOfDD(oDD)) {
                            continue;
                        }
                        if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
                            if (this.isOverTarget(pt, oDD, this.mode, curRegion)) {
                                if (isDrop) {
                                    dropEvts.push(oDD);
                                } else {
                                    if (!oldOvers[oDD.id]) {
                                        enterEvts.push(oDD);
                                    } else {
                                        overEvts.push(oDD);
                                    }
                                    this.dragOvers[oDD.id] = oDD;
                                }
                            }
                        }
                    }
                }
                this.interactionInfo = {
                    out: outEvts,
                    enter: enterEvts,
                    over: overEvts,
                    drop: dropEvts,
                    point: pt,
                    draggedRegion: curRegion,
                    sourceRegion: this.locationCache[dc.id],
                    validDrop: isDrop
                };
                if (isDrop && !dropEvts.length) {
                    this.interactionInfo.validDrop = false;
                    dc.onInvalidDrop(e);
                }
                if (this.mode) {
                    if (outEvts.length) {
                        dc.b4DragOut(e, outEvts);
                        if (dc) {
                            dc.onDragOut(e, outEvts);
                        }
                    }
                    if (enterEvts.length) {
                        if (dc) {
                            dc.onDragEnter(e, enterEvts);
                        }
                    }
                    if (overEvts.length) {
                        if (dc) {
                            dc.b4DragOver(e, overEvts);
                        }
                        if (dc) {
                            dc.onDragOver(e, overEvts);
                        }
                    }
                    if (dropEvts.length) {
                        if (dc) {
                            dc.b4DragDrop(e, dropEvts);
                        }
                        if (dc) {
                            dc.onDragDrop(e, dropEvts);
                        }
                    }
                } else {
                    var len = 0;
                    for (i = 0, len = outEvts.length; i < len; ++i) {
                        if (dc) {
                            dc.b4DragOut(e, outEvts[i].id);
                        }
                        if (dc) {
                            dc.onDragOut(e, outEvts[i].id);
                        }
                    }
                    for (i = 0, len = enterEvts.length; i < len; ++i) {
                        if (dc) {
                            dc.onDragEnter(e, enterEvts[i].id);
                        }
                    }
                    for (i = 0, len = overEvts.length; i < len; ++i) {
                        if (dc) {
                            dc.b4DragOver(e, overEvts[i].id);
                        }
                        if (dc) {
                            dc.onDragOver(e, overEvts[i].id);
                        }
                    }
                    for (i = 0, len = dropEvts.length; i < len; ++i) {
                        if (dc) {
                            dc.b4DragDrop(e, dropEvts[i].id);
                        }
                        if (dc) {
                            dc.onDragDrop(e, dropEvts[i].id);
                        }
                    }
                }
            },
            getBestMatch: function(dds) {
                var winner = null;
                var len = dds.length;
                if (len == 1) {
                    winner = dds[0];
                } else {
                    for (var i = 0; i < len; ++i) {
                        var dd = dds[i];
                        if (this.mode == this.INTERSECT && dd.cursorIsOver) {
                            winner = dd;
                            break;
                        } else {
                            if (!winner || !winner.overlap || (dd.overlap && winner.overlap.getArea() < dd.overlap.getArea())) {
                                winner = dd;
                            }
                        }
                    }
                }
                return winner;
            },
            refreshCache: function(groups) {
                var g = groups || this.ids;
                for (var sGroup in g) {
                    if ("string" != typeof sGroup) {
                        continue;
                    }
                    for (var i in this.ids[sGroup]) {
                        var oDD = this.ids[sGroup][i];
                        if (this.isTypeOfDD(oDD)) {
                            var loc = this.getLocation(oDD);
                            if (loc) {
                                this.locationCache[oDD.id] = loc;
                            } else {
                                delete this.locationCache[oDD.id];
                            }
                        }
                    }
                }
            },
            verifyEl: function(el) {
                try {
                    if (el) {
                        var parent = el.offsetParent;
                        if (parent) {
                            return true;
                        }
                    }
                } catch(e) {}
                return false;
            },
            getLocation: function(oDD) {
                if (!this.isTypeOfDD(oDD)) {
                    return null;
                }
                var el = oDD.getEl(),
                pos,
                x1,
                x2,
                y1,
                y2,
                t,
                r,
                b,
                l;
                try {
                    pos = YAHOO.util.Dom.getXY(el);
                } catch(e) {}
                if (!pos) {
                    return null;
                }
                x1 = pos[0];
                x2 = x1 + el.offsetWidth;
                y1 = pos[1];
                y2 = y1 + el.offsetHeight;
                t = y1 - oDD.padding[0];
                r = x2 + oDD.padding[1];
                b = y2 + oDD.padding[2];
                l = x1 - oDD.padding[3];
                return new YAHOO.util.Region(t, r, b, l);
            },
            isOverTarget: function(pt, oTarget, intersect, curRegion) {
                var loc = this.locationCache[oTarget.id];
                if (!loc || !this.useCache) {
                    loc = this.getLocation(oTarget);
                    this.locationCache[oTarget.id] = loc;
                }
                if (!loc) {
                    return false;
                }
                oTarget.cursorIsOver = loc.contains(pt);
                var dc = this.dragCurrent;
                if (!dc || (!intersect && !dc.constrainX && !dc.constrainY)) {
                    return oTarget.cursorIsOver;
                }
                oTarget.overlap = null;
                if (!curRegion) {
                    var pos = dc.getTargetCoord(pt.x, pt.y);
                    var el = dc.getDragEl();
                    curRegion = new YAHOO.util.Region(pos.y, pos.x + el.offsetWidth, pos.y + el.offsetHeight, pos.x);
                }
                var overlap = curRegion.intersect(loc);
                if (overlap) {
                    oTarget.overlap = overlap;
                    return (intersect) ? true: oTarget.cursorIsOver;
                } else {
                    return false;
                }
            },
            _onUnload: function(e, me) {
                this.unregAll();
            },
            unregAll: function() {
                if (this.dragCurrent) {
                    this.stopDrag();
                    this.dragCurrent = null;
                }
                this._execOnAll("unreg", []);
                for (i in this.elementCache) {
                    delete this.elementCache[i];
                }
                this.elementCache = {};
                this.ids = {};
            },
            elementCache: {},
            getElWrapper: function(id) {
                var oWrapper = this.elementCache[id];
                if (!oWrapper || !oWrapper.el) {
                    oWrapper = this.elementCache[id] = new this.ElementWrapper(YAHOO.util.Dom.get(id));
                }
                return oWrapper;
            },
            getElement: function(id) {
                return YAHOO.util.Dom.get(id);
            },
            getCss: function(id) {
                var el = YAHOO.util.Dom.get(id);
                return (el) ? el.style: null;
            },
            ElementWrapper: function(el) {
                this.el = el || null;
                this.id = this.el && el.id;
                this.css = this.el && el.style;
            },
            getPosX: function(el) {
                return YAHOO.util.Dom.getX(el);
            },
            getPosY: function(el) {
                return YAHOO.util.Dom.getY(el);
            },
            swapNode: function(n1, n2) {
                if (n1.swapNode) {
                    n1.swapNode(n2);
                } else {
                    var p = n2.parentNode;
                    var s = n2.nextSibling;
                    if (s == n1) {
                        p.insertBefore(n1, n2);
                    } else if (n2 == n1.nextSibling) {
                        p.insertBefore(n2, n1);
                    } else {
                        n1.parentNode.replaceChild(n2, n1);
                        p.insertBefore(n1, s);
                    }
                }
            },
            getScroll: function() {
                var t, l, dde = document.documentElement,
                db = document.body;
                if (dde && (dde.scrollTop || dde.scrollLeft)) {
                    t = dde.scrollTop;
                    l = dde.scrollLeft;
                } else if (db) {
                    t = db.scrollTop;
                    l = db.scrollLeft;
                } else {}
                return {
                    top: t,
                    left: l
                };
            },
            getStyle: function(el, styleProp) {
                return YAHOO.util.Dom.getStyle(el, styleProp);
            },
            getScrollTop: function() {
                return this.getScroll().top;
            },
            getScrollLeft: function() {
                return this.getScroll().left;
            },
            moveToEl: function(moveEl, targetEl) {
                var aCoord = YAHOO.util.Dom.getXY(targetEl);
                YAHOO.util.Dom.setXY(moveEl, aCoord);
            },
            getClientHeight: function() {
                return YAHOO.util.Dom.getViewportHeight();
            },
            getClientWidth: function() {
                return YAHOO.util.Dom.getViewportWidth();
            },
            numericSort: function(a, b) {
                return (a - b);
            },
            _timeoutCount: 0,
            _addListeners: function() {
                var DDM = YAHOO.util.DDM;
                if (YAHOO.util.Event && document) {
                    DDM._onLoad();
                } else {
                    if (DDM._timeoutCount > 2000) {} else {
                        setTimeout(DDM._addListeners, 10);
                        if (document && document.body) {
                            DDM._timeoutCount += 1;
                        }
                    }
                }
            },
            handleWasClicked: function(node, id) {
                if (this.isHandle(id, node.id)) {
                    return true;
                } else {
                    var p = node.parentNode;
                    while (p) {
                        if (this.isHandle(id, p.id)) {
                            return true;
                        } else {
                            p = p.parentNode;
                        }
                    }
                }
                return false;
            }
        };
    } ();
    YAHOO.util.DDM = YAHOO.util.DragDropMgr;
    YAHOO.util.DDM._addListeners();
} (function() {
    var Event = YAHOO.util.Event;
    var Dom = YAHOO.util.Dom;
    YAHOO.util.DragDrop = function(id, sGroup, config) {
        if (id) {
            this.init(id, sGroup, config);
        }
    };
    YAHOO.util.DragDrop.prototype = {
        id: null,
        config: null,
        dragElId: null,
        handleElId: null,
        invalidHandleTypes: null,
        invalidHandleIds: null,
        invalidHandleClasses: null,
        startPageX: 0,
        startPageY: 0,
        groups: null,
        locked: false,
        lock: function() {
            this.locked = true;
        },
        unlock: function() {
            this.locked = false;
        },
        isTarget: true,
        padding: null,
        _domRef: null,
        __ygDragDrop: true,
        constrainX: false,
        constrainY: false,
        minX: 0,
        maxX: 0,
        minY: 0,
        maxY: 0,
        deltaX: 0,
        deltaY: 0,
        maintainOffset: false,
        xTicks: null,
        yTicks: null,
        primaryButtonOnly: true,
        available: false,
        hasOuterHandles: false,
        cursorIsOver: false,
        overlap: null,
        b4StartDrag: function(x, y) {},
        startDrag: function(x, y) {},
        b4Drag: function(e) {},
        onDrag: function(e) {},
        onDragEnter: function(e, id) {},
        b4DragOver: function(e) {},
        onDragOver: function(e, id) {},
        b4DragOut: function(e) {},
        onDragOut: function(e, id) {},
        b4DragDrop: function(e) {},
        onDragDrop: function(e, id) {},
        onInvalidDrop: function(e) {},
        b4EndDrag: function(e) {},
        endDrag: function(e) {},
        b4MouseDown: function(e) {},
        onMouseDown: function(e) {},
        onMouseUp: function(e) {},
        onAvailable: function() {},
        getEl: function() {
            if (!this._domRef) {
                this._domRef = Dom.get(this.id);
            }
            return this._domRef;
        },
        getDragEl: function() {
            return Dom.get(this.dragElId);
        },
        init: function(id, sGroup, config) {
            this.initTarget(id, sGroup, config);
            Event.on(this._domRef || this.id, "mousedown", this.handleMouseDown, this, true);
        },
        initTarget: function(id, sGroup, config) {
            this.config = config || {};
            this.DDM = YAHOO.util.DDM;
            this.groups = {};
            if (typeof id !== "string") {
                this._domRef = id;
                id = Dom.generateId(id);
            }
            this.id = id;
            this.addToGroup((sGroup) ? sGroup: "default");
            this.handleElId = id;
            Event.onAvailable(id, this.handleOnAvailable, this, true);
            this.setDragElId(id);
            this.invalidHandleTypes = {
                A: "A"
            };
            this.invalidHandleIds = {};
            this.invalidHandleClasses = [];
            this.applyConfig();
        },
        applyConfig: function() {
            this.padding = this.config.padding || [0, 0, 0, 0];
            this.isTarget = (this.config.isTarget !== false);
            this.maintainOffset = (this.config.maintainOffset);
            this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
        },
        handleOnAvailable: function() {
            this.available = true;
            this.resetConstraints();
            this.onAvailable();
        },
        setPadding: function(iTop, iRight, iBot, iLeft) {
            if (!iRight && 0 !== iRight) {
                this.padding = [iTop, iTop, iTop, iTop];
            } else if (!iBot && 0 !== iBot) {
                this.padding = [iTop, iRight, iTop, iRight];
            } else {
                this.padding = [iTop, iRight, iBot, iLeft];
            }
        },
        setInitPosition: function(diffX, diffY) {
            var el = this.getEl();
            if (!this.DDM.verifyEl(el)) {
                return;
            }
            var dx = diffX || 0;
            var dy = diffY || 0;
            var p = Dom.getXY(el);
            this.initPageX = p[0] - dx;
            this.initPageY = p[1] - dy;
            this.lastPageX = p[0];
            this.lastPageY = p[1];
            this.setStartPosition(p);
        },
        setStartPosition: function(pos) {
            var p = pos || Dom.getXY(this.getEl());
            this.deltaSetXY = null;
            this.startPageX = p[0];
            this.startPageY = p[1];
        },
        addToGroup: function(sGroup) {
            this.groups[sGroup] = true;
            this.DDM.regDragDrop(this, sGroup);
        },
        removeFromGroup: function(sGroup) {
            if (this.groups[sGroup]) {
                delete this.groups[sGroup];
            }
            this.DDM.removeDDFromGroup(this, sGroup);
        },
        setDragElId: function(id) {
            this.dragElId = id;
        },
        setHandleElId: function(id) {
            if (typeof id !== "string") {
                id = Dom.generateId(id);
            }
            this.handleElId = id;
            this.DDM.regHandle(this.id, id);
        },
        setOuterHandleElId: function(id) {
            if (typeof id !== "string") {
                id = Dom.generateId(id);
            }
            Event.on(id, "mousedown", this.handleMouseDown, this, true);
            this.setHandleElId(id);
            this.hasOuterHandles = true;
        },
        unreg: function() {
            Event.removeListener(this.id, "mousedown", this.handleMouseDown);
            this._domRef = null;
            this.DDM._remove(this);
        },
        isLocked: function() {
            return (this.DDM.isLocked() || this.locked);
        },
        handleMouseDown: function(e, oDD) {
            var button = e.which || e.button;
            if (this.primaryButtonOnly && button > 1) {
                return;
            }
            if (this.isLocked()) {
                return;
            }
            this.b4MouseDown(e);
            this.onMouseDown(e);
            this.DDM.refreshCache(this.groups);
            var pt = new YAHOO.util.Point(Event.getPageX(e), Event.getPageY(e));
            if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this)) {} else {
                if (this.clickValidator(e)) {
                    this.setStartPosition();
                    this.DDM.handleMouseDown(e, this);
                    this.DDM.stopEvent(e);
                } else {}
            }
        },
        clickValidator: function(e) {
            var target = Event.getTarget(e);
            return (this.isValidHandleChild(target) && (this.id == this.handleElId || this.DDM.handleWasClicked(target, this.id)));
        },
        getTargetCoord: function(iPageX, iPageY) {
            var x = iPageX - this.deltaX;
            var y = iPageY - this.deltaY;
            if (this.constrainX) {
                if (x < this.minX) {
                    x = this.minX;
                }
                if (x > this.maxX) {
                    x = this.maxX;
                }
            }
            if (this.constrainY) {
                if (y < this.minY) {
                    y = this.minY;
                }
                if (y > this.maxY) {
                    y = this.maxY;
                }
            }
            x = this.getTick(x, this.xTicks);
            y = this.getTick(y, this.yTicks);
            return {
                x: x,
                y: y
            };
        },
        addInvalidHandleType: function(tagName) {
            var type = tagName.toUpperCase();
            this.invalidHandleTypes[type] = type;
        },
        addInvalidHandleId: function(id) {
            if (typeof id !== "string") {
                id = Dom.generateId(id);
            }
            this.invalidHandleIds[id] = id;
        },
        addInvalidHandleClass: function(cssClass) {
            this.invalidHandleClasses.push(cssClass);
        },
        removeInvalidHandleType: function(tagName) {
            var type = tagName.toUpperCase();
            delete this.invalidHandleTypes[type];
        },
        removeInvalidHandleId: function(id) {
            if (typeof id !== "string") {
                id = Dom.generateId(id);
            }
            delete this.invalidHandleIds[id];
        },
        removeInvalidHandleClass: function(cssClass) {
            for (var i = 0, len = this.invalidHandleClasses.length; i < len; ++i) {
                if (this.invalidHandleClasses[i] == cssClass) {
                    delete this.invalidHandleClasses[i];
                }
            }
        },
        isValidHandleChild: function(node) {
            var valid = true;
            var nodeName;
            try {
                nodeName = node.nodeName.toUpperCase();
            } catch(e) {
                nodeName = node.nodeName;
            }
            valid = valid && !this.invalidHandleTypes[nodeName];
            valid = valid && !this.invalidHandleIds[node.id];
            for (var i = 0, len = this.invalidHandleClasses.length; valid && i < len; ++i) {
                valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);
            }
            return valid;
        },
        setXTicks: function(iStartX, iTickSize) {
            this.xTicks = [];
            this.xTickSize = iTickSize;
            var tickMap = {};
            for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
                if (!tickMap[i]) {
                    this.xTicks[this.xTicks.length] = i;
                    tickMap[i] = true;
                }
            }
            for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
                if (!tickMap[i]) {
                    this.xTicks[this.xTicks.length] = i;
                    tickMap[i] = true;
                }
            }
            this.xTicks.sort(this.DDM.numericSort);
        },
        setYTicks: function(iStartY, iTickSize) {
            this.yTicks = [];
            this.yTickSize = iTickSize;
            var tickMap = {};
            for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
                if (!tickMap[i]) {
                    this.yTicks[this.yTicks.length] = i;
                    tickMap[i] = true;
                }
            }
            for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
                if (!tickMap[i]) {
                    this.yTicks[this.yTicks.length] = i;
                    tickMap[i] = true;
                }
            }
            this.yTicks.sort(this.DDM.numericSort);
        },
        setXConstraint: function(iLeft, iRight, iTickSize) {
            this.leftConstraint = parseInt(iLeft, 10);
            this.rightConstraint = parseInt(iRight, 10);
            this.minX = this.initPageX - this.leftConstraint;
            this.maxX = this.initPageX + this.rightConstraint;
            if (iTickSize) {
                this.setXTicks(this.initPageX, iTickSize);
            }
            this.constrainX = true;
        },
        clearConstraints: function() {
            this.constrainX = false;
            this.constrainY = false;
            this.clearTicks();
        },
        clearTicks: function() {
            this.xTicks = null;
            this.yTicks = null;
            this.xTickSize = 0;
            this.yTickSize = 0;
        },
        setYConstraint: function(iUp, iDown, iTickSize) {
            this.topConstraint = parseInt(iUp, 10);
            this.bottomConstraint = parseInt(iDown, 10);
            this.minY = this.initPageY - this.topConstraint;
            this.maxY = this.initPageY + this.bottomConstraint;
            if (iTickSize) {
                this.setYTicks(this.initPageY, iTickSize);
            }
            this.constrainY = true;
        },
        resetConstraints: function() {
            if (this.initPageX || this.initPageX === 0) {
                var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX: 0;
                var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY: 0;
                this.setInitPosition(dx, dy);
            } else {
                this.setInitPosition();
            }
            if (this.constrainX) {
                this.setXConstraint(this.leftConstraint, this.rightConstraint, this.xTickSize);
            }
            if (this.constrainY) {
                this.setYConstraint(this.topConstraint, this.bottomConstraint, this.yTickSize);
            }
        },
        getTick: function(val, tickArray) {
            if (!tickArray) {
                return val;
            } else if (tickArray[0] >= val) {
                return tickArray[0];
            } else {
                for (var i = 0, len = tickArray.length; i < len; ++i) {
                    var next = i + 1;
                    if (tickArray[next] && tickArray[next] >= val) {
                        var diff1 = val - tickArray[i];
                        var diff2 = tickArray[next] - val;
                        return (diff2 > diff1) ? tickArray[i] : tickArray[next];
                    }
                }
                return tickArray[tickArray.length - 1];
            }
        },
        toString: function() {
            return ("DragDrop " + this.id);
        }
    };
})();
YAHOO.util.DD = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
    }
};
YAHOO.extend(YAHOO.util.DD, YAHOO.util.DragDrop, {
    scroll: true,
    autoOffset: function(iPageX, iPageY) {
        var x = iPageX - this.startPageX;
        var y = iPageY - this.startPageY;
        this.setDelta(x, y);
    },
    setDelta: function(iDeltaX, iDeltaY) {
        this.deltaX = iDeltaX;
        this.deltaY = iDeltaY;
    },
    setDragElPos: function(iPageX, iPageY) {
        var el = this.getDragEl();
        this.alignElWithMouse(el, iPageX, iPageY);
    },
    alignElWithMouse: function(el, iPageX, iPageY) {
        var oCoord = this.getTargetCoord(iPageX, iPageY);
        if (!this.deltaSetXY) {
            var aCoord = [oCoord.x, oCoord.y];
            YAHOO.util.Dom.setXY(el, aCoord);
            var newLeft = parseInt(YAHOO.util.Dom.getStyle(el, "left"), 10);
            var newTop = parseInt(YAHOO.util.Dom.getStyle(el, "top"), 10);
            this.deltaSetXY = [newLeft - oCoord.x, newTop - oCoord.y];
        } else {
            YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
            YAHOO.util.Dom.setStyle(el, "top", (oCoord.y + this.deltaSetXY[1]) + "px");
        }
        this.cachePosition(oCoord.x, oCoord.y);
        this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
    },
    cachePosition: function(iPageX, iPageY) {
        if (iPageX) {
            this.lastPageX = iPageX;
            this.lastPageY = iPageY;
        } else {
            var aCoord = YAHOO.util.Dom.getXY(this.getEl());
            this.lastPageX = aCoord[0];
            this.lastPageY = aCoord[1];
        }
    },
    autoScroll: function(x, y, h, w) {
        if (this.scroll) {
            var clientH = this.DDM.getClientHeight();
            var clientW = this.DDM.getClientWidth();
            var st = this.DDM.getScrollTop();
            var sl = this.DDM.getScrollLeft();
            var bot = h + y;
            var right = w + x;
            var toBot = (clientH + st - y - this.deltaY);
            var toRight = (clientW + sl - x - this.deltaX);
            var thresh = 40;
            var scrAmt = (document.all) ? 80 : 30;
            if (bot > clientH && toBot < thresh) {
                window.scrollTo(sl, st + scrAmt);
            }
            if (y < st && st > 0 && y - st < thresh) {
                window.scrollTo(sl, st - scrAmt);
            }
            if (right > clientW && toRight < thresh) {
                window.scrollTo(sl + scrAmt, st);
            }
            if (x < sl && sl > 0 && x - sl < thresh) {
                window.scrollTo(sl - scrAmt, st);
            }
        }
    },
    applyConfig: function() {
        YAHOO.util.DD.superclass.applyConfig.call(this);
        this.scroll = (this.config.scroll !== false);
    },
    b4MouseDown: function(e) {
        this.setStartPosition();
        this.autoOffset(YAHOO.util.Event.getPageX(e), YAHOO.util.Event.getPageY(e));
    },
    b4Drag: function(e) {
        this.setDragElPos(YAHOO.util.Event.getPageX(e), YAHOO.util.Event.getPageY(e));
    },
    toString: function() {
        return ("DD " + this.id);
    }
});
YAHOO.util.DDProxy = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
        this.initFrame();
    }
};
YAHOO.util.DDProxy.dragElId = "ygddfdiv";
YAHOO.extend(YAHOO.util.DDProxy, YAHOO.util.DD, {
    resizeFrame: true,
    centerFrame: false,
    createFrame: function() {
        var self = this,
        body = document.body;
        if (!body || !body.firstChild) {
            setTimeout(function() {
                self.createFrame();
            },
            50);
            return;
        }
        var div = this.getDragEl(),
        Dom = YAHOO.util.Dom;
        if (!div) {
            div = document.createElement("div");
            div.id = this.dragElId;
            var s = div.style;
            s.position = "absolute";
            s.visibility = "hidden";
            s.cursor = "move";
            s.border = "2px solid #aaa";
            s.zIndex = 999;
            s.height = "25px";
            s.width = "25px";
            var _data = document.createElement('div');
            Dom.setStyle(_data, 'height', '100%');
            Dom.setStyle(_data, 'width', '100%');
            Dom.setStyle(_data, 'background-color', '#ccc');
            Dom.setStyle(_data, 'opacity', '0');
            div.appendChild(_data);
            body.insertBefore(div, body.firstChild);
        }
    },
    initFrame: function() {
        this.createFrame();
    },
    applyConfig: function() {
        YAHOO.util.DDProxy.superclass.applyConfig.call(this);
        this.resizeFrame = (this.config.resizeFrame !== false);
        this.centerFrame = (this.config.centerFrame);
        this.setDragElId(this.config.dragElId || YAHOO.util.DDProxy.dragElId);
    },
    showFrame: function(iPageX, iPageY) {
        var el = this.getEl();
        var dragEl = this.getDragEl();
        var s = dragEl.style;
        this._resizeProxy();
        if (this.centerFrame) {
            this.setDelta(Math.round(parseInt(s.width, 10) / 2), Math.round(parseInt(s.height, 10) / 2));
        }
        this.setDragElPos(iPageX, iPageY);
        YAHOO.util.Dom.setStyle(dragEl, "visibility", "visible");
    },
    _resizeProxy: function() {
        if (this.resizeFrame) {
            var DOM = YAHOO.util.Dom;
            var el = this.getEl();
            var dragEl = this.getDragEl();
            var bt = parseInt(DOM.getStyle(dragEl, "borderTopWidth"), 10);
            var br = parseInt(DOM.getStyle(dragEl, "borderRightWidth"), 10);
            var bb = parseInt(DOM.getStyle(dragEl, "borderBottomWidth"), 10);
            var bl = parseInt(DOM.getStyle(dragEl, "borderLeftWidth"), 10);
            if (isNaN(bt)) {
                bt = 0;
            }
            if (isNaN(br)) {
                br = 0;
            }
            if (isNaN(bb)) {
                bb = 0;
            }
            if (isNaN(bl)) {
                bl = 0;
            }
            var newWidth = Math.max(0, el.offsetWidth - br - bl);
            var newHeight = Math.max(0, el.offsetHeight - bt - bb);
            DOM.setStyle(dragEl, "width", newWidth + "px");
            DOM.setStyle(dragEl, "height", newHeight + "px");
        }
    },
    b4MouseDown: function(e) {
        this.setStartPosition();
        var x = YAHOO.util.Event.getPageX(e);
        var y = YAHOO.util.Event.getPageY(e);
        this.autoOffset(x, y);
    },
    b4StartDrag: function(x, y) {
        this.showFrame(x, y);
    },
    b4EndDrag: function(e) {
        YAHOO.util.Dom.setStyle(this.getDragEl(), "visibility", "hidden");
    },
    endDrag: function(e) {
        var DOM = YAHOO.util.Dom;
        var lel = this.getEl();
        var del = this.getDragEl();
        DOM.setStyle(del, "visibility", "");
        DOM.setStyle(lel, "visibility", "hidden");
        YAHOO.util.DDM.moveToEl(lel, del);
        DOM.setStyle(del, "visibility", "hidden");
        DOM.setStyle(lel, "visibility", "");
    },
    toString: function() {
        return ("DDProxy " + this.id);
    }
});
YAHOO.util.DDTarget = function(id, sGroup, config) {
    if (id) {
        this.initTarget(id, sGroup, config);
    }
};
YAHOO.extend(YAHOO.util.DDTarget, YAHOO.util.DragDrop, {
    toString: function() {
        return ("DDTarget " + this.id);
    }
});
YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {
    version: "2.3.0",
    build: "442"
});
YAHOO.widget.Slider = function(sElementId, sGroup, oThumb, sType) {
    if (sElementId) {
        this.init(sElementId, sGroup, true);
        this.initSlider(sType);
        this.initThumb(oThumb);
    }
};
YAHOO.widget.Slider.getHorizSlider = function(sBGElId, sHandleElId, iLeft, iRight, iTickSize) {
    return new YAHOO.widget.Slider(sBGElId, sBGElId, new YAHOO.widget.SliderThumb(sHandleElId, sBGElId, iLeft, iRight, 0, 0, iTickSize), "horiz");
};
YAHOO.widget.Slider.getVertSlider = function(sBGElId, sHandleElId, iUp, iDown, iTickSize) {
    return new YAHOO.widget.Slider(sBGElId, sBGElId, new YAHOO.widget.SliderThumb(sHandleElId, sBGElId, 0, 0, iUp, iDown, iTickSize), "vert");
};
YAHOO.widget.Slider.getSliderRegion = function(sBGElId, sHandleElId, iLeft, iRight, iUp, iDown, iTickSize) {
    return new YAHOO.widget.Slider(sBGElId, sBGElId, new YAHOO.widget.SliderThumb(sHandleElId, sBGElId, iLeft, iRight, iUp, iDown, iTickSize), "region");
};
YAHOO.widget.Slider.ANIM_AVAIL = true;
YAHOO.extend(YAHOO.widget.Slider, YAHOO.util.DragDrop, {
    initSlider: function(sType) {
        this.type = sType;
        this.createEvent("change", this);
        this.createEvent("slideStart", this);
        this.createEvent("slideEnd", this);
        this.isTarget = false;
        this.animate = YAHOO.widget.Slider.ANIM_AVAIL;
        this.backgroundEnabled = true;
        this.tickPause = 40;
        this.enableKeys = true;
        this.keyIncrement = 20;
        this.moveComplete = true;
        this.animationDuration = 0.2;
        this.SOURCE_UI_EVENT = 1;
        this.SOURCE_SET_VALUE = 2;
        this.valueChangeSource = 0;
    },
    initThumb: function(t) {
        var self = this;
        this.thumb = t;
        t.cacheBetweenDrags = true;
        t.onChange = function() {
            self.handleThumbChange();
        };
        if (t._isHoriz && t.xTicks && t.xTicks.length) {
            this.tickPause = Math.round(360 / t.xTicks.length);
        } else if (t.yTicks && t.yTicks.length) {
            this.tickPause = Math.round(360 / t.yTicks.length);
        }
        t.onMouseDown = function() {
            return self.thumbMouseDown();
        };
        t.onMouseUp = function() {
            self.thumbMouseUp();
        };
        t.onDrag = function() {
            self.fireEvents(true);
        };
        t.onAvailable = function() {
            return self.setStartSliderState();
        };
    },
    onAvailable: function() {
        var Event = YAHOO.util.Event;
        Event.on(this.id, "keydown", this.handleKeyDown, this, true);
        Event.on(this.id, "keypress", this.handleKeyPress, this, true);
    },
    handleKeyPress: function(e) {
        if (this.enableKeys) {
            var Event = YAHOO.util.Event;
            var kc = Event.getCharCode(e);
            switch (kc) {
            case 0x25:
            case 0x26:
            case 0x27:
            case 0x28:
            case 0x24:
            case 0x23:
                Event.preventDefault(e);
                break;
            default:
            }
        }
    },
    handleKeyDown: function(e) {
        if (this.enableKeys) {
            var Event = YAHOO.util.Event;
            var kc = Event.getCharCode(e),
            t = this.thumb;
            var h = this.getXValue(),
            v = this.getYValue();
            var horiz = false;
            var changeValue = true;
            switch (kc) {
            case 0x25:
                h -= this.keyIncrement;
                break;
            case 0x26:
                v -= this.keyIncrement;
                break;
            case 0x27:
                h += this.keyIncrement;
                break;
            case 0x28:
                v += this.keyIncrement;
                break;
            case 0x24:
                h = t.leftConstraint;
                v = t.topConstraint;
                break;
            case 0x23:
                h = t.rightConstraint;
                v = t.bottomConstraint;
                break;
            default:
                changeValue = false;
            }
            if (changeValue) {
                if (t._isRegion) {
                    this.setRegionValue(h, v, true);
                } else {
                    var newVal = (t._isHoriz) ? h: v;
                    this.setValue(newVal, true);
                }
                Event.stopEvent(e);
            }
        }
    },
    setStartSliderState: function() {
        this.setThumbCenterPoint();
        this.baselinePos = YAHOO.util.Dom.getXY(this.getEl());
        this.thumb.startOffset = this.thumb.getOffsetFromParent(this.baselinePos);
        if (this.thumb._isRegion) {
            if (this.deferredSetRegionValue) {
                this.setRegionValue.apply(this, this.deferredSetRegionValue, true);
                this.deferredSetRegionValue = null;
            } else {
                this.setRegionValue(0, 0, true, true);
            }
        } else {
            if (this.deferredSetValue) {
                this.setValue.apply(this, this.deferredSetValue, true);
                this.deferredSetValue = null;
            } else {
                this.setValue(0, true, true);
            }
        }
    },
    setThumbCenterPoint: function() {
        var el = this.thumb.getEl();
        if (el) {
            this.thumbCenterPoint = {
                x: parseInt(el.offsetWidth / 2, 10),
                y: parseInt(el.offsetHeight / 2, 10)
            };
        }
    },
    lock: function() {
        this.thumb.lock();
        this.locked = true;
    },
    unlock: function() {
        this.thumb.unlock();
        this.locked = false;
    },
    thumbMouseDown: function() {
        var ret = this.focus();
        this.fireEvent('slideStart');
        return ret;
    },
    thumbMouseUp: function() {
        if (!this.isLocked() && !this.moveComplete) {
            this.endMove();
        }
    },
    getThumb: function() {
        return this.thumb;
    },
    focus: function() {
        this.valueChangeSource = this.SOURCE_UI_EVENT;
        var el = this.getEl();
        if (el.focus) {
            try {
                el.focus();
            } catch(e) {}
        }
        this.verifyOffset();
        if (this.isLocked()) {
            return false;
        } else {
            this.onSlideStart();
            return true;
        }
    },
    onChange: function(firstOffset, secondOffset) {},
    onSlideStart: function() {},
    onSlideEnd: function() {},
    getValue: function() {
        return this.thumb.getValue();
    },
    getXValue: function() {
        return this.thumb.getXValue();
    },
    getYValue: function() {
        return this.thumb.getYValue();
    },
    handleThumbChange: function() {
        var t = this.thumb;
        if (t._isRegion) {
            t.onChange(t.getXValue(), t.getYValue());
            this.fireEvent("change", {
                x: t.getXValue(),
                y: t.getYValue()
            });
        } else {
            t.onChange(t.getValue());
            this.fireEvent("change", t.getValue());
        }
    },
    setValue: function(newOffset, skipAnim, force) {
        this.valueChangeSource = this.SOURCE_SET_VALUE;
        if (!this.thumb.available) {
            this.deferredSetValue = arguments;
            return false;
        }
        if (this.isLocked() && !force) {
            return false;
        }
        if (isNaN(newOffset)) {
            return false;
        }
        var t = this.thumb;
        var newX, newY;
        this.verifyOffset(true);
        if (t._isRegion) {
            return false;
        } else if (t._isHoriz) {
            this.onSlideStart();
            newX = t.initPageX + newOffset + this.thumbCenterPoint.x;
            this.moveThumb(newX, t.initPageY, skipAnim);
        } else {
            this.onSlideStart();
            newY = t.initPageY + newOffset + this.thumbCenterPoint.y;
            this.moveThumb(t.initPageX, newY, skipAnim);
        }
        return true;
    },
    setRegionValue: function(newOffset, newOffset2, skipAnim, force) {
        this.valueChangeSource = this.SOURCE_SET_VALUE;
        if (!this.thumb.available) {
            this.deferredSetRegionValue = arguments;
            return false;
        }
        if (this.isLocked() && !force) {
            return false;
        }
        if (isNaN(newOffset)) {
            return false;
        }
        var t = this.thumb;
        if (t._isRegion) {
            this.onSlideStart();
            var newX = t.initPageX + newOffset + this.thumbCenterPoint.x;
            var newY = t.initPageY + newOffset2 + this.thumbCenterPoint.y;
            this.moveThumb(newX, newY, skipAnim);
            return true;
        }
        return false;
    },
    verifyOffset: function(checkPos) {
        var newPos = YAHOO.util.Dom.getXY(this.getEl());
        if (newPos[0] != this.baselinePos[0] || newPos[1] != this.baselinePos[1]) {
            this.thumb.resetConstraints();
            this.baselinePos = newPos;
            return false;
        }
        return true;
    },
    moveThumb: function(x, y, skipAnim) {
        var t = this.thumb;
        var self = this;
        if (!t.available) {
            return;
        }
        t.setDelta(this.thumbCenterPoint.x, this.thumbCenterPoint.y);
        var _p = t.getTargetCoord(x, y);
        var p = [_p.x, _p.y];
        this.fireEvent("slideStart");
        if (this.animate && YAHOO.widget.Slider.ANIM_AVAIL && t._graduated && !skipAnim) {
            this.lock();
            this.curCoord = YAHOO.util.Dom.getXY(this.thumb.getEl());
            setTimeout(function() {
                self.moveOneTick(p);
            },
            this.tickPause);
        } else if (this.animate && YAHOO.widget.Slider.ANIM_AVAIL && !skipAnim) {
            this.lock();
            var oAnim = new YAHOO.util.Motion(t.id, {
                points: {
                    to: p
                }
            },
            this.animationDuration, YAHOO.util.Easing.easeOut);
            oAnim.onComplete.subscribe(function() {
                self.endMove();
            });
            oAnim.animate();
        } else {
            t.setDragElPos(x, y);
            this.endMove();
        }
    },
    moveOneTick: function(finalCoord) {
        var t = this.thumb,
        tmp;
        var nextCoord = null;
        if (t._isRegion) {
            nextCoord = this._getNextX(this.curCoord, finalCoord);
            var tmpX = (nextCoord) ? nextCoord[0] : this.curCoord[0];
            nextCoord = this._getNextY([tmpX, this.curCoord[1]], finalCoord);
        } else if (t._isHoriz) {
            nextCoord = this._getNextX(this.curCoord, finalCoord);
        } else {
            nextCoord = this._getNextY(this.curCoord, finalCoord);
        }
        if (nextCoord) {
            this.curCoord = nextCoord;
            this.thumb.alignElWithMouse(t.getEl(), nextCoord[0], nextCoord[1]);
            if (! (nextCoord[0] == finalCoord[0] && nextCoord[1] == finalCoord[1])) {
                var self = this;
                setTimeout(function() {
                    self.moveOneTick(finalCoord);
                },
                this.tickPause);
            } else {
                this.endMove();
            }
        } else {
            this.endMove();
        }
    },
    _getNextX: function(curCoord, finalCoord) {
        var t = this.thumb;
        var thresh;
        var tmp = [];
        var nextCoord = null;
        if (curCoord[0] > finalCoord[0]) {
            thresh = t.tickSize - this.thumbCenterPoint.x;
            tmp = t.getTargetCoord(curCoord[0] - thresh, curCoord[1]);
            nextCoord = [tmp.x, tmp.y];
        } else if (curCoord[0] < finalCoord[0]) {
            thresh = t.tickSize + this.thumbCenterPoint.x;
            tmp = t.getTargetCoord(curCoord[0] + thresh, curCoord[1]);
            nextCoord = [tmp.x, tmp.y];
        } else {}
        return nextCoord;
    },
    _getNextY: function(curCoord, finalCoord) {
        var t = this.thumb;
        var thresh;
        var tmp = [];
        var nextCoord = null;
        if (curCoord[1] > finalCoord[1]) {
            thresh = t.tickSize - this.thumbCenterPoint.y;
            tmp = t.getTargetCoord(curCoord[0], curCoord[1] - thresh);
            nextCoord = [tmp.x, tmp.y];
        } else if (curCoord[1] < finalCoord[1]) {
            thresh = t.tickSize + this.thumbCenterPoint.y;
            tmp = t.getTargetCoord(curCoord[0], curCoord[1] + thresh);
            nextCoord = [tmp.x, tmp.y];
        } else {}
        return nextCoord;
    },
    b4MouseDown: function(e) {
        this.thumb.autoOffset();
        this.thumb.resetConstraints();
    },
    onMouseDown: function(e) {
        if (!this.isLocked() && this.backgroundEnabled) {
            var x = YAHOO.util.Event.getPageX(e);
            var y = YAHOO.util.Event.getPageY(e);
            this.focus();
            this.moveThumb(x, y);
        }
    },
    onDrag: function(e) {
        if (!this.isLocked()) {
            var x = YAHOO.util.Event.getPageX(e);
            var y = YAHOO.util.Event.getPageY(e);
            this.moveThumb(x, y, true);
        }
    },
    endMove: function() {
        this.unlock();
        this.moveComplete = true;
        this.fireEvents();
    },
    fireEvents: function(thumbEvent) {
        var t = this.thumb;
        if (!thumbEvent) {
            t.cachePosition();
        }
        if (!this.isLocked()) {
            if (t._isRegion) {
                var newX = t.getXValue();
                var newY = t.getYValue();
                if (newX != this.previousX || newY != this.previousY) {
                    this.onChange(newX, newY);
                    this.fireEvent("change", {
                        x: newX,
                        y: newY
                    });
                }
                this.previousX = newX;
                this.previousY = newY;
            } else {
                var newVal = t.getValue();
                if (newVal != this.previousVal) {
                    this.onChange(newVal);
                    this.fireEvent("change", newVal);
                }
                this.previousVal = newVal;
            }
            if (this.moveComplete) {
                this.onSlideEnd();
                this.fireEvent("slideEnd");
                this.moveComplete = false;
            }
        }
    },
    toString: function() {
        return ("Slider (" + this.type + ") " + this.id);
    }
});
YAHOO.augment(YAHOO.widget.Slider, YAHOO.util.EventProvider);
YAHOO.widget.SliderThumb = function(id, sGroup, iLeft, iRight, iUp, iDown, iTickSize) {
    if (id) {
        YAHOO.widget.SliderThumb.superclass.constructor.call(this, id, sGroup);
        this.parentElId = sGroup;
    }
    this.isTarget = false;
    this.tickSize = iTickSize;
    this.maintainOffset = true;
    this.initSlider(iLeft, iRight, iUp, iDown, iTickSize);
    this.scroll = false;
};
YAHOO.extend(YAHOO.widget.SliderThumb, YAHOO.util.DD, {
    startOffset: null,
    _isHoriz: false,
    _prevVal: 0,
    _graduated: false,
    getOffsetFromParent0: function(parentPos) {
        var myPos = YAHOO.util.Dom.getXY(this.getEl());
        var ppos = parentPos || YAHOO.util.Dom.getXY(this.parentElId);
        return [(myPos[0] - ppos[0]), (myPos[1] - ppos[1])];
    },
    getOffsetFromParent: function(parentPos) {
        var el = this.getEl();
        if (!this.deltaOffset) {
            var myPos = YAHOO.util.Dom.getXY(el);
            var ppos = parentPos || YAHOO.util.Dom.getXY(this.parentElId);
            var newOffset = [(myPos[0] - ppos[0]), (myPos[1] - ppos[1])];
            var l = parseInt(YAHOO.util.Dom.getStyle(el, "left"), 10);
            var t = parseInt(YAHOO.util.Dom.getStyle(el, "top"), 10);
            var deltaX = l - newOffset[0];
            var deltaY = t - newOffset[1];
            if (isNaN(deltaX) || isNaN(deltaY)) {} else {
                this.deltaOffset = [deltaX, deltaY];
            }
        } else {
            var newLeft = parseInt(YAHOO.util.Dom.getStyle(el, "left"), 10);
            var newTop = parseInt(YAHOO.util.Dom.getStyle(el, "top"), 10);
            newOffset = [newLeft + this.deltaOffset[0], newTop + this.deltaOffset[1]];
        }
        return newOffset;
    },
    initSlider: function(iLeft, iRight, iUp, iDown, iTickSize) {
        this.initLeft = iLeft;
        this.initRight = iRight;
        this.initUp = iUp;
        this.initDown = iDown;
        this.setXConstraint(iLeft, iRight, iTickSize);
        this.setYConstraint(iUp, iDown, iTickSize);
        if (iTickSize && iTickSize > 1) {
            this._graduated = true;
        }
        this._isHoriz = (iLeft || iRight);
        this._isVert = (iUp || iDown);
        this._isRegion = (this._isHoriz && this._isVert);
    },
    clearTicks: function() {
        YAHOO.widget.SliderThumb.superclass.clearTicks.call(this);
        this.tickSize = 0;
        this._graduated = false;
    },
    getValue: function() {
        if (!this.available) {
            return 0;
        }
        var val = (this._isHoriz) ? this.getXValue() : this.getYValue();
        return val;
    },
    getXValue: function() {
        if (!this.available) {
            return 0;
        }
        var newOffset = this.getOffsetFromParent();
        return (newOffset[0] - this.startOffset[0]);
    },
    getYValue: function() {
        if (!this.available) {
            return 0;
        }
        var newOffset = this.getOffsetFromParent();
        return (newOffset[1] - this.startOffset[1]);
    },
    toString: function() {
        return "SliderThumb " + this.id;
    },
    onChange: function(x, y) {}
});
if ("undefined" == typeof YAHOO.util.Anim) {
    YAHOO.widget.Slider.ANIM_AVAIL = false;
}
YAHOO.register("slider", YAHOO.widget.Slider, {
    version: "2.3.0",
    build: "442"
});
LMI.Mapping.InteractiveMap = (function() {
    var Y = YAHOO.util,
    $L = YAHOO.lang,
    $D = Y.Dom,
    $E = Y.Event,
    _E = LMI.Element;
    InteractiveMap = function(container, options) {
        this.init(container, options);
    };
    InteractiveMap.contextCenterHere = function(type, e, map) {
        var xy = $D.getXY(map.container),
        x = map.contextMenuOpenX - xy[0],
        y = map.contextMenuOpenY - xy[1],
        point = map.getPointByXY(x, y);
        map.centerOnPoint(point);
    };
    InteractiveMap.contextZoomIn = function(type, e, map) {
        map.zoomIn();
    };
    InteractiveMap.contextZoomOut = function(type, e, map) {
        map.zoomOut();
    };
    InteractiveMap.Defaults = {
        enableOverview: true,
        enableResize: true,
        overviewWidth: 150,
        overviewHeight: 150,
        contextMenuItems: [{
            text: 'Center Here',
            className: 'map_cm_center',
            onclick: {
                fn: InteractiveMap.contextCenterHere
            }
        },
        {
            text: 'Zoom In',
            className: 'map_cm_zoomIn',
            onclick: {
                fn: InteractiveMap.contextZoomIn
            }
        },
        {
            text: 'Zoom Out',
            className: 'map_cm_zoomOut',
            onclick: {
                fn: InteractiveMap.contextZoomOut
            }
        }]
    };
    YAHOO.lang.extend(InteractiveMap, LMI.Mapping.Map, {
        init: function() {
            var ie = YAHOO.env.ua.ie;
            InteractiveMap.superclass.init.apply(this, arguments);
            this.easingMethod = Y.Easing.easeOutStrong;
            this.animationDuration = 1;
            this.sliders = [];
            if (this.getOption('enableResize')) {
                if (ie && ie < 7) {
                    this.container.style.overflow = 'hidden';
                }
                $E.on(window, 'resize', this.resizeLayers, this, true);
            }
        },
        updateMap: function() {
            this.tileManager.setMapOffsets(this.getMapLeft(true), this.getMapTop(true));
            this.tileManager.updateMap();
            this.updateScale();
        },
        setZoomLevel: function(level) {
            var className, that = this,
            tm = this.tileManager;
            if (this._contextMenu) {
                this._contextMenu.cfg.setProperty('visible', false);
                if (!this._zoomInMenuItem) {
                    LMI.Lang.forEach(this._contextMenu.getItems(),
                    function(i) {
                        className = i.cfg.getProperty('classname');
                        if (className === 'map_cm_zoomIn') {
                            that._zoomInMenuItem = i;
                        } else if (className === 'map_cm_zoomOut') {
                            that._zoomOutMenuItem = i;
                        }
                    });
                }
                if (level <= tm.minLevel) {
                    this._zoomInMenuItem.cfg.setProperty('disabled', true);
                    this._zoomOutMenuItem.cfg.setProperty('disabled', false);
                } else if (level >= tm.maxLevel) {
                    this._zoomInMenuItem.cfg.setProperty('disabled', false);
                    this._zoomOutMenuItem.cfg.setProperty('disabled', true);
                } else {
                    this._zoomInMenuItem.cfg.setProperty('disabled', false);
                    this._zoomOutMenuItem.cfg.setProperty('disabled', false);
                }
            }
            InteractiveMap.superclass.setZoomLevel.apply(this, arguments);
            this.setZoomSliderPosition((this.zoomLevel - 1) / (tm.zoomLevels - 1));
        },
        addZoomSlider: function(slider, min, max, inverse) {
            var that = this;
            function toPercent(offset) {
                var percent = Math.floor(((offset - min) / (max - min)) * 100) / 100;
                if (inverse) {
                    percent = 1 - percent;
                }
                return percent;
            }
            function setPosition(pos) {
                if (inverse) {
                    pos = 1 - pos;
                }
                slider.setValue(Math.round(pos * max) + min);
            }
            slider.subscribe('slideStart',
            function() {
                if (this.valueChangeSource !== slider.SOURCE_SET_VALUE) {
                    that.startZoom(toPercent(slider.getValue()));
                }
            });
            slider.subscribe('slideEnd',
            function() {
                if (this.valueChangeSource !== slider.SOURCE_SET_VALUE) {
                    that.endZoom(toPercent(slider.getValue()));
                }
            });
            slider.subscribe('change',
            function(pos) {
                if (this.valueChangeSource !== slider.SOURCE_SET_VALUE) {
                    that.scaleMap(toPercent(pos));
                }
            });
            this.sliders.push({
                slider: slider,
                toPercent: toPercent,
                setPosition: setPosition,
                isShown: true
            });
        },
        setZoomSliderPosition: function(pos) {
            LMI.Lang.forEach(this.sliders,
            function(s) {
                s.setPosition(pos);
            });
        }
    });
    var proto = InteractiveMap.prototype,
    superclass = InteractiveMap.superclass;
    proto.initOptions = function(options) {
        var opts = LMI.Lang.mergeObjects({},
        InteractiveMap.Defaults);
        LMI.Lang.mergeObjects(opts, options);
        superclass.initOptions.call(this, opts);
    };
    proto.initContainer = function() {
        superclass.initContainer.apply(this, arguments);
        this.mapDragger = new DSInteraction.Drag(this.mapLayer, {
            disable: true
        });
        this.mapDragger.bindEvent('startDrag', this, this.startDrag);
        this.mapDragger.bindEvent('drag', this, this.drag);
        this.mapDragger.bindEvent('endDrag', this, this.endDrag);
    };
    proto.initSlideObject = function() {
        if (this.slideObject) {
            this.slideObject.skipToEnd();
        }
    };
    proto.getSlideObject = function(b, e) {
        var l = this.mapLayer,
        a = new LMI.Animation.Motion(l, b, e);
        this.slideObject = a;
        a.bindEvent('tween', this, this.updateMap);
        a.setDuration(this.animationDuration);
        a.setEasingMethod(this.easingMethod);
        return a;
    };
    proto.isSlideDistanceValid = function(b, e) {
        var xLimit = this.width * 3,
        yLimit = this.height * 3;
        return (Math.abs(b.x - e.x) < xLimit) && (Math.abs(b.y - e.y) < yLimit);
    };
    proto.slideToPoint = function(p) {
        this.initSlideObject();
        var c = this.getCenterPoint();
        if (c && !p.equals(c)) {
            var oldxy = this.tileManager.getPosition(this.getCenterPoint());
            var newxy = this.tileManager.getPosition(p);
            var b = {
                x: this.getMapLeft(true),
                y: this.getMapTop(true)
            };
            var e = {
                x: b.x - (newxy.x - oldxy.x),
                y: b.y - (newxy.y - oldxy.y)
            };
            if (this.isSlideDistanceValid(b, e)) {
                this.prepareEventObject();
                this.tileManager.setCenterPoint(p);
                var a = this.getSlideObject(b, e);
                a.bindEvent('end', this, this.endSlide);
                a.start();
            } else {
                this.centerOnPoint(p);
            }
        }
    };
    proto.slideBy = function(x, y) {
        this.initSlideObject();
        var b = {
            x: this.getMapLeft(true),
            y: this.getMapTop(true)
        },
        e = {
            x: b.x + x,
            y: b.y + y
        };
        var a = this.getSlideObject(b, e);
        a.bindEvent('end', this, this.endSlideBy);
        a.start();
    };
    proto.endSlide = function(e) {
        this.slideObject = null;
        var o = this.getEventObject();
        if (e.endedEarly) {
            o.endedEarly = true;
        }
        this.triggerEvent('recenter', o, this);
    };
    proto.endSlideBy = function(e) {
        this.updateMap();
        this.endSlide(e);
    };
    proto.setEasingMethod = function(method) {
        this.easingMethod = method;
    };
    proto.enableDragging = function() {
        $D.addClass(this.container, 'dsMapDraggable');
        this.mapDragger.enable();
        if (!this.dblclick) {
            this.dblclick = $E.on(this.viewport, 'dblclick', this.centerOnClick, this, true);
        }
    };
    proto.startDrag = function() {
        this.hasDragged = false;
        $D.addClass(this.container, 'dsMapDragging');
        this.prepareEventObject();
    };
    proto.endDrag = function() {
        var o;
        $D.removeClass(this.container, 'dsMapDragging');
        if (this.hasDragged) {
            this.updateMap();
            o = this.getEventObject();
            this.triggerEvent('recenter', o, this);
        }
    };
    proto.drag = function() {
        this.hasDragged = true;
        this.updateMap();
    };
    proto.centerOnClick = function(e) {
        if (e.ctrlKey && e.altKey) {
            this.setEasingMethod(Y.Easing.bounceOut);
            if (this.overviewMap) {
                this.overviewMap.setEasingMethod(Y.Easing.bounceOut);
            }
        }
        var xy = LMI.Element.getOffsets(this.viewport);
        this.slideBy((this.width / 2) - ($E.getPageX(e) - xy.x), (this.height / 2) - ($E.getPageY(e) - xy.y));
        $E.stopPropagation(e);
    };
    proto.hideContextMenu = function() {
        this._contextMenu.cfg.setProperty('visible', false);
    };
    proto.addContextMenuItem = function(item) {
        if (!this._contextMenuItems) {
            this._contextMenuItems = [];
        }
        if ('onclick' in item && !('obj' in item.onclick)) {
            item.onclick.obj = this;
        }
        this._contextMenuItems.push(item);
    };
    proto.addContextMenu = function() {
        var that = this;
        if (!YAHOO.env.getVersion('menu')) {
            this.addMessage('The context menu could not be added as the YUI menu library is not loaded');
            return;
        }
        if (!this._contextMenu) {
            function onOpen(type, args) {
                var e = args[0];
                that.contextMenuOpenX = $E.getPageX(e);
                that.contextMenuOpenY = $E.getPageY(e);
            }
            LMI.Lang.forEach(this.getOption('contextMenuItems'),
            function(c) {
                that.addContextMenuItem(c);
            });
            this._contextMenu = new YAHOO.widget.ContextMenu("mapContextMenu", {
                trigger: this.viewport,
                clicktohide: true,
                lazyload: false,
                monitorresize: false
            });
            if (this._contextMenuItems) {
                LMI.Lang.forEach(this._contextMenuItems,
                function(i) {
                    that._contextMenu.addItem(i);
                });
            }
            this._contextMenu.render(document.body);
            this._contextMenu.triggerContextMenuEvent.subscribe(onOpen);
            $E.on(this.viewport, 'click', this.hideContextMenu, this, true);
        }
    };
    proto.addControls = function(type) {
        var o, t, el, s, slider, i, p, sBg, sId, tId;
        if (!type) {
            type = LMI.Mapping.Controls.getLargeControls(this.getOption('imageBase'));
        }
        if (YAHOO.lang.isFunction(type)) {
            type = type(this.getOption('imageBase'));
        }
        if (type.zoom) {
            t = type.zoom.zoomIn;
            this.addDecorator(new DSMapControl(this, t[0], t[1], 'zoom', 'Zoom In', t[2]));
            t = type.zoom.zoomOut;
            this.zoomOutControl = new DSMapControl(this, t[0], t[1], 'zoom', 'Zoom Out', t[2]);
            this.addDecorator(this.zoomOutControl);
            el = this.zoomOutControl.getElement();
            this.zoomOutControl.origTop = parseFloat($D.getStyle(el, 'top'));
            this.zoomOutControl.origBottom = this.zoomOutControl.origTop + el.offsetHeight;
            if (type.zoom.slider && type.zoom.thumb) {
                s = type.zoom.slider;
                sBg = _E.create('div', null, {
                    className: 'slider control',
                    children: [{
                        tag: 'img',
                        src: s[0],
                        style: 'position: absolute'
                    }]
                });
                sBg = new DSMapDecorator(this, sBg, s[1], 'zoom', 'Zoom Slider');
                sId = $D.generateId(sBg.getElement());
                this.addDecorator(sBg);
                t = type.zoom.thumb;
                i = _E.create('img', sBg.getElement(), {
                    src: t[0],
                    height: t[1].height,
                    width: t[1].width,
                    style: 'position: absolute'
                });
                if ('left' in t[1]) {
                    i.style.left = t[1].left + 'px';
                }
                tId = $D.generateId(i);
                if (s[1].horizontal) {
                    slider = YAHOO.widget.Slider.getHorizSlider(sId, tId, 0, s[1].width - t[1].width);
                    this.addZoomSlider(slider, 0, s[1].width - t[1].width, s[1].invert);
                } else {
                    slider = YAHOO.widget.Slider.getVertSlider(sId, tId, 0, s[1].height - t[1].height);
                    this.addZoomSlider(slider, 0, s[1].height - t[1].height, s[1].invert);
                }
            }
        }
        p = type.misc;
        for (var j = 0; j < p.length; ++j) {
            this.addDecorator(new DSMapControl(this, p[j][0], p[j][3], p[j][1], p[j][2], p[j][4]));
        }
        o = type.options;
        if (o) {
            if (o.dragging) {
                this.enableDragging();
            }
            if (this.getOption('enableOverview') && o.overview) {
                this.overviewMap = new LMI.Mapping.OverviewMap(this, this.options);
            }
            if (o.contextMenu) {
                this.addContextMenu();
            }
        }
    };
    proto.startZoom = function(percent) {
        this.zooming = {
            mapCenter: this.getCenterPoint(),
            left: parseInt(this.mapLayer.style.left, 10),
            top: parseInt(this.mapLayer.style.top, 10),
            leftAdjusted: this.getMapLeft(),
            topAdjusted: this.getMapTop()
        };
        this.hideObjects();
        this.scaleMap(percent);
    };
    proto.endZoom = function(percent) {
        if (this.zooming) {
            this.showObjects();
            this.setZoomLevel(Math.round(percent * (this.tileManager.zoomLevels - 1)) + 1, this.zooming.mapCenter);
            this.zooming = null;
        }
    };
    proto.zoomIn = function() {
        this.setZoomLevel(this.zoomLevel - 1);
    };
    proto.zoomOut = function() {
        this.setZoomLevel(this.zoomLevel + 1);
    };
    proto.panNorth = function() {
        this.slideBy(0, 0.45 * this.height);
    };
    proto.panNorthEast = function() {
        this.slideBy( - 0.45 * this.width, 0.45 * this.height);
    };
    proto.panNorthWest = function() {
        this.slideBy(0.45 * this.width, 0.45 * this.height);
    };
    proto.panSouth = function() {
        this.slideBy(0, -0.45 * this.height);
    };
    proto.panSouthEast = function() {
        this.slideBy( - 0.45 * this.width, -0.45 * this.height);
    };
    proto.panSouthWest = function() {
        this.slideBy(0.45 * this.width, -0.45 * this.height);
    };
    proto.panEast = function() {
        this.slideBy( - 0.45 * this.width, 0);
    };
    proto.panWest = function() {
        this.slideBy(0.45 * this.width, 0);
    };
    proto.resizeLayers = function() {
        var o = {
            oldWidth: this.width,
            oldHeight: this.height,
            zoomLevel: this.zoomLevel
        };
        this.sizeLayers();
        this.triggerEvent('resize', o, this);
    };
    proto.appendRow = function() {
        var r = this.rows++;
        for (var i = 0; i < this.columns; ++i) {
            var t = new LMI.Mapping.Tile(this, this.tileLayer);
            t.setUrl(this.tileUrlFactory.getUrl(this.getGridLeft() + i, this.getGridTop() + r, this.zoomLevel));
            this.tiles.push(t);
        }
    };
    proto.removeRow = function() {
        this.rows--;
        var c = this.tiles.length - this.columns;
        while (this.tiles.length > c) {
            var i = this.tiles.length - 1;
            this.tiles[i].removeFromDom();
            this.tiles.splice(i, 1);
        }
    };
    proto.appendColumn = function() {
        var c = this.columns++;
        for (var i = 0; i < this.rows; ++i) {
            var n = (c * (1 + i)) + i;
            var t = new LMI.Mapping.Tile(this, this.tileLayer);
            t.setUrl(this.tileUrlFactory.getUrl(this.getGridLeft() + c, this.getGridTop() + i, this.zoomLevel));
            this.tiles.splice(n, 0, t);
        }
    };
    proto.removeColumn = function() {
        var c = this.columns--;
        for (var i = this.tiles.length - 1; i > 0; i -= c) {
            this.tiles[i].removeFromDom();
            this.tiles.splice(i, 1);
        }
    };
    proto.showObjects = function() {
        for (var it = new DSMapObject_Iterator(this.objects); it.hasNext();) {
            var o = it.next();
            o.element.style.visibility = 'visible';
        }
    };
    proto.hideObjects = function() {
        for (var it = new DSMapObject_Iterator(this.objects); it.hasNext();) {
            var o = it.next();
            o.element.style.visibility = 'hidden';
        }
    };
    proto.scaleMap = function(percent) {
        if (!this.zooming) {
            return;
        }
        this.tileManager.previewZoomLevel(percent * this.tileManager.zoomLevels);
        this.positionMap();
    };
    return InteractiveMap;
})();
function DSMapControl(map, src, pos, type, name, events) {
    var i = LMI.Element.create('img', null, {
        title: name,
        alt: name
    });
    YAHOO.util.Dom.addClass(i, 'control');
    LMI.Element.setImageSrc(i, src);
    DSMapControl.superclass.init.call(this, map, i, pos, type, name);
    this.events = events;
    this.addEventHandlers();
}
LMI.Lang.extend(DSMapControl, DSMapDecorator);
DSMapControl.prototype.addEventHandlers = function() {
    var $E = YAHOO.util.Event;
    for (var i in {
        click: '',
        dblclick: '',
        mousedown: ''
    }) {
        if (typeof this.events[i] == 'function') {
            if (i === 'click') {
                YAHOO.util.Dom.addClass(this.element, 'dsMapClickable');
            }
            $E.on(this.element, i, this.events[i], this.map, true);
        } else {
            $E.on(this.element, i, $E.stopEvent, $E, true);
        }
    }
};
LMI.Mapping.Controls = {};
LMI.Mapping.Controls.getLargeControls = function(imageBase) {
    if (typeof imageBase == 'undefined') {
        imageBase = LMI.Mapping.Map.Defaults.imageBase;
    }
    var M = LMI.Mapping.InteractiveMap.prototype,
    o = {
        left: 10,
        top: 10,
        zIndex: 100
    };
    return {
        zoom: {
            zoomIn: [imageBase + 'large_controls/map_zoom_in.png', {
                left: o.left + 25,
                top: o.top + 86,
                zIndex: o.zIndex,
                width: 24,
                height: 23
            },
            {
                click: M.zoomIn
            }],
            zoomOut: [imageBase + 'large_controls/map_zoom_out.png', {
                left: o.left + 25,
                top: o.top + 277,
                zIndex: o.zIndex,
                width: 24,
                height: 22
            },
            {
                click: M.zoomOut
            }],
            slider: [imageBase + 'large_controls/map_zoom_slider.png', {
                left: o.left + 25,
                top: o.top + 111,
                zIndex: o.zIndex,
                width: 24,
                height: 162,
                horizontal: false,
                invert: false
            }],
            thumb: [imageBase + 'large_controls/map_zoom_thumb.png', {
                left: -3,
                top: o.top + 205,
                zIndex: o.zIndex + 1,
                width: 30,
                height: 17
            }]
        },
        misc: [[imageBase + 'large_controls/map_pan_n.png', 'pan', 'Pan North', {
            left: o.left + 26,
            top: o.top,
            zIndex: o.zIndex,
            width: 19,
            height: 27
        },
        {
            click: M.panNorth
        }], [imageBase + 'large_controls/map_pan_ne.png', 'pan', 'Pan North-East', {
            left: o.left + 45,
            top: o.top + 8,
            zIndex: o.zIndex,
            width: 19,
            height: 19
        },
        {
            click: M.panNorthEast
        }], [imageBase + 'large_controls/map_pan_nw.png', 'pan', 'Pan North-West', {
            left: o.left + 7,
            top: o.top + 8,
            zIndex: o.zIndex,
            width: 19,
            height: 19
        },
        {
            click: M.panNorthWest
        }], [imageBase + 'large_controls/map_pan_s.png', 'pan', 'Pan South', {
            left: o.left + 26,
            top: o.top + 46,
            zIndex: o.zIndex,
            width: 19,
            height: 29
        },
        {
            click: M.panSouth
        }], [imageBase + 'large_controls/map_pan_se.png', 'pan', 'Pan South-East', {
            left: o.left + 44,
            top: o.top + 46,
            zIndex: o.zIndex,
            width: 19,
            height: 19
        },
        {
            click: M.panSouthEast
        }], [imageBase + 'large_controls/map_pan_sw.png', 'pan', 'Pan South-West', {
            left: o.left + 9,
            top: o.top + 46,
            zIndex: o.zIndex,
            width: 17,
            height: 17
        },
        {
            click: M.panSouthWest
        }], [imageBase + 'large_controls/map_pan_e.png', 'pan', 'Pan East', {
            left: o.left + 45,
            top: o.top + 27,
            zIndex: o.zIndex,
            width: 28,
            height: 19
        },
        {
            click: M.panEast
        }], [imageBase + 'large_controls/map_pan_w.png', 'pan', 'Pan West', {
            left: o.left,
            top: o.top + 27,
            zIndex: o.zIndex,
            width: 26,
            height: 19
        },
        {
            click: M.panWest
        }], [imageBase + 'large_controls/map_pan_center.png', 'pan', 'Best Fit', {
            left: o.left + 26,
            top: o.top + 27,
            zIndex: o.zIndex,
            width: 19,
            height: 19
        },
        {
            click: LMI.Mapping.Map.prototype.bestFitEventHandler
        }]],
        options: {
            overview: true,
            contextMenu: true,
            dragging: true
        }
    };
};
LMI.Mapping.Controls.getSmallControls = function(imageBase) {
    if (typeof imageBase == 'undefined') {
        imageBase = LMI.Mapping.Map.Defaults.imageBase;
    }
    var M = LMI.Mapping.InteractiveMap.prototype,
    o = {
        left: 10,
        top: 10,
        zIndex: 100
    };
    return {
        zoom: {
            zoomIn: [imageBase + 'small_controls/map_zoom_in.gif', {
                left: o.left + 19,
                top: o.top + 63,
                zIndex: o.zIndex,
                width: 15,
                height: 14
            },
            {
                click: M.zoomIn
            }],
            zoomOut: [imageBase + 'small_controls/map_zoom_out.gif', {
                left: o.left + 19,
                top: o.top + 197,
                zIndex: o.zIndex,
                width: 15,
                height: 14
            },
            {
                click: M.zoomOut
            }],
            slider: [imageBase + 'small_controls/map_zoom_slider.gif', {
                left: o.left + 19,
                top: o.top + 82,
                zIndex: o.zIndex,
                width: 15,
                height: 110,
                horizontal: false,
                invert: false
            }],
            thumb: [imageBase + 'small_controls/map_zoom_thumb.png', {
                left: -3,
                top: o.top + 193,
                zIndex: o.zIndex + 1,
                width: 21,
                height: 11
            }]
        },
        misc: [[imageBase + 'small_controls/map_pan_n.gif', 'pan', 'Pan North', {
            left: o.left + 19,
            top: o.top,
            zIndex: o.zIndex,
            width: 15,
            height: 19
        },
        {
            click: M.panNorth
        }], [imageBase + 'small_controls/map_pan_ne.gif', 'pan', 'Pan North-East', {
            left: o.left + 33,
            top: o.top + 8,
            zIndex: o.zIndex,
            width: 12,
            height: 12
        },
        {
            click: M.panNorthEast
        }], [imageBase + 'small_controls/map_pan_nw.gif', 'pan', 'Pan North-West', {
            left: o.left + 8,
            top: o.top + 8,
            zIndex: o.zIndex,
            width: 12,
            height: 12
        },
        {
            click: M.panNorthWest
        }], [imageBase + 'small_controls/map_pan_s.gif', 'pan', 'Pan South', {
            left: o.left + 19,
            top: o.top + 34,
            zIndex: o.zIndex,
            width: 15,
            height: 19
        },
        {
            click: M.panSouth
        }], [imageBase + 'small_controls/map_pan_se.gif', 'pan', 'Pan South-East', {
            left: o.left + 33,
            top: o.top + 33,
            zIndex: o.zIndex,
            width: 12,
            height: 12
        },
        {
            click: M.panSouthEast
        }], [imageBase + 'small_controls/map_pan_sw.gif', 'pan', 'Pan South-West', {
            left: o.left + 8,
            top: o.top + 33,
            zIndex: o.zIndex,
            width: 12,
            height: 12
        },
        {
            click: M.panSouthWest
        }], [imageBase + 'small_controls/map_pan_e.gif', 'pan', 'Pan East', {
            left: o.left + 34,
            top: o.top + 19,
            zIndex: o.zIndex,
            width: 19,
            height: 15
        },
        {
            click: M.panEast
        }], [imageBase + 'small_controls/map_pan_w.gif', 'pan', 'Pan West', {
            left: o.left,
            top: o.top + 19,
            zIndex: o.zIndex,
            width: 19,
            height: 15
        },
        {
            click: M.panWest
        }], [imageBase + 'small_controls/map_pan_center.gif', 'pan', 'Best Fit', {
            left: o.left + 19,
            top: o.top + 19,
            zIndex: o.zIndex,
            width: 15,
            height: 15
        },
        {
            click: LMI.Mapping.Map.prototype.bestFitEventHandler
        }]],
        options: {
            overview: false,
            dragging: true
        }
    };
};
LMI.Mapping.Outline = (function() {
    var $D = YAHOO.util.Dom,
    _E = LMI.Element;
    function Outline(point, width, height) {
        this.init(point, width, height);
    }
    YAHOO.lang.extend(Outline, LMI.Mapping.MapObject, {
        init: function(point, width, height) {
            var o = _E.create('div', null, {
                className: 'outline'
            }),
            e = _E.create('div', o, {
                className: 'fill'
            });
            $D.setStyle(o, 'opacity', 0.6);
            $D.setStyle(e, 'opacity', 0.25);
            Outline.superclass.init.call(this, point, o);
            this.setWidth(width);
            this.setHeight(height);
        },
        setWidth: function(w) {
            this.element.style.width = w + 'px';
        },
        setHeight: function(h) {
            this.element.style.height = h + 'px';
        }
    });
    return Outline;
})();
LMI.Mapping.OverviewMap = (function() {
    var Y = YAHOO.util,
    $D = Y.Dom,
    _E = LMI.Element,
    _$ = _E.getAll;
    var OverviewMap = function(map, options) {
        this.init(map, options);
    };
    OverviewMap.Defaults = {
        collapsedWidth: 12,
        collapsedHeight: 12,
        gutterWidth: 7,
        gutterHeight: 7,
        overviewCollapsed: false,
        sizeAnimationDuration: 1
    };
    YAHOO.lang.extend(OverviewMap, LMI.Mapping.InteractiveMap, {
        init: function(map, options) {
            var width, height, gutterWidth, gutterHeight, mapCont;
            this.parentMap = map;
            this.gutter = _E.create('div', map.decoratorLayer);
            $D.addClass(this.gutter, 'gutter');
            mapCont = _E.create('div', this.gutter);
            OverviewMap.superclass.init.call(this, mapCont, options);
            $D.addClass(mapCont, 'dsOverview');
            if (this.getOption('overviewCollapsed')) {
                width = this.getOption('collapsedWidth');
                height = this.getOption('collapsedHeight');
                gutterWidth = 0;
                gutterHeight = 0;
                this.expanded = false;
                $D.addClass(this.gutter, 'collapsed');
            } else {
                width = this.getOption('overviewWidth');
                height = this.getOption('overviewHeight');
                gutterWidth = width + this.getOption('gutterWidth');
                gutterHeight = height + this.getOption('gutterHeight');
                this.expanded = true;
                this.watchParent();
            }
            $D.setStyle(this.gutter, 'width', gutterWidth + 'px');
            $D.setStyle(this.gutter, 'height', gutterHeight + 'px');
            $D.setStyle(mapCont, 'width', width + 'px');
            $D.setStyle(mapCont, 'height', height + 'px');
            this.resizeLayers();
            this.width = this.getOption('overviewWidth');
            this.height = this.getOption('overviewHeight');
            this.setCopyright('');
            this.initEvents('collapse', 'expand');
            this.sizeDuration = this.getOption('sizeAnimationDuration');
            this.addControls(LMI.Mapping.Controls.getOverviewControls(this.getOption('imageBase')));
            this.collapseControl = this.decorators.getByType('collapse')[0];
            this.updateCollapseControlIcon();
            this.bindEvent('recenter', this, this.updateParent);
        },
        initOptions: function(options) {
            var opts = LMI.Lang.mergeObjects({},
            OverviewMap.Defaults);
            LMI.Lang.mergeObjects(opts, options);
            opts.enableResize = false;
            opts.enableScales = false;
            OverviewMap.superclass.initOptions.call(this, opts);
        },
        initContainer: function() {
            $D.setStyle(this.container, 'width', this.getOption('overviewWidth') + 'px');
            $D.setStyle(this.container, 'height', this.getOption('overviewHeight') + 'px');
            OverviewMap.superclass.initContainer.call(this);
        },
        updateDataCopyright: function() {},
        watchParent: function() {
            var that = this;
            if (this.parentMap.getCenterPoint()) {
                this.update();
            }
            if (!this.parentEvents) {
                this.parentEvents = {};
            }
            LMI.Lang.forEach(['recenter', 'zoom', 'resize'],
            function(e) {
                if (!that.parentEvents[e]) {
                    that.parentEvents[e] = that.parentMap.bindEvent(e, that, that.update);
                }
            });
        },
        stopWatchingParent: function() {
            if (this.parentEvents) {
                for (var e in this.parentEvents) {
                    if (this.parentEvents[e]) {
                        this.parentMap.removeEventListener(this.parentEvents[e]);
                        this.parentEvents[e] = null;
                    }
                }
            }
        },
        update: function(e) {
            var grid, w, h, nexy, swxy, fitFactor = 0.4,
            maxFitFactor = 0.9,
            m = this.parentMap,
            ne = m.getURPoint(),
            sw = m.getLLPoint(),
            zoom = this.tileManager.getZoomByBounds({
                upper: ne,
                lower: sw
            },
            this.width * fitFactor, this.height * fitFactor);
            this.centerAndZoom(m.getCenterPoint(), zoom);
            grid = this.tileManager.getGrid();
            nexy = grid.toXY(ne);
            swxy = grid.toXY(sw);
            w = Math.abs(nexy.x - swxy.x);
            h = Math.abs(nexy.y - swxy.y);
            if (w < this.width * maxFitFactor && h < this.height * maxFitFactor) {
                if (this.outline) {
                    this.outline.setWidth(w);
                    this.outline.setHeight(h);
                    this.positionObject(this.outline, m.getULPoint());
                } else {
                    this.outline = new LMI.Mapping.Outline(m.getULPoint(), w, h);
                    this.outlineDragger = new DSInteraction.Drag(this.outline.element);
                    this.outlineDragger.bindEvent('startDrag', this, this.outlineGrab);
                    this.outlineDragger.bindEvent('endDrag', this, this.outlineDrop);
                    this.addObject(this.outline);
                }
            } else {
                if (this.outline) {
                    this.removeObject(this.outline);
                    this.outline = null;
                }
            }
        },
        updateParent: function(e) {
            this.parentMap.slideToPoint(e.center);
        },
        outlineGrab: function(dragEvt, e) {
            var el = e.element;
            $D.addClass(el, 'dsMapDragging');
        },
        outlineDrop: function(dragEvt, e) {
            var el = e.element,
            x = dragEvt.elementEndPosition.x,
            y = dragEvt.elementEndPosition.y,
            p = this.tileManager.getPointByPosition(x, y);
            $D.removeClass(el, 'dsMapDragging');
            this.positionObject(this.outline, p);
            x += parseInt($D.getStyle(this.outline.element, 'width'), 10) / 2;
            y += parseInt($D.getStyle(this.outline.element, 'height'), 10) / 2;
            this.parentMap.slideToPoint(this.tileManager.getPointByPosition(x, y));
        },
        doSize: function(p, expanding) {
            var a, ease = this.expanded ? Y.Easing.bounceOut: Y.Easing.elasticOut;
            if (this.sizeAnimation) {
                this.sizeAnimation.stop(true);
            }
            $D.setStyle(_$('.decLayer>img', this.container), 'visibility', 'hidden');
            this.sizeDurationMS = this.sizeDuration * 1000;
            a = this.sizeAnimation = new Y.Anim(this.container, p, this.sizeDuration, ease);
            a.onTween.subscribe(this.resizing, this, true);
            a.onComplete.subscribe(this.endSizing, this, true);
            a.animate();
            this.expanded = expanding;
        },
        resizing: function(type, args) {
            var pos = args[0].duration / this.sizeDurationMS,
            gap = this.expanded ? Math.floor(pos * 7) : 7 - Math.floor(pos * 7);
            this.gutter.style.width = (this.container.offsetWidth + gap) + 'px';
            this.gutter.style.height = (this.container.offsetHeight + gap) + 'px';
            this.viewport.style.width = this.decoratorLayer.style.width = $D.getStyle(this.container, 'width');
            this.viewport.style.height = this.decoratorLayer.style.height = $D.getStyle(this.container, 'height');
        },
        endSizing: function() {
            var w, h;
            this.sizeAnimation = null;
            if (!this.expanded) {
                $D.addClass(this.gutter, 'collapsed');
            } else {
                w = $D.getStyle(this.container, 'width');
                h = $D.getStyle(this.container, 'height');
                this.gutter.style.width = (parseInt(w, 10) + 7) + 'px';
                this.gutter.style.height = (parseInt(h, 10) + 7) + 'px';
                this.viewport.style.width = this.decoratorLayer.style.width = w;
                this.viewport.style.height = this.decoratorLayer.style.height = h;
            }
            this.updateCollapseControlIcon();
            $D.setStyle(_$('.decLayer>img', this.container), 'visibility', 'visible');
        },
        updateCollapseControlIcon: function() {
            var that = this;
            if (this.expanded) {
                window.setTimeout(function() {
                    _E.setImageSrc(that.collapseControl.getElement(), that.getOption('imageBase') + 'map_collapse.png');
                },
                0);
            } else {
                window.setTimeout(function() {
                    _E.setImageSrc(that.collapseControl.getElement(), that.getOption('imageBase') + 'map_expand.png');
                },
                0);
            }
        },
        toggleExpandState: function() {
            var p, evt;
            if (this.expanded) {
                p = {
                    width: {
                        to: this.getOption('collapsedWidth')
                    },
                    height: {
                        to: this.getOption('collapsedHeight')
                    }
                };
                evt = 'collapse';
                this.stopWatchingParent();
            } else {
                $D.removeClass(this.gutter, 'collapsed');
                p = {
                    width: {
                        to: this.width
                    },
                    height: {
                        to: this.height
                    }
                };
                evt = 'expand';
                this.watchParent();
            }
            this.doSize(p, evt === 'expand');
            this.triggerEvent(evt, {},
            this);
        }
    });
    return OverviewMap;
})();
LMI.Mapping.Controls.getOverviewControls = function(imageBase) {
    if (typeof imageBase === 'undefined') {
        imageBase = LMI.Mapping.Map.Defaults.imageBase;
    }
    return {
        misc: [[imageBase + 'map_collapse.png', 'collapse', 'Expand/Collapse', {
            right: 0,
            top: 0,
            zIndex: 100,
            width: 11,
            height: 11
        },
        {
            click: LMI.Mapping.OverviewMap.prototype.toggleExpandState
        }]],
        options: {
            overview: false,
            dragging: true
        }
    };
};
LMI.Mapping.FlyoutFactory = (function() {
    var _E = LMI.Element,
    create = _E.create,
    $ = _E.getOne,
    hop = YAHOO.lang.hasOwnProperty,
    $E = YAHOO.util.Event;
    function FlyoutFactory() {
        this.init();
    }
    FlyoutFactory.prototype = {
        init: function() {
            this.contents = {
                'default': FlyoutFactory.defaultFlyoutContent,
                ambig: FlyoutFactory.defaultAmbigContent
            };
            this.styles = {
                'default': {
                    creator: FlyoutFactory.defaultFlyoutStyle,
                    xOffset: 3,
                    yOffset: 8,
                    zOffset: 5
                }
            };
        },
        clone: function() {
            var i, j, f = new LMI.Mapping.FlyoutFactory();
            for (i in this.contents) {
                if (hop(this.contents, i)) {
                    f.contents[i] = this.contents[i];
                }
            }
            for (i in this.styles) {
                if (hop(this.styles, i)) {
                    f.styles[i] = {};
                    for (j in this.styles[i]) {
                        if (hop(this.styles[i], j)) {
                            f.styles[i][j] = this.styles[i][j];
                        }
                    }
                }
            }
            return f;
        },
        addContentCreator: function(type, creator) {
            this.contents[type] = creator;
        },
        addStyle: function(style, creator, options) {
            var s = {
                creator: creator
            };
            if (!options) {
                s.xOffset = 0;
                s.yOffset = 0;
                s.zOffset = 5;
            } else {
                LMI.Lang.forEach(['xOffset', 'yOffset', 'zOffset'],
                function(p) {
                    if (p in options) {
                        s[p] = options[p];
                    } else {
                        s[p] = p === 'zOffset' ? 5 : 0;
                    }
                });
            }
            this.styles[style] = s;
        },
        getFlyout: function(point, poi, type, style) {
            type = type || 'default';
            style = style || 'default';
            var content = this.contents[type](poi),
            s = this.styles[style];
            return new LMI.Mapping.Flyout(point, s.creator(content, poi), s.xOffset, s.yOffset, s.zOffset);
        }
    };
    FlyoutFactory.defaultFlyoutStyle = function(content, poi) {
        var baseUrl = poi.map.getOption('imageBase'),
        boxSrc = baseUrl + 'flyout_box.png';
        var f = create('div', null, {
            className: 'flyout',
            id: 'LMIMapFlyout',
            children: [{
                tag: 'img',
                src: baseUrl + 'flyout_close.gif',
                alt: '',
                className: 'flyoutClose',
                events: {
                    click: function() {
                        poi.hideFlyout();
                    }
                }
            },
            {
                tag: 'div',
                className: 'content',
                children: [{
                    tag: 'img',
                    src: baseUrl + 'flyout_print.gif',
                    className: 'printonly',
                    alt: ''
                }]
            },
            {
                tag: 'div',
                className: 'flyoutCorner flyoutBL',
                children: [{
                    tag: 'img',
                    src: boxSrc,
                    alt: ''
                }]
            },
            {
                tag: 'div',
                className: 'flyoutCorner flyoutTR',
                children: [{
                    tag: 'img',
                    src: boxSrc,
                    alt: ''
                }]
            },
            {
                tag: 'div',
                className: 'flyoutCorner flyoutBR',
                children: [{
                    tag: 'img',
                    src: boxSrc,
                    alt: ''
                }]
            },
            {
                tag: 'img',
                src: baseUrl + 'flyout_pointy_corner_tl.png',
                alt: '',
                className: 'flyoutTL'
            },
            {
                tag: 'div',
                className: 'flyoutCap'
            },
            {
                tag: 'div',
                className: 'flyoutBoot'
            }]
        });
        $('div.content', f).appendChild(content);
        return f;
    };
    FlyoutFactory.defaultFlyoutContent = function() {
        return create('div', null, {
            textValue: 'no content'
        });
    };
    FlyoutFactory.defaultAmbigContent = function(poi) {
        var ul, li, name, a, d = create('div', null, {
            className: 'ambigFlyout'
        });
        create('div', d, {
            textValue: 'Multiple Matches:',
            className: 'flyoutName'
        });
        ul = create('ul', d);
        LMI.Lang.forEach([poi].concat(poi.collisions),
        function(o, i) {
            name = o.getProperty('name') || o.getProperty('displayValue');
            li = create('li', ul, {
                className: i === 0 ? 'first': ''
            });
            a = create('a', li, {
                textValue: name,
                href: '#'
            });
            $E.on(a, 'click',
            function(e) {
                o.showFlyout();
                $E.stopEvent(e);
            });
        });
        return d;
    };
    return FlyoutFactory;
})();
LMI.Mapping.Flyout = function(point, el, x, y, z) {
    var $E = YAHOO.util.Event;
    this.init(point, el);
    $E.on(el, 'mousedown', $E.stopPropagation, $E, true);
    $E.on(el, 'dblclick', $E.stopPropagation, $E, true);
    this.setXOffset(x);
    this.setYOffset(y);
    this.setZOffset(z);
};
YAHOO.lang.extend(LMI.Mapping.Flyout, LMI.Mapping.MapObject);
LMI.Mapping.IconWithFlyout = (function() {
    var collection = new DSMapObject_Collection();
    function IconWithFlyout(point, index) {
        this.init(point, index);
    }
    LMI.Lang.extend(IconWithFlyout, LMI.Mapping.Icon);
    var proto = IconWithFlyout.prototype,
    superclass = IconWithFlyout.superclass;
    function _overlaps(o1, o2, hTolerance, vTolerance) {
        var e1 = o1.element,
        e2 = o2.element,
        he1 = o1.getWidth() / 2,
        he2 = o2.getWidth() / 2,
        ve1 = o1.getHeight() / 2,
        ve2 = o2.getHeight() / 2,
        x1 = parseInt(e1.style.left, 10) + he1,
        y1 = parseInt(e1.style.top, 10) + ve1,
        x2 = parseInt(e2.style.left, 10) + he2,
        y2 = parseInt(e2.style.top, 10) + ve2,
        hOverlap = (he1 + he2) - Math.abs(x2 - x1),
        vOverlap = (ve1 + ve2) - Math.abs(y2 - y1);
        if (!hTolerance) {
            hTolerance = 0;
        }
        if (!vTolerance) {
            vTolerance = 0;
        }
        return (hOverlap > hTolerance && vOverlap > vTolerance);
    }
    proto.init = function(point, index) {
        this.flyouts = {};
        superclass.init.call(this, point, index);
        this.bindEvent('click', this, this.iconClick);
    };
    proto.update = function() {
        if (!this.shownOnMap) {
            this._id = collection.add(this);
        }
        superclass.update.apply(this, arguments);
    };
    proto.remove = function() {
        this.hideFlyout();
        this.flyouts = {};
        if (this.shownOnMap) {
            collection.remove(this._id);
        }
        superclass.remove.apply(this, arguments);
    };
    proto.scrollMapToFlyout = function(f) {
        var x = 0,
        y = 0,
        m = this.map.mapLayer,
        vp = this.map.viewport,
        left = parseInt(f.element.style.left, 10) + parseInt(m.style.left, 10),
        top = parseInt(f.element.style.top, 10) + parseInt(m.style.top, 10);
        if (left - this.getLeftBuffer() < 0) {
            x = left - this.getLeftBuffer();
        } else if (left + f.element.offsetWidth + this.getRightBuffer() > vp.offsetWidth) {
            x = f.element.offsetWidth - vp.offsetWidth + left + this.getRightBuffer();
            if (left - x < 0) {
                x = left - this.getLeftBuffer();
            }
        }
        if (top - this.getTopBuffer() < 0) {
            y = top - this.getTopBuffer();
        } else if (top + f.element.offsetHeight + this.getBottomBuffer() > vp.offsetHeight) {
            y = f.element.offsetHeight - vp.offsetHeight + top + this.getBottomBuffer();
            if (top - y < 0) {
                y = top - this.getTopBuffer();
            }
        }
        if (x !== 0 || y !== 0) {
            this.map.slideBy( - x, -y);
        }
    };
    proto.getBottomBuffer = function() {
        return 30;
    };
    proto.getTopBuffer = function() {
        return 30;
    };
    proto.getLeftBuffer = function() {
        return 30;
    };
    proto.getRightBuffer = function() {
        return 30;
    };
    proto.findCollisions = function() {
        this.collisions = [];
        for (var it = new DSMapObject_Iterator(collection); it.hasNext();) {
            o = it.next();
            if (o !== this && _overlaps(this, o, (o.getWidth() / 3), (o.getHeight() / 3))) {
                this.collisions.push(o);
            }
        }
    };
    proto.iconClick = function(e) {
        if (this.getActiveFlyout()) {
            this.hideFlyout();
        } else {
            this.findCollisions();
            if (this.collisions.length) {
                this.showFlyout('ambig');
            } else {
                this.showFlyout('default');
            }
        }
        YAHOO.util.Event.stopEvent(e);
    };
    proto.showFlyout = function(type, style) {
        var f;
        type = type || 'default';
        IconWithFlyout.hideFlyouts();
        this.setZIndex(this.z + 1);
        f = this.flyouts[type] = {
            type: type,
            id: null,
            flyout: this.getFlyoutFactory().getFlyout(this.point, this, type, style)
        };
        f.id = this.map.addObject(f.flyout);
        this.scrollMapToFlyout(f.flyout);
    };
    proto.hideFlyout = function() {
        var f = this.getActiveFlyout();
        if (f) {
            this.map.removeObject(f.id);
            f.id = null;
        }
        this.setZIndex(this.z);
    };
    proto.getActiveFlyout = function() {
        var f, i;
        for (i in this.flyouts) {
            if (this.flyouts.hasOwnProperty(i)) {
                f = this.flyouts[i];
                if (typeof f === 'object' && f.id) {
                    return f;
                }
            }
        }
        return null;
    };
    IconWithFlyout.getActiveFlyouts = function() {
        var f, a = [],
        it = new DSMapObject_Iterator(collection);
        while (it.hasNext()) {
            f = it.next().getActiveFlyout();
            if (f) {
                a.push(f);
            }
        }
        return a;
    };
    IconWithFlyout.hideFlyouts = function() {
        var it = new DSMapObject_Iterator(collection);
        while (it.hasNext()) {
            it.next().hideFlyout();
        }
    };
    IconWithFlyout.flyoutFactory = new LMI.Mapping.FlyoutFactory();
    proto.getFlyoutFactory = function() {
        return IconWithFlyout.flyoutFactory;
    };
    return IconWithFlyout;
})();
LMI.Mapping.AerialTileFactory = (function() {
    function AerialTileFactory(map) {
        var v;
        this.map = map;
        if ((v = map.getOption('aerialLayerStack'))) {
            this.layerStack = v;
        } else {
            throw new Error('the map config option "aerialLayerStack" must be set');
        }
        if ((v = map.getOption('aerialTileBase'))) {
            this.base = v;
        } else {
            throw new Error('the map config option "aerialTileBase" must be set');
        }
        if ((v = map.getOption('aerialClientId'))) {
            this.clientId = v;
        } else {
            throw new Error('the map config option "aerialClientId" must be set');
        }
        if ((v = map.getOption('aerialAppId'))) {
            this.appId = v;
        } else {
            throw new Error('the map config option "aerialAppId" must be set');
        }
        this.setPre();
    }
    AerialTileFactory.prototype = {
        getUrl: function(x, y, z) {
            var ul = this.map.gridSystem.toLL(x * 256, y * 256),
            lr = this.map.gridSystem.toLL((x * 256) + 256, (y * 256) + 256),
            p = new EquiRectangularMapProjection(radians(0.0), radians(40.0)),
            xyUL = p.forward(radians(ul.lng), radians(ul.lat)),
            xyLR = p.forward(radians(lr.lng), radians(lr.lat));
            return this.pre + '&xul=' + xyUL.x + '&yul=' + xyUL.y + '&xlr=' + xyLR.x + '&ylr=' + xyLR.y;
        },
        setPre: function() {
            var proj4 = '+proj=eqc +lat_ts=40.0000 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs';
            this.pre = this.base + '?cmd=image&proj=eqc&lat_ts=40&iw=256&ih=256&ls=' + this.layerStack + '&id=' + this.clientId + '&appID=' + this.appId + '&projid=' + encodeURIComponent(proj4);
        }
    };
    return AerialTileFactory;
})();
LMI.Mapping.TileSwitcher = (function() {
    var Y = YAHOO.util,
    $D = Y.Dom,
    $E = Y.Event,
    _E = LMI.Element;
    var map, overviewMap, tileManagers = {},
    ovTileManagers = {},
    links = {},
    linkList, activeTileSet;
    function switchTileSet(key) {
        if (activeTileSet !== key) {
            if (links[activeTileSet]) {
                $D.removeClass(links[activeTileSet], 'selected');
            } else {
                $D.removeClass(LMI.Element.getOne('.mapTilesLinks .default a'), 'selected');
            }
            $D.addClass(links[key], 'selected');
            map.setTileManager(tileManagers[key]);
            if (overviewMap) {
                overviewMap.setTileManager(ovTileManagers[key]);
            }
            activeTileSet = key;
        }
    }
    function addTileSetButtons() {
        linkList = _E.create('ul', null, {
            className: 'linkList horizontalLinkList mapTilesLinks'
        });
        addTileSet('default', null, 'Kort');
        addTileSet('aerial', LMI.Mapping.AerialTileManager, 'Luftfoto');
        addTileSet('hybrid', LMI.Mapping.HybridTileManager, 'Kombineret');
        //addTileSet('topo', LMI.Mapping.TopoTileManager, 'Topo');
        map.addDecorator(new DSMapDecorator(map, linkList, {},
        'tileSets', 'list'));
    }
    function addTileSet(key, manager, string) {
        var cl = '',
        li = _E.create('li', linkList, {
            className: key
        });
        var storedDefault = getDefaultTileSetName();
        if (storedDefault) {
            if (storedDefault == key) {
                cl = 'selected';
            }
        } else if (key == 'default') {
            cl = 'selected';
        }
        links[key] = _E.create('a', li, {
            href: '#',
            text: string,
            events: {
                click: function(e) {
                    $E.stopEvent(e);
                    switchTileSet(key);
                }
            },
            className: cl
        });
        if (manager) {
            tileManagers[key] = new manager(map.tileLayer, {
                width: map.width,
                height: map.height
            });
            if (map.overviewMap) {
                ovTileManagers[key] = new manager(map.overviewMap.tileLayer, {
                    width: overviewMap.width,
                    height: overviewMap.height
                });
            }
        }
    }
    function getActiveTileSetName() {
        return activeTileSet || 'default';
    }
    function getDefaultTileSetName() {
        return 'default';
    }
    function init(m) {
        map = m;
        if (m.overviewMap) {
            overviewMap = m.overviewMap;
        }
        addTileSetButtons();
        tileManagers['default'] = map.getTileManager();
        if (map.overviewMap) {
            ovTileManagers['default'] = map.overviewMap.getTileManager();
        }
        var defaultTileSet = getDefaultTileSetName();
        if (defaultTileSet) {
            switchTileSet(defaultTileSet);
        }
    }
    return {
        init: init,
        getActiveTileSetName: getActiveTileSetName
    };
})();
LMI.Mapping.OverlayTile = (function() {
    function OverlayTile(el, options) {
        this.init(el, options);
    }
    OverlayTile.defaults = {
        brokenTile: '/images/pixel_trans.gif'
    };
    YAHOO.lang.extend(OverlayTile, LMI.Mapping.Tile, {
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            LMI.Mapping.Tile.defaults);
            LMI.Lang.mergeObjects(this.options, OverlayTile.defaults);
            if ('config' in LMI.Mapping.Tile) {
                LMI.Lang.mergeObjects(this.options, LMI.Mapping.Tile.config);
            }
            if ('config' in OverlayTile) {
                LMI.Lang.mergeObjects(this.options, OverlayTile.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        }
    });
    return OverlayTile;
})();
LMI.Mapping.AerialTileManager = (function() {
    function AerialTileManager(el, options) {
        this.init(el, options);
    }
    YAHOO.lang.extend(AerialTileManager, LMI.Mapping.TileManager, {
        initOptions: function(options) {
            AerialTileManager.superclass.initOptions.call(this);
            if ('config' in AerialTileManager) {
                LMI.Lang.mergeObjects(this.options, AerialTileManager.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        }
    });
    return AerialTileManager;
})();
LMI.Mapping.HybridTileManager = (function() {
    function HybridTileManager(el, options) {
        this.init(el, options);
    }
    HybridTileManager.defaults = {
        overlayUrlStrategy: LMI.Mapping.TileUrl,
        overlayUrlOptions: {}
    };
    YAHOO.lang.extend(HybridTileManager, LMI.Mapping.TileManager, {
        init: function() {
            this.overlayTiles = [];
            HybridTileManager.superclass.init.apply(this, arguments);
            this.overlayUrls = new this.options.overlayUrlStrategy(this.options.overlayUrlOptions);
            if (this.mapWidth) {
                this.setMapWidth(this.mapWidth);
            }
            if (this.mapHeight) {
                this.setMapHeight(this.mapHeight);
            }
            if (this.locale) {
                this.setLocale(this.locale);
            }
        },
        initOptions: function(options) {
            HybridTileManager.superclass.initOptions.call(this);
            LMI.Lang.mergeObjects(this.options, HybridTileManager.defaults);
            if ('config' in HybridTileManager) {
                LMI.Lang.mergeObjects(this.options, HybridTileManager.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        setMapWidth: function(w) {
            HybridTileManager.superclass.setMapWidth.apply(this, arguments);
            if (this.overlayUrls) {
                this.overlayUrls.setMapWidth(this.mapWidth);
            }
        },
        setMapHeight: function(h) {
            HybridTileManager.superclass.setMapHeight.apply(this, arguments);
            if (this.overlayUrls) {
                this.overlayUrls.setMapHeight(this.mapHeight);
            }
        },
        setLocale: function(locale) {
            HybridTileManager.superclass.setLocale.apply(this, arguments);
            if (this.overlayUrls) {
                this.overlayUrls.setLocale(locale);
            }
        },
        createTiles: function() {
            var i, j, tw = this.tileWidth,
            th = this.tileHeight;
            this.rows = Math.ceil(this.mapHeight / th) + 2;
            this.columns = Math.ceil(this.mapWidth / tw) + 2;
            this.tileLayer = LMI.Element.create('div', null, {
                className: 'tileLayer'
            });
            this.width = this.columns * tw;
            this.height = this.rows * th;
            for (i = 0; i < this.rows; ++i) {
                for (j = 0; j < this.columns; ++j) {
                    this.tiles.push(new LMI.Mapping.Tile(this.tileLayer, {
                        width: tw,
                        height: th
                    }));
                    this.overlayTiles.push(new LMI.Mapping.OverlayTile(this.tileLayer, {
                        width: tw,
                        height: th,
                        transparent: true
                    }));
                }
            }
        },
        wrapNorth: function() {
            var i, t, zoom = this.getZoomLevel();
            this.offsets.y -= this.tileHeight;
            this.setGridTop(this.getGridTop() - 1);
            for (i = 0; i < this.columns; ++i) {
                t = this.tiles.pop();
                this.tiles.unshift(t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + ((this.columns - 1) - i)), this.getGridTop(), this.tileLevels[zoom - 1]));
                t = this.overlayTiles.pop();
                this.overlayTiles.unshift(t);
                t.setSrc(this.overlayUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + ((this.columns - 1) - i)), this.getGridTop(), this.tileLevels[zoom - 1]), true);
            }
            for (i = 0; i < this.columns; ++i) {
                this.positionTile(i);
            }
        },
        wrapSouth: function() {
            var i, len, t, zoom = this.getZoomLevel();
            this.offsets.y += this.tileHeight;
            for (i = 0; i < this.columns; ++i) {
                t = this.tiles.shift();
                this.tiles.push(t);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + i), this.getGridTop() + this.rows, this.tileLevels[zoom - 1]));
                t = this.overlayTiles.shift();
                this.overlayTiles.push(t);
                t.setSrc(this.overlayUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + i), this.getGridTop() + this.rows, this.tileLevels[zoom - 1]), true);
            }
            for (i = this.columns * (this.rows - 1), len = this.tiles.length; i < len; ++i) {
                this.positionTile(i);
            }
            this.setGridTop(this.getGridTop() + 1);
        },
        wrapWest: function() {
            var i, t, o, x, zoom = this.getZoomLevel();
            this.offsets.x -= this.tileWidth;
            this.setGridLeft(this.getGridLeft() - 1);
            for (i = 1; i <= this.rows; ++i) {
                x = this.columns * i - 1;
                t = this.tiles.splice(x, 1)[0];
                o = this.overlayTiles.splice(x, 1)[0];
                x -= this.columns - 1;
                this.tiles.splice(x, 0, t);
                this.overlayTiles.splice(x, 0, o);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft()), this.getGridTop() + i - 1, this.tileLevels[zoom - 1]));
                o.setSrc(this.overlayUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft()), this.getGridTop() + i - 1, this.tileLevels[zoom - 1]), true);
                this.positionTile(x);
            }
        },
        wrapEast: function() {
            var i, t, o, x, zoom = this.getZoomLevel();
            this.offsets.x += this.tileWidth;
            for (i = 0; i < this.rows; ++i) {
                x = this.columns * i;
                t = this.tiles.splice(x, 1)[0];
                o = this.overlayTiles.splice(x, 1)[0];
                x += this.columns - 1;
                this.tiles.splice(x, 0, t);
                this.overlayTiles.splice(x, 0, o);
                t.setSrc(this.tileUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + this.columns), this.getGridTop() + i, this.tileLevels[zoom - 1]));
                o.setSrc(this.overlayUrls.getUrl(this.getGrid().restrictGridX(this.getGridLeft() + this.columns), this.getGridTop() + i, this.tileLevels[zoom - 1]), true);
                this.positionTile(x);
            }
            this.setGridLeft(this.getGridLeft() + 1);
        },
        positionTile: function(i) {
            var n, t = this.tiles[i],
            o = this.overlayTiles[i];
            t.setSize(this.tileWidth, this.tileHeight);
            o.setSize(this.tileWidth, this.tileHeight);
            n = ((i % this.columns) * t.getWidth() + this.offsets.x) + 'px';
            t.setLeft(n);
            o.setLeft(n);
            n = (Math.floor(i / this.columns) * t.getHeight() + this.offsets.y) + 'px';
            t.setTop(n);
            o.setTop(n);
        },
        loadTiles: function() {
            var i, j, gridTop, right, bottom, left, tile = 0,
            zoom = this.getZoomLevel(),
            grid = this.getGrid();
            this.setMapOffsets(0, 0);
            this.setOffsets(0, 0);
            this.calculateGridPosition();
            gridTop = this.getGridTop();
            bottom = gridTop + this.rows;
            left = this.getGridLeft();
            right = left + this.columns;
            for (i = gridTop; i < bottom; ++i) {
                for (j = left; j < right; ++j) {
                    this.tiles[tile].setSrc(this.tileUrls.getUrl(grid.restrictGridX(j), i, this.tileLevels[zoom - 1]));
                    this.overlayTiles[tile].setSrc(this.overlayUrls.getUrl(grid.restrictGridX(j), i, this.tileLevels[zoom - 1]), true);
                    this.positionTile(tile++);
                }
            }
        }
    });
    return HybridTileManager;
})();
LMI.Mapping.TopoTileManager = (function() {
    var $D = YAHOO.util.Dom,
    $E = LMI.Element;
    function TopoTileManager(el, options) {
        this.init(el, options);
    }
    YAHOO.lang.extend(TopoTileManager, LMI.Mapping.TileManager, {
        init: function(el, options) {
            TopoTileManager.superclass.init.call(this, el, options);
            this.unavailableMessage = new DSMapDecorator(null, $E.create('div', null, {
                className: 'topoTilesUnvailable',
                text: ''
            }), {},
            "", "");
        },
        initOptions: function(options) {
            TopoTileManager.superclass.initOptions.call(this);
            if ('config' in TopoTileManager) {
                LMI.Lang.mergeObjects(this.options, TopoTileManager.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        setZoomLevel: function(z) {
            TopoTileManager.superclass.setZoomLevel.call(this, z);
            this.updateMessage();
        },
        remove: function() {
            TopoTileManager.superclass.remove.call(this);
            this.unavailableMessage.map.removeDecorator(this.unavailableMessage);
        },
        add: function(map) {
            TopoTileManager.superclass.add.call(this, map);
            this.unavailableMessage.map = map;
            map.addDecorator(this.unavailableMessage);
            this.updateMessage();
        },
        updateMessage: function() {
            var z = this.tileLevels[this.getZoomLevel() - 1],
            el = this.unavailableMessage.getElement(),
            o = this.options.tileUrlOptions;
            if (z < o.minTopoLevel) {
                el.firstChild.nodeValue = 'Please zoom in to view the topo maps';
                $D.removeClass(el, "hidden");
            }
            else if (z > o.maxTopoLevel) {
                el.firstChild.nodeValue = 'Please zoom out to view the topo maps';
                $D.removeClass(el, "hidden");
            } else {
                $D.addClass(el, "hidden");
            }
        }
    });
    return TopoTileManager;
})();
LMI.Mapping.TopoTileUrl = (function() {
    function TopoTileUrl(options) {
        this.init(options);
    }
    YAHOO.lang.extend(TopoTileUrl, LMI.Mapping.TileUrl, {
        initOptions: function(options) {
            this.options = LMI.Lang.mergeObjects({},
            LMI.Mapping.TileUrl.defaults);
            if ('config' in LMI.Mapping.TileUrl) {
                LMI.Lang.mergeObjects(this.options, LMI.Mapping.TileUrl.config);
            }
            LMI.Lang.mergeObjects(this.options, options);
        },
        getFallBackPre: function() {
            return this.options.fallBackUrl + (this.locale.length ? this.locale + '/': '');
        },
        getUrl: function(x, y, z) {
            if (z >= this.options.minTopoLevel && z <= this.options.maxTopoLevel) {
                return this.getPre() + z + '/' + x + '/' + y + this.getPost();
            } else {
                return this.getFallBackPre() + z + '/' + x + '/' + y + this.getPost();
            }
        }
    });
    return TopoTileUrl;
})();
