/*--------------------------------------------
File Name:    zealdollar.js
Depend On:    ----
Created Date: 2007-11-28 00:00 By Rex.Sun
Last Updated: 2008-06-16 12:06 By Rex.Sun
--------------------------------------------*/
var $window = this;
var $undef = function(o, p) { return (typeof (o || $window)[p] == "undefined"); };
var $oUdf = function(o) { return typeof o == "undefined"; };
var $oUim = function(o) { throw new Error("Unimplemented!"); };
var $oNul = function(o) { return o === null; };
var $oArr = function(o) { return o instanceof Array; };
var $oFun = function(o) { return typeof o == "function"; };
var $oBol = function(o) { return typeof o == "boolean" || o instanceof Boolean; };
var $oNum = function(o) { typeof o == "number" || o instanceof Number; };
var $oStr = function(o) { return typeof o == "string" || o instanceof String; };
var $oVal = function(o) { return ($oStr(o) || $oNum(o) || $oBol(o) || $oNul(o)); };
var $oObj = function(o) { return !$oVal(o); };
var $V = function(o) { return $oVal(o) ? o : o.valueOf(); };
var $A = function(arr) {
    if (!arr) return [];
    if ($oArr(arr)) return arr;
    if ($oVal(arr)) {
        var rar = [];
        rar.push(arr);
        return rar;
    }
    var l = arr.length, rtval = new Array(l);
    while (l--) rtval[l] = arr[l];
    return rtval;
};
var $E = function(msg, ctx) {
    var ex = Error(msg);
    $setto(ex, { context: ctx });
    throw ex;
};
var $ = function(elm) {
    if (arguments.length > 1) {
        for (var i = 0, elms = [], l = arguments.length; i < l; i++) {
            elms.push($(arguments[i]));
        }
        return elms;
    }
    if ($oStr(elm)) {
        elm = document.getElementById(elm);
    }
    return elm;
};
var $seton = function(obj, ps) {
    if (!obj) obj = {};
    if (!ps) return;
    for (var p in ps) {
        if (!obj[p]) {
            obj[p] = ps[p];
        }
    }
    return obj;
};
var $setto = function(obj, ps) {
    if (!obj) obj = {};
    if (!ps) return;
    for (var p in ps) {
        obj[p] = ps[p];
    }
    return obj;
};
var $try = function() {
    var rtval = null;
    for (var i = 0, l = arguments.length; i < l; i++) {
        var f = arguments[i];
        try {
            rtval = $exes(f);
            break;
        } catch (ex) { }
    }
    return rtval;
};
var $gat = function(obj, nam, create) {
    if (!obj || !nam) return undefined;
    if (!$undef(obj, nam)) return obj[nam];
    return (!!create ? (obj[nam] = {}) : undefined);
};
var $get = function() {
    if (!arguments) return undefined;
    var obj = arguments[0];
    for (var i = 1, l = arguments.length; i < l; i++) {
        var nam = arguments[i];
        obj = $gat(obj, nam);
        if (!obj) break;
    }
    return obj;
};
var $clone = function(obj) {
    if (obj instanceof Object) {
        var v = {};
        for (var k in obj) {
            v[k] = obj[k];
        }
        return v;
    }
    return obj;
};
var $watch = function(obj, onm) {
    var s = ["{"];
    for (var k in obj) {
        s.push(k);
        if (!onm) {
            s.push(":");
            try {
                var val = null;
                if ($oVal(obj[k])) {
                    val = String($V(obj[k]) || "_N/A_").wrap('"');
                } else if ($oFun(obj[k])) {
                    val = "function(){}";
                } else {
                    val = $watch(obj[k], onm);
                }
            } catch (ex) {
                val = '"_E/R_"';
            }
            s.push(val);
        }
        s.push(", ");
    }
    s.pop();
    s.push("}");
    return s.join("");
};
var $exes = function(f, args) {
    if (!f || !$oFun(f)) { return undefined; }
    return f.apply(f, $A(args));
};
var $exea = function(f, args, cb, cbargs) {
    var af = function() {
        $exes(f, args);
        $exes(cb, cbargs);
    };
    setTimeout(af, 1);
    af = null;
};
var $dispose = function(obj) {
    if (obj) {
        $exes(obj.dispose);
        obj = null;
    }
    return null;
};
//==== String ====
$seton(String.prototype, {
    trim: function() {
        return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
    },
    collapse: function() {
        return this.replace(/\s+/g, ' ').trim();
    },
    wrap: function(delim) {
        var close, delims = { "(": ")", "{": "}", "[": "]", "<": ">", "</": ">" };
        if (delims[delim]) {
            close = delims[delim];
        }
        else {
            var m = (/^<(\w+)(\s+\w+\s*=\s*"[^"]*")*\s*>$/).exec(delim);
            if (m) {
                close = "</" + m[1] + ">";
            }
        }
        return delim + this + (close ? close : delim);
    },
    padLeft: function(n, c) {
        var s = this;
        var x = n - s.length;
        if (x > 0) {
            c = c || " ";
            s = (new Array(Math.ceil(x / c.length) + 1)).join(c) + s;
            return s.substring(s.length - n, n);
        }
        return s;
    },
    padRight: function(n, c) {
        s = this;
        var x = n - s.length;
        if (x > 0) {
            c = c || " ";
            s = s + (new Array(Math.ceil(x / c.length))).join(c);
            return s.substring(0, n);
        }
        return s;
    },
    format: function() {
        var fmt = this;
        for (var i = 0, l = arguments.length; i < l; i++) {
            fmt = fmt.replace(new RegExp('\\{' + i + '\\}', "mg"), arguments[i]);
        }
        return fmt;
    },
    equals: function(str2, ignoreCase) {
        var str1 = this;
        if (str1 == null && str2 == null) {
            return true;
        } else if (str1 == null || str2 == null) {
            return false;
        }
        if (ignoreCase) {
            return str1.toLowerCase() == str2.toLowerCase();
        }
        else {
            return str1 == str2;
        }
    },
    encodeHtml: function() {
        var rtval = this.replace(/\>/g, "&gt;").replace(/\</g, "&lt;").replace(/\&/g, "&amp;").replace(/\'/g, "&#039;").replace(/\"/g, "&quot;");
        return rtval;
    },
    hasXss: function() {
        var xssRe = /<|&lt|\\u0*3c|\\x0*3c|%3C|&#0*60|>|&gt|\\u0*3e|\\x0*3e|%3E|&#0*62/gi;
        return xssRe.test(this);
    },
    escape: function() {
        return !!(encodeURIComponent) ? encodeURIComponent(this) : escape(this);
    },
    unescape: function() {
        return !!(decodeURIComponent) ? decodeURIComponent(this) : unescape(this);
    } 
});
//==== Array ====
$seton(Array.prototype, {
    foreach: function(proc) {
        for (var i = 0, l = this.length; i < l; i++) {
            proc(this[i]);
        }
    },
    push: function() {
        for (var i = 0, l = arguments.length; i < l; i++) {
            this[this.length] = arguments[i];
        }
        return this.length;
    },
    pop: function() {
        if (this.length > 0) {
            return this[--this.length];
        } else {
            return null;
        }
    },
    indexOf: function(elm, bgnIdx) {
        bgnIdx = bgnIdx || 0;
        if (bgnIdx < 0) bgnIdx = 0;
        for (var i = 0, l = this.length; i < l; i++) {
            if (this[i] === elm) {
                return i;
            }
        }
        return -1;
    },
    contains: function(elm) {
        return (this.indexOf(elm) >= 0);
    },
    shift: function() {
        return this.splice(0, 1)[0];
    },
    last: function() {
        return (this.length > 0 ? this[this.length - 1] : void (0));
    },
    remove: function(obj) {
        for (var i = this.length - 1; i >= 0; i--) {
            if (this[i] === obj) {
                this.splice(i, 1);
            }
        }
        return this;
    },
    map: function(fun, context) {
        var ret = [];
        for (var i = 0, l = this.length; i < l; i++) {
            ret.push(fun.call(context, this[i], i, this));
        }
        return ret;
    },
    splice: function(idx, num) {
        var delta;
        var addCount = arguments.length - 2;
        if (idx > this.length) {
            idx = this.length;
        }
        if (idx + num > this.length) {
            num = this.length - idx;
        }
        var deleted = [];
        for (var i = 0; i < num; ++i) {
            deleted.push(this[idx + i]);
        }
        if (addCount > num) {
            delta = addCount - num;
            for (i = this.length + delta - 1; i >= idx + delta; i--) {
                this[i] = this[i - delta];
            }
        }
        else if (addCount < num) {
            delta = num - addCount;
            for (i = idx + addCount; i < this.length - delta; i++) {
                this[i] = this[i + delta];
            }
            for (; i < this.length - 1; ++i) {
                delete this[i];
            }
            this.length -= delta;
        }
        for (i = 0; i < addCount; ++i) {
            this[idx + i] = arguments[2 + i];
        }
        return deleted;
    } 
});
//==== Date ====
$seton(Date.prototype, {
    toXmlString: function(hasMs) {
        return "{0}-{1}-{2} {3}:{4}:{5},{6}".format(this.getFullYear(), String(this.getMonth() + 1).padLeft(2, '0'), String(this.getDate()).padLeft(2, '0'), String(this.getHours()).padLeft(2, '0'), String(this.getMinutes()).padLeft(2, '0'), String(this.getSeconds()).padLeft(2, '0'), (hasMs ? String(this.getMilliseconds()).padLeft(3, '0') : ""));
    },
    toUTCXmlString: function(hasMs) { //2000-01-01T00:00:00Z000
        return "{0}-{1}-{2}T{3}:{4}:{5}Z{6}".format(this.getUTCFullYear(), String(this.getUTCMonth() + 1).padLeft(2, '0'), String(this.getUTCDate()).padLeft(2, '0'), String(this.getUTCHours()).padLeft(2, '0'), String(this.getUTCMinutes()).padLeft(2, '0'), String(this.getUTCSeconds()).padLeft(2, '0'), (hasMs ? String(this.getUTCMilliseconds()).padLeft(3, '0') : ""));
    },
    toNumString: function(hasMs) { //20000101000000000
        return "{0}{1}{2}{3}{4}{5}{6}".format(this.getUTCFullYear(), String(this.getUTCMonth() + 1).padLeft(2, '0'), String(this.getUTCDate()).padLeft(2, '0'), String(this.getUTCHours()).padLeft(2, '0'), String(this.getUTCMinutes()).padLeft(2, '0'), String(this.getUTCSeconds()).padLeft(2, '0'), (hasMs ? String(this.getUTCMilliseconds()).padLeft(3, '0') : ""));
    } 
});
//==== $T ====
$setto(this, {
    $T: function(cb, inMs, atOnce, isOnce) {
        var m_this = this;
        var m_cb = cb;
        var m_ms = inMs;
        var m_timerId = 0;
        var m_running = false;
        var m_atOnce = parseBool(atOnce, false);
        var m_isOnce = parseBool(isOnce, false);
        var m_handler = function() {
            if (m_running) {
                m_invoke();
                if (m_isOnce) {
                    m_this.stop();
                    return;
                }
                m_timerId = setTimeout(m_handler, m_ms);
            }
        };
        var m_invoke = function() {
            $exes(m_cb);
        };
        this.setPeriod = function(inMs) {
            m_ms = inMs;
        };
        this.start = function() {
            m_running = true;
            if (m_atOnce) {
                m_invoke();
                if (m_isOnce) {
                    m_this.stop();
                    return;
                }
            }
            m_timerId = setTimeout(m_handler, m_ms);
        };
        this.stop = function() {
            m_running = false;
            if (m_timerId > 0) {
                clearTimeout(m_timerId);
                m_timerId = 0;
            }
        };
    } 
});
//==== Uri helper ====
$setto(this, { $U: {
    xdomainProxy: "",
    fixPath: function(uri, isPath) {
        var rtval = String(uri);
        if (rtval) {
            if (isPath && rtval.lastIndexOf("/") < rtval.length - 1) {
                rtval += "/";
            }
            if (!isPath) {
                while (rtval.lastIndexOf("/") == rtval.length - 1) { rtval = rtval.substring(0, rtval.length - 1) }
            }
        }
        return rtval;
    },
    fixDomain: function(uri) {
        var rtval = String(uri);
        var regAb = new RegExp("https*://", "i");
        var regMy = new RegExp("://" + this.hostname + "(:\d+)*/", "i");
        if (regAb.test(rtval) && !regMy.test(rtval) && this.xdomainProxy) {
            rtval = this.xdomainProxy + rtval.escape();
        }
        return rtval;
    },
    getParam: function(url, pname) {
        var rtval = "";
        url = url || location.href;
        url = String(url).replace(/(#[^#]*)+/g, '').slice(url.indexOf('?') + 1);
        var params = url.split('&');
        for (var i = 0, l = params.length; i < l; i++) {
            var ps = String(params[i]).split('=');
            var pn = $get(ps, "0");
            var pv = $get(ps, "1");
            if (pn.equals(pname, true)) {
                rtval = String(pv).unescape();
                break;
            }
        }
        return rtval;
    },
    setParam: function(url, pname, val) {
        var rtval = "";
        url = url || location.href;
        if (url) {
            url = String(url);
            var ov = this.getParam(url, pname);
            var pv = "{0}={1}".format(pname, String(val).escape());
            if (ov != "") {
                rtval = url.replace(new RegExp("[?]{0}={1}".format(pname, ov), "ig"), "?" + pv);
                rtval = rtval.replace(new RegExp("&{0}={1}".format(pname, ov), "ig"), "&" + pv);
            } else {
                url = url.replace(/#+/, "{0}#");
                if (url.indexOf("{0}") < 0) {
                    url += "{0}";
                }
                rtval = url.format(((url.indexOf("?") >= 0) ? "&" : "?") + pv);
            }
        }
        return rtval;
    },
    getCookie: function(name) {
        var rtval = "";
        var ck = document.cookie;
        var s = ck.indexOf(name + "=");
        var len = s + name.length + 1;
        if (s >= 0 && name.equals(ck.substring(0, name.length), true)) {
            var e = ck.indexOf(";", len);
            if (e == -1) e = ck.length;
            rtval = ck.substring(len, e);
        }
        return rtval.unescape();
    },
    setCookie: function(name, value, expmins, path, domain, secure) {
        var expString = null;
        if (expmins) {
            var d = new Date();
            d.setMinutes(d.getMinutes() + expmins);
            expString = d.toGMTString();
        }
        var rtval = [];
        rtval.push("{0}={1}".format(name, value.escape()));
        if (expString) { rtval.push(";expires=" + expString) };
        if (path) { rtval.push(";path=" + path) };
        if (domain) { rtval.push(";domain=" + domain) };
        if (secure) { rtval.push(";secure") };
        document.cookie = rtval.join("");
    } }
});
//==== $ajax : ajax request pool ====
$setto(this, {
    ajaxMaster: function() {
        var m_id = -1;
        var m_this = this;
        var m_timer = null;
        var m_pool = new Array();
        var m_checkTimeouts = function() {
            if (m_pool.length > 0) {
                var now = new Date();
                for (var i = 0; i < m_pool.length; i++) {
                    var item = m_pool[i];
                    if (item && item.Timeout) {
                        var dt = new Date(item.BeginTime);
                        dt.setUTCMilliseconds(item.Timeout);
                        if (dt < now) {
                            item.Overtimed = true;
                            m_this.cancelItem(item.Id);
                        }
                    }
                }
            }
        };
        var m_removeItem = function(aId) {
            if (aId >= m_pool.length) { return; }
            var aItem = m_pool[aId];
            m_pool[aId] = null;
            $dispose(aItem);
        };
        var m_requestComplete = function(aItem) {
            if (!aItem) { return; }
            var httpObj = aItem.HttpObj;
            if (httpObj.readyState == 4) {
                var s = httpObj.status;
                if ((!s) || ((200 <= s) && (300 > s)) || (aItem.Allow304 && (s == 304))) {
                    $exes(aItem.CBFunc, [httpObj.responseText, aItem.CBData]);
                }
                m_removeItem(aItem.Id);
            }
        };
        this.getSycText = function(url, allow304) {
            var rtval = "";
            var cb = function(txt) { rtval = txt; };
            var rt = m_this.request(url, true, cb, false, allow304);
            rtval = rtval || rt;
            return rtval;
        };
        this.getResp = function(url, cb, isasy, allow304, cbData, timeout) {
            return m_this.request(url, true, cb, isasy, allow304, cbData, null, timeout);
        };
        this.postResp = function(url, cb, isasy, allow304, cbData, postData, timeout) {
            return m_this.request(url, false, cb, isasy, allow304, cbData, postData, timeout);
        };
        this.request = function(url, isGet, cb, isasy, allow304, cbData, postData, timeout) {
            var method = isGet ? "GET" : "POST";
            var httpObj = $try(
            function() { return new ActiveXObject('MSXML2.XMLHTTP.6.0'); },
            function() { return new ActiveXObject('MSXML2.XMLHTTP.5.0'); },
            function() { return new ActiveXObject('MSXML2.XMLHTTP.4.0'); },
            function() { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); },
            function() { return new ActiveXObject('MSXML2.XMLHTTP'); },
            function() { return new ActiveXObject('Microsoft.XMLHTTP'); },
            function() { return new XMLHttpRequest(); }
        );
            if (httpObj) {
                var aItem = new ajaxItem(++m_id, httpObj, !!allow304, cb, cbData, timeout);
                m_pool[m_id] = aItem;
                if (timeout && !m_timer) {
                    m_timer = new $T(m_checkTimeouts, 1000, false, false);
                    m_timer.start();
                }
                httpObj.onreadystatechange = function() {
                    m_requestComplete(aItem);
                };
                url = $U.fixDomain(url);
                httpObj.open(method, url, !!isasy);
                if (isGet) {
                    httpObj.send(null);
                } else {
                    httpObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    httpObj.send(postData);
                }
                try {
                    if (!isasy) {
                        return httpObj.responseText;
                    } else {
                        return httpObj;
                    }
                } catch (ex) {
                    return null;
                }
            }
            else {
                $E("XMLHTTP is not available!");
            }
        };
        this.getItem = function(aId) {
            var aItem = null;
            if (aId < m_pool.length) {
                aItem = m_pool[aId];
            }
            return aItem;
        };
        this.cancelItem = function(aId) {
            var aItem = m_this.getItem(aId);
            if (aItem && (aItem.httpObj.readyState != 4)) {
                aItem.httpObj.abort();
            }
            m_removeItem(aId);
        };
    },
    ajaxItem: function(id, httpObj, allow304, cb, cbData, timeout) {
        this.Id = id;
        this.CBFunc = cb;
        this.CBData = cbData;
        this.HttpObj = httpObj;
        this.Timeout = timeout;
        this.Overtimed = false;
        this.Allow304 = allow304;
        this.BeginTime = new Date();
        this.dispose = function() {
            this.Id = null;
            this.CBFunc = null;
            this.CBData = null;
            this.Timeout = null;
            this.HttpObj = null;
            this.BeginTime = null;
        };
    } 
});
$setto(this, { $ajax: new ajaxMaster() });
//==== Namespace ====
$setto(this, { $N: {
    defaultNsUri: "",
    libPackFile: "__ns__.js",
    hostname: location.hostname.toLowerCase(),
    addRootPath: function(ns, path, update) {
        if (!ns || !path) { return; }
        var nsRoot = ns.split(".")[0];
        if (!this.libRootPath[nsRoot] || update) {
            this.libRootPath[nsRoot] = $U.fixPath($U.fixPath(this.defaultNsUri, true) + path, true);
        }
    },
    getJsPath: function(ns) {
        var rtval = ns;
        if (!/\/+/.test(ns)) {
            var nms = ns.split(".");
            var len = nms.length;
            if (len > 0) {
                if (this.libRootPath[nms[0]]) {
                    var lr = this.libRootPath[nms[0]];
                    nms[0] = $U.fixPath(lr, false);
                }
                else {
                    nms[0] = this.libRootPath["sys"] + nms[0];
                }
                if (nms[len - 1] != "*") {
                    nms[len - 1] += ".js";
                }
                else {
                    nms[len - 1] = this.libPackFile;
                }
                rtval = nms.join("/");
            }
        }
        return rtval;
    } }
});
$setto(this, {
    $import: function(jsuri, refresh) {
        if (!jsuri) { return; }
        var parsepath = (refresh && jsuri.indexOf("?") < 0);
        if (refresh) { jsuri = $U.setParam(jsuri, "refresh", new Date().toNumString(true)); }
        var jsrpath = (parsepath ? jsuri.split("?")[0] : jsuri);
        var ok = $N.loadedPackagesUri[jsrpath];
        if (!ok) {
            var jsc = $ajax.getSycText(jsuri, true);
            if (jsc) {
                ok = $N.loadedPackagesUri[jsrpath] = true;
                return jsc;
            }
        }
        return ok;
    },
    $using: function(ns, nspath) {
        if (!ns) { return; }
        $N.addRootPath(ns, nspath, !!nspath);
        var jsuri = $N.getJsPath(ns);
        var rtval = $import(jsuri, true);
        return rtval;
    },
    $initCore: function(xProxy, defaultNs) {
        $setto($U, { xdomainProxy: xProxy });
        $setto($N, {
            defaultNsUri: $U.fixPath(defaultNs, true),
            libRootPath: { sys: $U.fixPath(defaultNs + "js_p_sys", true) },
            loadedPackagesUri: { "zealdollar.js": true }
        });
    } 
});
$initCore("", "");