Greasy Fork is available in English.

集装箱

一个插件,提供一揽子服务。插件主要功能有:[1]网盘助手:大概是最优雅好用的网盘助手了。 [2]优 惠 购 :以最优惠的价格,把宝贝抱回家。 [3]下载卫士:拒绝高(捆)速(绑)下载。

安装此脚本?
作者推荐脚本

您或许会喜欢优惠购

安装此脚本
// ==UserScript==
// @name         集装箱
// @namespace    http://one.newday.me/
// @version      0.1.3
// @icon         http://one.newday.me/one/favicon.ico
// @author       哩呵
// @description  一个插件,提供一揽子服务。插件主要功能有:[1]网盘助手:大概是最优雅好用的网盘助手了。 [2]优 惠 购 :以最优惠的价格,把宝贝抱回家。 [3]下载卫士:拒绝高(捆)速(绑)下载。
// @match        *://*.taobao.com/*
// @match        *://*.tmall.com/*
// @match        *://*.tmall.hk/*
// @match        *://*.liangxinyao.com/*
// @match        *://*.yao.95095.com/*
// @match        *://item.jd.com/*
// @match        *://item.jd.hk/*
// @match        *://goods.kaola.com/product/*
// @match        *://you.163.com/item/*
// @match        *://item.yhd.com/*
// @match        *://product.suning.com/*
// @match        *://www.amazon.cn/dp/*
// @match        *://www.amazon.cn/gp/*
// @match        *://product.dangdang.com/*
// @match        *://item.gome.com.cn/*
// @match        *://detail.vip.com/*
// @match        *://pan.baidu.com/*
// @match        *://yun.baidu.com/*
// @match        *://share.weiyun.com/*
// @match        *://*.lanzous.com/*
// @match        *://vdisk.weibo.com/*
// @match        *://*.ctfile.com/*
// @match        *://*.pipipan.com/*
// @match        *://*.dfpan.com/*
// @match        *://*.onlinedown.net/*
// @match        *://*.cr173.com/*
// @match        *://*.xiazaiba.com/*
// @match        *://*.mydown.com/*
// @match        *://*.pc6.com/*
// @match        *://*.zol.com.cn/*
// @match        *://*.pconline.com.cn/*
// @match        *://*.jb51.net/*
// @match        *://*.cncrk.com/*
// @match        *://pc.qq.com/*
// @match        *://*.crsky.com/*
// @match        *://*.duote.com/*
// @match        *://*.downza.cn/*
// @match        *://*.yesky.com/*
// @match        *://*.ddooo.com/*
// @match        *://*.pchome.net/*
// @match        *://*.xpgod.com/*
// @match        *://*.52z.com/*
// @match        *://*.opdown.com/*
// @match        *://*.newday.me/*
// @connect      taobao.com
// @connect      tmall.com
// @connect      ctfile.com
// @connect      pipipan.com
// @connect      newday.me
// @require      https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// @require      https://cdn.staticfile.org/snap.svg/0.5.1/snap.svg-min.js
// @require      https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js
// @require      https://cdn.staticfile.org/qrcode-generator/1.4.3/qrcode.min.js
// @require      https://cdn.staticfile.org/vue/2.6.6/vue.min.js
// @run-at       document-start
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_listValues
// @grant        GM_xmlhttpRequest
// @grant        GM_openInTab
// @noframes
// ==/UserScript==

var appWpzs = function () {
    'use strict';

    var injectInfo = {
        enable: true,
        name: "wpzs",
        version: "0.2.6",
        router_addon: {
            option: "/page/wpzs/option.html"
        },
        router_script: {
            option: "http://one.newday.me/page/wpzs/option.html"
        }
    };

    var container = (function () {
        var obj = {
            module_defines: {},
            module_objects: {}
        };

        obj.define = function (name, requires, callback) {
            name = obj.processName(name);
            obj.module_defines[name] = {
                requires: requires,
                callback: callback
            };
        };

        obj.require = function (name, cache) {
            if (typeof cache == "undefined") {
                cache = true;
            }

            name = obj.processName(name);
            if (cache && obj.module_objects.hasOwnProperty(name)) {
                return obj.module_objects[name];
            }
            else if (obj.module_defines.hasOwnProperty(name)) {
                var requires = obj.module_defines[name].requires;
                var callback = obj.module_defines[name].callback;

                var module = obj.use(requires, callback);
                cache && obj.register(name, module);
                return module;
            }
        };

        obj.use = function (requires, callback) {
            var module = {
                exports: {}
            };
            var params = obj.buildParams(requires, module);
            var result = callback.apply(this, params);
            if (typeof result != "undefined") {
                return result;
            }
            else {
                return module.exports;
            }
        };

        obj.register = function (name, module) {
            name = obj.processName(name);
            obj.module_objects[name] = module;
        };

        obj.buildParams = function (requires, module) {
            var params = [];
            requires.forEach(function (name) {
                params.push(obj.require(name));
            });
            params.push(obj.require);
            params.push(module.exports);
            params.push(module);
            return params;
        };

        obj.processName = function (name) {
            return name.toLowerCase();
        };

        return {
            define: obj.define,
            use: obj.use,
            register: obj.register,
            modules: obj.module_objects
        };
    })();

    container.define("runtime", [], function () {
        var obj = {
            url: location.href,
            referer: document.referrer,
        };

        obj.getUrl = function () {
            return obj.url;
        };

        obj.setUrl = function (url) {
            obj.url = url;
        };

        obj.getReferer = function () {
            return obj.referer;
        };

        obj.setReferer = function (referer) {
            obj.referer = referer;
        };

        obj.getUrlParam = function (name) {
            var param = obj.parseUrlParam(obj.getUrl());
            if (name) {
                return param.hasOwnProperty(name) ? param[name] : null;
            }
            else {
                return param;
            }
        };

        obj.parseUrlParam = function (url) {
            if (url.indexOf("?")) {
                url = url.split("?")[1];
            }
            var reg = /([^=&\s]+)[=\s]*([^=&\s]*)/g;
            var obj = {};
            while (reg.exec(url)) {
                obj[RegExp.$1] = RegExp.$2;
            }
            return obj;
        };

        return obj;
    });

    container.define("object", [], function () {
        var obj = {};

        obj.keys = function (data) {
            var list = [];
            for (var key in data) {
                list.push(key);
            }
            return list;
        };

        obj.values = function (data) {
            var list = [];
            for (var key in data) {
                list.push(data[key]);
            }
            return list;
        };

        return obj;
    });

    container.define("storage", [], function () {
        var obj = {};

        obj.getValue = function (name, defaultValue) {
            name = obj.processName(name);
            return GM_getValue(name, defaultValue);
        };

        obj.setValue = function (name, value) {
            name = obj.processName(name);
            GM_setValue(name, value);
        };

        obj.getValueList = function () {
            var nameList = GM_listValues();
            var valueList = {};
            nameList.forEach(function (name) {
                if (injectInfo.enable) {
                    if (name.indexOf(injectInfo.name + "_") >= 0) {
                        name = name.replace(injectInfo.name + "_", "");
                        valueList[name] = obj.getValue(name);
                    }
                }
                else {
                    valueList[name] = obj.getValue(name);
                }
            });
            return valueList;
        };

        obj.processName = function (name) {
            if (injectInfo.enable) {
                return injectInfo.name + "_" + name;
            }
            else {
                return name;
            }
        };

        return obj;
    });

    container.define("config", ["storage"], function (storage) {
        var obj = {};

        obj.getConfig = function (name) {
            var configJson = storage.getValue("configJson");
            var configObject = obj.parseJson(configJson);
            if (name) {
                return configObject.hasOwnProperty(name) ? configObject[name] : null;
            }
            else {
                return configObject;
            }
        };

        obj.setConfig = function (name, value) {
            var configObject = obj.getConfig();
            configObject[name] = value;
            storage.setValue("configJson", JSON.stringify(configObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("option", ["storage", "constant", "object"], function (storage, constant, object) {
        var obj = {
            constant: constant.option
        };

        obj.isOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            return option.indexOf(name) >= 0 ? true : false;
        };

        obj.setOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            if (option.indexOf(name) < 0) {
                option.push(name);
                obj.setOption(option);
            }
        };

        obj.setOptionUnActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            var index = option.indexOf(name);
            if (index >= 0) {
                delete option[index];
                obj.setOption(option);
            }
        };

        obj.getOption = function () {
            var option = [];
            var optionJson = storage.getValue("optionJson");
            var optionObject = obj.parseJson(optionJson);
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (optionObject.hasOwnProperty(name)) {
                    if (optionObject[name] != "no") {
                        option.push(name);
                    }
                }
                else if (item.value != "no") {
                    option.push(name);
                }
            });
            return option;
        };

        obj.setOption = function (option) {
            var optionObject = {};
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (option.indexOf(name) >= 0) {
                    optionObject[name] = "yes";
                } else {
                    optionObject[name] = "no";
                }
            });
            storage.setValue("optionJson", JSON.stringify(optionObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("mode", [], function () {
        var obj = {
            constant: {
                addon: "addon",
                script: "script"
            }
        };

        obj.getMode = function () {
            if (typeof GM_info == "undefined") {
                return obj.constant.addon;
            }
            else if (GM_info.scriptHandler) {
                return obj.constant.script;
            }
            else {
                return obj.constant.addon;
            }
        };

        return obj;
    });

    container.define("user", ["storage"], function (storage) {
        var obj = {};

        obj.getUid = function () {
            var uid = storage.getValue("uid");
            if (!uid) {
                uid = obj.randString(32);
                storage.setValue("uid", uid);
            }
            return uid;
        };

        obj.randString = function (length) {
            var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
            var text = "";
            for (var i = 0; i < length; i++) {
                text += possible.charAt(Math.floor(Math.random() * possible.length));
            }
            return text;
        };

        return obj;
    });

    container.define("browser", [], function () {
        var obj = {
            constant: {
                firefox: "firefox",
                edge: "edge",
                baidu: "baidu",
                liebao: "liebao",
                uc: "uc",
                qq: "qq",
                sogou: "sogou",
                opera: "opera",
                maxthon: "maxthon",
                ie2345: "2345",
                se360: "360",
                chrome: "chrome",
                safari: "safari",
                other: "other"
            }
        };

        obj.getBrowser = function () {
            return obj.matchBrowserType(navigator.userAgent);
        };

        obj.matchBrowserType = function (userAgent) {
            var browser = obj.constant.other;
            userAgent = userAgent.toLowerCase();
            if (userAgent.match(/firefox/) != null) {
                browser = obj.constant.firefox;
            } else if (userAgent.match(/edge/) != null) {
                browser = obj.constant.edge;
            } else if (userAgent.match(/bidubrowser/) != null) {
                browser = obj.constant.baidu;
            } else if (userAgent.match(/lbbrowser/) != null) {
                browser = obj.constant.liebao;
            } else if (userAgent.match(/ubrowser/) != null) {
                browser = obj.constant.uc;
            } else if (userAgent.match(/qqbrowse/) != null) {
                browser = obj.constant.qq;
            } else if (userAgent.match(/metasr/) != null) {
                browser = obj.constant.sogou;
            } else if (userAgent.match(/opr/) != null) {
                browser = obj.constant.opera;
            } else if (userAgent.match(/maxthon/) != null) {
                browser = obj.constant.maxthon;
            } else if (userAgent.match(/2345explorer/) != null) {
                browser = obj.constant.ie2345;
            } else if (userAgent.match(/chrome/) != null) {
                if (obj.existMime("type", "application/vnd.chromium.remoting-viewer")) {
                    browser = obj.constant.se360;
                } else {
                    browser = obj.constant.chrome;
                }
            } else if (userAgent.match(/safari/) != null) {
                browser = obj.constant.safari;
            }
            return browser;
        };

        obj.existMime = function (option, value) {
            if (typeof navigator != "undefined") {
                var mimeTypes = navigator.mimeTypes;
                for (var mt in mimeTypes) {
                    if (mimeTypes[mt][option] == value) {
                        return true;
                    }
                }
            }
            return false;
        };

        return obj;
    });

    container.define("env", ["mode", "user", "browser"], function (mode, user, browser) {
        var obj = {};

        obj.getMode = function () {
            return mode.getMode();
        };

        obj.getAid = function () {
            if (GM_info.addon && GM_info.addon.id) {
                return GM_info.addon.id;
            }
            else if (GM_info.scriptHandler) {
                return GM_info.scriptHandler.toLowerCase();
            }
            else {
                return "unknown";
            }
        };

        obj.getUid = function () {
            return user.getUid();
        };

        obj.getVersion = function () {
            if (injectInfo.enable) {
                return injectInfo.version;
            }
            else {
                return GM_info.script.version;
            }
        };

        obj.getBrowser = function () {
            return browser.getBrowser();
        };

        obj.getInfo = function () {
            return {
                mode: obj.getMode(),
                aid: obj.getAid(),
                uid: obj.getUid(),
                version: obj.getVersion(),
                browser: obj.getBrowser()
            };
        };

        return obj;
    });

    container.define("http", [], function () {
        var obj = {};

        obj.ajax = function (option) {
            var details = {
                method: option.type,
                url: option.url,
                responseType: option.dataType,
                onload: function (result) {
                    option.success && option.success(result.response);
                },
                onerror: function (result) {
                    option.error && option.error(result.error);
                }
            };

            // 提交数据
            if (option.data) {
                if (option.data instanceof FormData) {
                    details.data = option.data;
                }
                else {
                    var formData = new FormData();
                    for (var i in option.data) {
                        formData.append(i, option.data[i]);
                    }
                    details.data = formData;
                }
            }

            // 自定义头
            if (option.headers) {
                details.headers = option.headers;
            }

            // 超时
            if (option.timeout) {
                details.timeout = option.timeout;
            }

            GM_xmlhttpRequest(details);
        };

        return obj;
    });

    container.define("router", [], function () {
        var obj = {};

        obj.goUrl = function (url) {
            obj.eval('location.href = "' + url + '";');
        };

        obj.openUrl = function (url) {
            obj.eval('window.open("' + url + '");');
        };

        obj.openTab = function (url, active) {
            GM_openInTab(url, !active);
        };

        obj.eval = function (script) {
            var node = document.createElementNS(document.lookupNamespaceURI(null) || "http://www.w3.org/1999/xhtml", "script");
            node.textContent = script;
            (document.head || document.body || document.documentElement || document).appendChild(node);
            node.parentNode.removeChild(node)
        };

        return obj;
    });

    container.define("logger", ["env", "constant"], function (env, constant) {
        var obj = {
            level: 3,
            constant: {
                debug: 0,
                info: 1,
                warn: 2,
                error: 3
            }
        };

        obj.debug = function (message) {
            obj.log(message, obj.constant.debug);
        };

        obj.info = function (message) {
            obj.log(message, obj.constant.info);
        };

        obj.warn = function (message) {
            obj.log(message, obj.constant.warn);
        };

        obj.error = function (message) {
            obj.log(message, obj.constant.error);
        };

        obj.log = function (message, level) {
            if (level < obj.level) {
                return false;
            }

            console.group("[" + constant.name + "]" + env.getMode());
            switch (level) {
                case obj.constant.debug:
                    console.log(message);
                    break;
                case obj.constant.info:
                    console.info(message);
                    break;
                case obj.constant.warn:
                    console.warn(message);
                    break;
                case obj.constant.error:
                    console.error(message);
                    break;
                default:
                    console.log(message);
                    break;
            }
            console.groupEnd();
        };

        obj.setLevel = function (level) {
            obj.level = level;
        };

        return obj;
    });

    container.define("meta", ["constant", "$"], function (constant, $) {
        var obj = {};

        obj.existMeta = function (name) {
            name = obj.processName(name);
            if ($("meta[name='" + name + "']").length) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.appendMeta = function (name, content) {
            name = obj.processName(name);
            content || (content = "on");
            $('<meta name="' + name + '" content="on">').appendTo($("head"));
        };

        obj.processName = function (name) {
            return constant.name + "::" + name;
        };

        return obj;
    });

    container.define("unsafe_window", [], function () {
        if (typeof unsafeWindow == "undefined") {
            return window;
        }
        else {
            return unsafeWindow;
        }
    });

    /** custom start **/
    container.define("constant", ["mode", "browser"], function (mode, browser) {
        return {
            name: "wpzs",
            mode: mode.constant,
            browser: browser.constant,
            option: {
                send_usage: {
                    name: "send_usage",
                    value: "yes"
                },
                baidu_page_home: {
                    name: "baidu_page_home",
                    value: "yes"
                },
                baidu_page_share: {
                    name: "baidu_page_share",
                    value: "yes"
                },
                baidu_page_verify: {
                    name: "baidu_page_verify",
                    value: "yes"
                },
                baidu_share_status: {
                    name: "baidu_share_status",
                    value: "yes"
                },
                baidu_custom_password: {
                    name: "baidu_custom_password",
                    value: "yes"
                },
                baidu_show_origin: {
                    name: "baidu_show_origin",
                    value: "yes"
                },
                baidu_multi_link: {
                    name: "baidu_multi_link",
                    value: "no"
                },
                baidu_disable_client: {
                    name: "baidu_disable_client",
                    value: "yes"
                },
                baidu_auto_jump: {
                    name: "baidu_auto_jump",
                    value: "no"
                },
                weiyun_page_verify: {
                    name: "weiyun_page_verify",
                    value: "yes"
                },
                weiyun_share_status: {
                    name: "weiyun_share_status",
                    value: "yes"
                },
                weiyun_auto_jump: {
                    name: "weiyun_auto_jump",
                    value: "no"
                },
                lanzous_page_verify: {
                    name: "lanzous_page_verify",
                    value: "yes"
                },
                lanzous_share_status: {
                    name: "lanzous_share_status",
                    value: "yes"
                },
                lanzous_auto_jump: {
                    name: "lanzous_auto_jump",
                    value: "no"
                },
                weibo_page_download: {
                    name: "weibo_page_download",
                    value: "yes"
                },
                ctfile_page_list: {
                    name: "ctfile_page_list",
                    value: "yes"
                },
                ctfile_page_download: {
                    name: "ctfile_page_download",
                    value: "yes"
                },
                ctfile_multi_link: {
                    name: "ctfile_multi_link",
                    value: "no"
                },
                yunfile_page_download: {
                    name: "yunfile_page_download",
                    value: "yes"
                }
            },
            source: {
                baidu: "baidu",
                weiyun: "weiyun",
                lanzous: "lanzous"
            },
            router: {
                home: "http://pan.newday.me",
                option: "http://pan.newday.me/script/option.html"
            }
        };
    });

    container.define("share_log", ["object", "storage", "constant"], function (object, storage, constant) {
        var obj = {};

        obj.addShareLog = function (shareId, sharePwd, shareLink, shareSource) {
            var shareLogList = obj.getShareLogList();
            shareLogList[shareId] = {
                share_id: shareId,
                share_pwd: sharePwd,
                share_link: shareLink,
                share_source: shareSource,
                share_time: (new Date()).getTime()
            };
            storage.setValue("share_log_json", JSON.stringify(shareLogList));
        };

        obj.getShareLogList = function () {
            var shareLogJson = storage.getValue("share_log_json");
            return obj.parseJson(shareLogJson);
        };

        obj.buildShareLink = function (shareId, shareSource, shareLink) {
            if (shareSource == constant.source.baidu) {
                shareLink = "https://pan.baidu.com/s/1" + shareId;
            }
            else if (shareSource == constant.source.baidu) {
                shareLink = "https://share.weiyun.com/" + shareId;
            } else if (shareSource == constant.source.baidu) {
                shareLink = "https://www.lanzous.com/" + shareId;
            }
            return shareLink;
        };

        obj.buildShareTime = function (shareTime) {
            var date = new Date(shareTime);
            var year = 1900 + date.getYear();
            var month = "0" + (date.getMonth() + 1);
            var day = "0" + date.getDate();
            var hour = "0" + date.getHours();
            var minute = "0" + date.getMinutes();
            var second = "0" + date.getSeconds();
            var vars = {
                "Y": year,
                "m": month.substring(month.length - 2, month.length),
                "d": day.substring(day.length - 2, day.length),
                "H": hour.substring(hour.length - 2, hour.length),
                "i": minute.substring(minute.length - 2, minute.length),
                "s": second.substring(second.length - 2, second.length)
            };
            return obj.replaceVars(vars, "Y-m-d H:i:s");
        };

        obj.replaceVars = function (vars, value) {
            object.keys(vars).forEach(function (key) {
                value = value.replace(key, vars[key]);
            });
            return value;
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("core", ["router", "constant"], function (router, constant) {
        var obj = {};

        obj.openPage = function (url, mode) {
            switch (mode) {
                case 9:
                    // self
                    router.goUrl(url);
                    break;
                case 6:
                    // new
                    router.openUrl(url);
                    break;
                case 3:
                    // new & not active
                    router.openTab(url, false);
                    break;
                case 1:
                    // new & active
                    router.openTab(url, true);
                    break;
            }
        };

        obj.openOptionPage = function () {
            if (injectInfo.enable) {
                if (env.getMode() == constant.mode.addon) {
                    router.openTab(injectInfo.router_addon.option, true);
                }
                else {
                    router.openTab(injectInfo.router_script.option, true);
                }
            }
            else if (GM_info.addon && GM_info.addon.options_page) {
                router.openTab(GM_info.addon.options_page, true);
            }
            else {
                router.openTab(constant.router.option, true);
            }
        };

        obj.ready = function (callback) {
            callback && callback();
        };

        return obj;
    });

    container.define("api", ["http", "env", "share_log", "snap"], function (http, env, shareLog, snap) {
        var obj = {
            base: "https://api.newday.me"
        };

        obj.queryShareOrigin = function (shareId, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/share/disk/origin",
                dataType: "json",
                data: {
                    share_id: shareId,
                    mode: env.getMode(),
                    aid: env.getAid(),
                    uid: env.getUid(),
                    version: env.getVersion(),
                    browser: env.getBrowser()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function () {
                    callback && callback("");
                }
            });
        };

        obj.querySharePwd = function (shareId, shareLink, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/share/disk/query",
                dataType: "json",
                data: {
                    share_id: shareId,
                    share_point: obj.getStrPoint(shareId),
                    share_link: shareLink,
                    mode: env.getMode(),
                    aid: env.getAid(),
                    uid: env.getUid(),
                    version: env.getVersion(),
                    browser: env.getBrowser()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function () {
                    callback && callback("");
                }
            });
        };

        obj.storeSharePwd = function (shareId, sharePwd, shareLink, shareSource, callback) {
            // 记录日志
            shareLog.addShareLog(shareId, sharePwd, shareLink, shareSource);

            http.ajax({
                type: "post",
                url: obj.base + "/share/disk/store",
                dataType: "json",
                data: {
                    share_id: shareId,
                    share_pwd: sharePwd,
                    share_point: obj.getStrPoint(shareId),
                    share_link: shareLink,
                    mode: env.getMode(),
                    aid: env.getAid(),
                    uid: env.getUid(),
                    version: env.getVersion(),
                    browser: env.getBrowser()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function () {
                    callback && callback("");
                }
            });
        };

        obj.logOption = function (option, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/share/disk/option",
                dataType: "json",
                data: {
                    option_json: JSON.stringify(option),
                    mode: env.getMode(),
                    aid: env.getAid(),
                    uid: env.getUid(),
                    version: env.getVersion(),
                    browser: env.getBrowser()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function () {
                    callback && callback("");
                }
            });
        };

        obj.sendUsage = function (url, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/share/disk/usage",
                dataType: "json",
                data: {
                    url: url,
                    mode: env.getMode(),
                    aid: env.getAid(),
                    uid: env.getUid(),
                    version: env.getVersion(),
                    browser: env.getBrowser()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function () {
                    callback && callback("");
                }
            });
        };

        obj.getStrPoint = function (str) {
            if (str.length < 2) {
                return "0:0";
            }

            var path = "";
            var current, last = str[0].charCodeAt();
            var sum = last;
            for (var i = 1; i < str.length; i++) {
                current = str[i].charCodeAt();
                if (i == 1) {
                    path = path + "M";
                } else {
                    path = path + " L";
                }
                path = path + current + " " + last;
                last = current;
                sum = sum + current;
            }
            path = path + " Z";
            var index = sum % str.length;
            var data = snap.path.getPointAtLength(path, str[index].charCodeAt());
            return data.m.x + ":" + data.n.y;
        };

        return obj;
    });

    /** app start **/
    container.define("app_baidu", ["runtime", "config", "option", "logger", "unsafe_window", "constant", "core", "api", "$"], function (runtime, config, option, logger, unsafeWindow, constant, core, api, $) {
        var obj = {
            app_id: 250528,
            yun_data: null,
            verify_page: {
                share_pwd: null,
                setPwd: null,
                backupPwd: null,
                restorePwd: null,
                submit_pwd: null
            }
        };

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf(".baidu.com/s/") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.baidu_page_share) && obj.initSharePage();
                });
                return true;
            }
            else if (url.indexOf(".baidu.com/disk/home") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.baidu_page_home) && obj.initHomePage();
                });
                return true;
            } else if (url.indexOf(".baidu.com/disk/timeline") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.baidu_page_home) && obj.initTimeLinePage();
                });
                return true;
            } else if (url.indexOf(".baidu.com/share/init") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.baidu_page_verify) && obj.initVerifyPage();
                });
                return true;
            }
            else {
                return false;
            }
        };

        obj.initSharePage = function () {
            obj.registerCustomAppId();

            obj.removeDownloadLimit();

            obj.removeVideoLimit();

            obj.prettySingleSharePage();

            obj.initButtonShare();

            obj.initButtonEvent();

            if (option.isOptionActive(option.constant.baidu_show_origin)) {
                obj.showShareOrigin();
            }
        };

        obj.initHomePage = function () {
            obj.registerCustomAppId();

            obj.registerCustomSharePwd();

            obj.removeDownloadLimit();

            obj.initButtonHome();

            obj.initButtonEvent();
        };

        obj.initTimeLinePage = function () {
            obj.registerCustomAppId();

            obj.registerCustomSharePwd();

            obj.removeDownloadLimit();

            obj.initButtonTimeLine();

            obj.initButtonEvent();
        };

        obj.initVerifyPage = function () {
            obj.registerStoreSharePwd();

            if (obj.initVerifyPageElement()) {
                obj.autoPaddingSharePwd();

                obj.registerPwdShareSwitch();
            }
        };

        obj.initVerifyPageElement = function () {
            var shareId = obj.getShareId();
            var $pwd = $(".input-area input");
            if (shareId && $pwd.length) {
                // 设置提取码
                obj.verify_page.setPwd = function (pwd) {
                    $pwd.val(pwd);
                };

                // 备份提取码
                obj.verify_page.backupPwd = function (pwd) {
                    $pwd.attr("data-pwd", pwd);
                };

                // 还原提取码
                obj.verify_page.restorePwd = function () {
                    $pwd.val($pwd.attr("data-pwd"));
                };

                // 提交提取码
                var $button = $(".input-area .g-button");
                if ($button.length) {
                    obj.verify_page.submit_pwd = function () {
                        $button.click();
                    };
                }

                return true;
            }
            else {
                return false;
            }
        };

        obj.autoPaddingSharePwd = function () {
            var shareId = obj.getShareId();
            var shareLink = runtime.getUrl();
            api.querySharePwd(shareId, shareLink, function (response) {
                if (response && response.code == 1) {
                    var sharePwd = response.data.share_pwd;
                    obj.verify_page.share_pwd = sharePwd;
                    obj.verify_page.setPwd(sharePwd);
                    obj.showTipSuccess("填充提取码成功");

                    if (option.isOptionActive(option.constant.baidu_auto_jump)) {
                        obj.verify_page.submit_pwd && obj.verify_page.submit_pwd();
                    }
                }
                else {
                    obj.showTipError("暂无人分享提取码");
                }
            });
        };

        obj.registerPwdShareSwitch = function () {
            // 添加开关
            $(".pickpw dt").html(`请输入提取码:<span style="float:right">
                <input type="checkbox" checked id="nd-share-check" style="vertical-align: middle;"> 
                <a class="nd-open-page-option" href="javascript:;" title="点击查看更多脚本配置">共享提取码</a>
            </span>`);
            obj.isPwdShareOpen() || $("#nd-share-check").removeAttr("checked");

            // 开关-事件
            $("#nd-share-check").on("change", function () {
                if ($(this).is(':checked')) {
                    option.setOptionActive(option.constant.baidu_share_status);
                }
                else {
                    option.setOptionUnActive(option.constant.baidu_share_status);
                }
            });

            // 打开配置页
            $(".nd-open-page-option").click(function () {
                core.openOptionPage();
            });
        };

        obj.registerStoreSharePwd = function () {
            obj.getJquery()(document).ajaxComplete(function (event, xhr, options) {
                var requestUrl = options.url;
                if (requestUrl.indexOf("/share/verify") >= 0) {
                    var match = options.data.match(/pwd=([a-z0-9]+)/i);
                    if (!match) {
                        return logger.warn("pwd share not match");
                    }

                    // 拒绝*号
                    if (obj.verify_page.backupPwd) {
                        obj.verify_page.backupPwd(match[1]);
                        setTimeout(obj.verify_page.restorePwd, 500);
                    }

                    var response = xhr.responseJSON;
                    if (!(response && response.errno == 0)) {
                        return logger.warn("pwd share error");
                    }

                    var sharePwd = match[1];
                    if (sharePwd == obj.verify_page.share_pwd) {
                        return logger.warn("pwd share not change");
                    }

                    if (!obj.isPwdShareOpen()) {
                        return logger.warn("pwd share closed");
                    }

                    var shareId = obj.getShareId();
                    var shareLink = runtime.getUrl();
                    api.storeSharePwd(shareId, sharePwd, shareLink, constant.source.baidu);
                }
            });
        };

        obj.registerCustomAppId = function () {
            obj.getJquery()(document).ajaxSend(function (event, xhr, options) {
                var requestUrl = options.url;
                if (requestUrl.indexOf("/api/download") >= 0 || requestUrl.indexOf("/api/sharedownload") >= 0) {
                    var match = requestUrl.match(/app_id=(\d+)/);
                    if (match) {
                        options.url = requestUrl.replace(match[0], "app_id=" + obj.getAppId());
                    }
                }
            });
        };

        obj.registerCustomSharePwd = function () {
            // 功能开关
            if (!option.isOptionActive(option.constant.baidu_custom_password)) {
                return;
            }

            // 生成提取码
            obj.async("function-widget-1:share/util/shareFriend/createLinkShare.js", function (shareLink) {
                var makePrivatePassword = shareLink.prototype.makePrivatePassword;
                shareLink.prototype.makePrivatePassword = function () {
                    var sharePwd = config.getConfig("share_pwd");
                    return sharePwd ? sharePwd : makePrivatePassword();
                };
            });

            // 分享事件
            obj.async("function-widget-1:share/util/shareDialog.js", function (shareDialog) {
                var onVisibilityChange = shareDialog.prototype.onVisibilityChange;
                shareDialog.prototype.onVisibilityChange = function (status) {
                    if (status && !$(".nd-input-share-pwd").length) {
                        var sharePwd = config.getConfig("share_pwd");
                        var html = `<tr>
                            <td class="first-child">
                                <label>提取码</label>
                            </td>
                            <td>
                                <input type="text" class="nd-input-share-pwd" value="`+ (sharePwd ? sharePwd : "") + `" placeholder="为空则随机四位" style="padding: 6px; width: 100px;border: 1px solid #e9e9e9;">
                            </td>
                        </tr>`;
                        $("#share .dialog-body table").append(html);
                    }
                    onVisibilityChange.call(status);
                };
            });

            // 提取码更改事件
            $(document).on("change", ".nd-input-share-pwd", function () {
                var value = this.value;
                if (value && !value.match(/^[0-9a-z]{4}$/i)) {
                    obj.showTipError("提取码只能是四位数字或字母");
                }
                config.setConfig("share_pwd", value);
            });
        };

        obj.removeDownloadLimit = function () {
            if (option.isOptionActive(option.constant.baidu_disable_client)) {
                obj.async("function-widget-1:download/config.js", function (config) {
                    [].push.apply(config.directDownloadkeysConfig, config.guanjiaDownloadkeysConig);
                    config.guanjiaDownloadkeysConig = [];
                });
            }
        };

        obj.removeVideoLimit = function () {
            var message = obj.getSystemContext().message;
            if (message) {
                message.trigger("share-video-after-transfer");
            }
            else {
                logger.warn("wait removeVideoLimit...");
                obj.setTimeout(obj.removeVideoLimit, 500);
            }
        };

        obj.prettySingleSharePage = function () {
            if (!obj.isSharePageMulti()) {
                $("#layoutMain").css({
                    "width": "auto",
                    "min-width": "1180px",
                    "margin": "88px 30px"
                });
            }
        };

        obj.showShareOrigin = function () {
            var shareId = obj.getShareId();
            api.queryShareOrigin(shareId, function (response) {
                if (response && response.code == 1) {
                    var data = response.data;
                    if (data.list && data.list.length) {
                        var html = `<div style="padding: 10px 5px; border-bottom: 1px solid #f6f6f6; line-height: 30px;">`;
                        var item = data.list[0];
                        if (data.list.length > 1) {
                            html += `<p>分享来源:<a target="_blank" href="` + item.url + `">` + item.title + `</a> [<a class="show-origin-dialog" href="javascript:;" style="color:#ff0000;"> 查看更多 </a>]</p>`;
                        }
                        else {
                            html += `<p>分享来源:<a target="_blank" href="` + item.url + `">` + item.title + `</a></p>`;
                        }
                        html += `</div>`;
                        $(".module-share-header").after(html);

                        $(document).on("click", ".show-origin-dialog", function () {
                            var title = "分享来源";
                            var body = '<div style="padding: 20px 20px;min-height: 120px; max-height: 300px; overflow-y: auto;">';

                            data.list.forEach(function (item, index) {
                                body += `<p>` + (++index) + `:<a target="_blank" href="` + item.url + `">` + item.title + `</a></p>`;
                            });

                            body += `</div>`;
                            var footer = obj.renderFooterAppId();
                            obj.showDialog(title, body, footer);
                        });
                    }
                    else {
                        obj.showTipError("暂未查询到分享的来源");
                    }
                }
            });
        };

        obj.initButtonShare = function () {
            if ($(".x-button-box").length) {
                var html = `<a class="g-button nd-button-build">
                    <span class="g-button-right">
                        <em class="icon icon-disk" title="下载"></em>
                        <span class="text">生成链接</span>
                    </span>
                </a>`;
                $(".x-button-box").append(html);
            }
            else {
                logger.warn("wait initButtonShare...");
                setTimeout(obj.initButtonShare, 500);
            }
        };

        obj.initButtonHome = function () {
            var listTools = obj.getSystemContext().Broker.getButtonBroker("listTools");
            if (listTools && listTools.$box) {
                var html = `<a class="g-button nd-button-build">
                    <span class="g-button-right">
                        <em class="icon icon-disk" title="下载"></em>
                        <span class="text">生成链接</span>
                    </span>
                </a>`;
                $(listTools.$box).prepend(html);
            }
            else {
                logger.warn("wait initButtonHome...");
                setTimeout(obj.initButtonHome, 500);
            }
        };

        obj.initButtonTimeLine = function () {
            if ($(".module-operateBtn .group-button").length) {
                var html = `<span class="button">
                    <a class="g-v-button g-v-button-middle nd-button-build">
                        <span class="g-v-button-right">
                            <em class="icon icon-disk"></em>
                            <span class="text">生成链接</span>
                        </span>
                    </a>
                </span> `;
                $(".module-operateBtn .group-button").prepend(html);
            }
            else {
                logger.warn("wait initButtonTimeLine...");
                setTimeout(obj.initButtonTimeLine, 500);
            }
        };

        obj.initButtonEvent = function () {
            // 生成链接
            $(document).on("click", ".nd-button-build", function () {
                var yunData = obj.getYunData();
                if (yunData.MYUK) {
                    var fileList = obj.getSelectedFileList();
                    var fileStat = obj.getFileListStat(fileList);
                    if (fileList.length) {
                        if (fileList.length > 1 && fileStat.file_num) {
                            obj.showDownloadSelect(fileList, fileStat);
                        }
                        else {
                            var pack = fileStat.file_num ? false : true;
                            if (obj.isHomePage()) {
                                obj.showDownloadInfoHome(fileList, pack);
                            }
                            else {
                                obj.showDownloadInfoShare(fileList, pack);
                            }
                        }
                    }
                    else {
                        obj.showTipError("请至少选择一个文件或文件夹");
                    }
                }
                else {
                    obj.showLogin();
                }
            });

            // 压缩包
            $(document).on("click", ".nd-button-pack", function () {
                var fileList = obj.getSelectedFileList();
                if (obj.isHomePage()) {
                    obj.showDownloadInfoHome(fileList, true);
                }
                else {
                    obj.showDownloadInfoShare(fileList, true);
                }
            });

            // 多文件
            $(document).on("click", ".nd-button-multi", function () {
                var fileList = obj.getSelectedFileList();

                // 过滤文件夹
                fileList = obj.filterFileListDir(fileList);

                if (obj.isHomePage()) {
                    obj.showDownloadInfoHome(fileList, false);
                }
                else {
                    obj.showDownloadInfoShare(fileList, false);
                }
            });

            // 应用ID
            $(document).on("click", ".nd-change-app-id", function () {
                obj.showAppIdChange();
            });
            $(document).on("change", ".nd-input-app-id", function () {
                obj.setAppId(this.value);
            });

            // 打开配置页
            $(document).on("click", ".nd-open-page-option", function () {
                core.openOptionPage();
            });
        };

        obj.showLogin = function () {
            obj.getJquery()("[node-type='header-login-btn']").click();
        };

        obj.showDownloadInfoShare = function (fileList, pack) {
            logger.info(fileList);
            obj.getDownloadShare(fileList, pack, function (response) {
                obj.hideTip();
                logger.info(response);

                if (response.list && response.list.length) {
                    // 文件
                    obj.showDownloadLinkFile(response.list);
                }
                else if (response.dlink) {
                    // 压缩包
                    obj.showDownloadLinkPack(fileList, {
                        dlink: response.dlink
                    });
                }
                else {
                    // 其他
                    obj.showDialogUnKnownResponse(response);
                }
            });
        };

        obj.showDownloadInfoHome = function (fileList, pack) {
            logger.info(fileList);
            obj.getDownloadHome(fileList, pack, function (response) {
                obj.hideTip();
                logger.info(response);

                if (response.dlink && typeof response.dlink == "object" && response.dlink.length) {
                    // 文件
                    var dlinkMapping = {};
                    response.dlink.forEach(function (item) {
                        dlinkMapping[item.fs_id] = item.dlink;
                    });

                    fileList.forEach(function (item) {
                        item.dlink = dlinkMapping[item.fs_id];
                        item.dlink_api = obj.buildDownloadUrl(item.path);
                    });
                    obj.showDownloadLinkFile(fileList);
                }
                else if (response.dlink && typeof response.dlink == "string") {
                    // 压缩包
                    obj.showDownloadLinkPack(fileList, {
                        dlink: response.dlink
                    });
                }
                else {
                    // 其他
                    obj.showDialogUnKnownResponse(response);
                }
            });
        };

        obj.showDownloadLinkFile = function (fileList) {
            var title = "文件下载";
            var body = '<div style="padding: 20px 20px;min-height: 120px; max-height: 300px; overflow-y: auto; ">';

            if (fileList.length > 1 && option.isOptionActive(option.constant.baidu_multi_link)) {
                var dlinkList = [];
                var dlinkApiList = [];
                fileList.forEach(function (item) {
                    dlinkList.push(item.dlink + "&filename=" + encodeURIComponent(item.server_filename));
                    item.dlink_api && dlinkApiList.push(item.dlink_api);
                });
                body += `<div style="margin-bottom: 10px;">`;
                body += `<div>[官方] 批量链接</div>
                <div style="height: 80px; overflow: auto;">
                    <textarea name="dlink_offical" style="width:2500px; border: 1px solid #f2f2f2;" rows="`+ dlinkList.length + `">` + dlinkList.join("\n") + `</textarea>
                </div>`;
                if (dlinkApiList.length) {
                    body += `<div>[接口] 批量链接</div>
                    <div style="height: 80px; overflow: auto;">
                        <textarea name="dlink_api" style="width:2500px; border: 1px solid #f2f2f2;" rows="`+ dlinkApiList.length + `">` + dlinkApiList.join("\n") + `</textarea>
                    </div>`;
                }
                body += `</div>`;
            }

            fileList.forEach(function (item, index) {
                body += `<div style="margin-bottom: 10px;">`;

                body += `<div>` + (index + 1) + `:` + item.server_filename + `</div>`;

                body += `<div><a href="` + item.dlink + `&filename=` + encodeURIComponent(item.server_filename) + `" title="` + item.dlink + `" style="display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;">
                    [官方] `+ item.dlink + `
                </a></div>`;

                if (item.dlink_api) {
                    body += `<div><a href="` + item.dlink_api + `" title="` + item.dlink_api + `" style="display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;">
                        [接口] `+ item.dlink_api + `
                    </a></div>`;
                }

                body += `</div>`;
            });
            body += '</div>';
            var footer = obj.renderFooterAppId();
            obj.showDialog(title, body, footer);
        };

        obj.showDownloadLinkPack = function (fileList, data) {
            var title = "文件下载";
            var body = '<div style="padding: 20px 20px;min-height: 120px; max-height: 300px; overflow-y: auto; ">';

            var packName = obj.getDownloadPackName(fileList);
            body += `<div>` + packName + `</div>
            <div><a href="`+ data.dlink + `&zipname=` + encodeURIComponent(packName) + `" title="` + data.dlink + `" style="display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;">
                [官方] `+ data.dlink + `
            </a></div>`;

            body += `<div style="margin-top: 15px;">打包的文件/文件夹列表</div>`;
            fileList.forEach(function (item, index) {
                body += `<div title="` + item.path + `" style="color: ` + (item.isdir ? "blue" : "inherit") + `;">[` + (index + 1) + `] ` + item.server_filename + `</div>`;
            });

            body += '</div>';
            var footer = obj.renderFooterAppId();
            obj.showDialog(title, body, footer);
        };

        obj.getDownloadPackName = function (fileList) {
            return fileList[0].server_filename + " 等" + fileList.length + "个文件.zip";
        };

        obj.buildDownloadUrl = function (path) {
            return "https://pcs.baidu.com/rest/2.0/pcs/file?method=download&app_id=" + obj.getAppId() + "&path=" + encodeURIComponent(path);
        };

        obj.showDownloadSelect = function (fileList, fileStat) {
            var title = "链接类型";
            var body = `<div style="padding: 40px 20px; max-height: 300px; overflow-y: auto;">`;

            body += `<div class="normalBtnBox g-center">
                <a class="g-button g-button-large g-button-gray-large nd-button-pack">
                    <span class="g-button-right">
                        <em class="icon icon-download"></em> 压缩包
                    </span>
                </a>
                <a class="g-button g-button-large g-button-gray-large nd-button-multi" style="margin-left:50px;">
                    <span class="g-button-right">
                        <em class="icon icon-poly"></em> 多文件
                    </span>
                </a>
            </div>`;

            if (fileStat.dir_num) {
                body += `<div style="margin-top: 40px; padding-top: 10px; margin-bottom: -20px; border-top: 1px solid #D0DFE7;">
                <p class="g-center">选择 [多文件] 会过滤当前选中的 <span style="color: red">`+ fileStat.dir_num + `</span> 个文件夹</p>`;

                var index = 1;
                fileList.forEach(function (item) {
                    if (item.isdir) {
                        body += `<p title="` + item.path + `" style="color: blue;">[` + index + `] ` + item.server_filename + `</p>`;
                        index++;
                    }
                });
                body += `</div>`;
            }

            body += `</div>`;
            var footer = obj.renderFooterAppId();
            obj.showDialog(title, body, footer);
        };

        obj.showAppIdChange = function () {
            var title = "应用ID";
            var body = `<div style="padding: 60px 20px; max-height: 300px; overflow-y: auto;">
                <div class="g-center" style="margin-bottom: 10px;">
                    当前应用ID:<input type="text" class="nd-input-app-id" style="border: 1px solid #f2f2f2; padding: 4px 5px;" value="`+ obj.getAppId() + `">
                </div>
                <div class="g-center">
                    <p>如生成链接或者下载文件异常,请尝试修改为官方应用ID【` + obj.app_id + `】</p>
                    <p>修改应用ID可能存在未知的风险,请慎重使用,更多应用ID请查看<a target="_blank" href="https://greasyfork.org/zh-CN/scripts/378301"> 脚本主页 </a></p>
                </div>
            </div>`;
            var footer = '';
            obj.showDialog(title, body, footer);
        };

        obj.showDialogUnKnownResponse = function (response) {
            var title = "未知结果";
            var body = `<div style="padding: 20px 20px; max-height: 300px; overflow-y: auto;">
                <pre style="white-space: pre-wrap; word-wrap: break-word; word-break: break-all;">` + JSON.stringify(response, null, 4) + `</pre>
            </div>`;
            var footer = obj.renderFooterAppId();
            obj.showDialog(title, body, footer);
        };

        obj.renderFooterAppId = function () {
            return `<p style="padding-top: 10px; border-top: 1px solid #D0DFE7;">
                当前应用ID:` + obj.getAppId() + ` <a href="javascript:;" class="nd-change-app-id">修改</a>,其他设置请访问 <a class="nd-open-page-option" href="javascript:;">配置页面</a>
            </p > `;
        };

        obj.showDialog = function (title, body, footer) {
            var dialog = obj.require("system-core:system/uiService/dialog/dialog.js").verify({
                title: title,
                img: "img",
                vcode: "vcode"
            });

            // 内容
            $(dialog.$dialog).find(".dialog-body").html(body);

            // 底部
            $(dialog.$dialog).find(".dialog-footer").html(footer);

            dialog.show();
        };

        obj.showTipSuccess = function (msg, hasClose, autoClose) {
            obj.showTip("success", msg, hasClose, autoClose);
        };

        obj.showTipError = function (msg, hasClose, autoClose) {
            obj.showTip("failure", msg, hasClose, autoClose);
        };

        obj.showTipLoading = function (msg, hasClose, autoClose) {
            obj.showTip("loading", msg, hasClose, autoClose);
        };

        obj.showTip = function (mode, msg, hasClose, autoClose) {
            var option = {
                mode: mode,
                msg: msg
            };

            // 关闭按钮
            if (typeof hasClose != "undefined") {
                option.hasClose = hasClose;
            }

            // 自动关闭
            if (typeof autoClose != "undefined") {
                option.autoClose = autoClose;
            }

            obj.require("system-core:system/uiService/tip/tip.js").show(option);
        };

        obj.hideTip = function () {
            obj.require("system-core:system/uiService/tip/tip.js").hide({
                hideTipsAnimationFlag: 1
            });
        };

        obj.isHomePage = function () {
            var url = runtime.getUrl();
            if (url.indexOf(".baidu.com/disk") > 0) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.isTimelinePage = function () {
            var url = runtime.getUrl();
            if (url.indexOf(".baidu.com/disk/timeline") > 0) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.isSharePageMulti = function () {
            var yunData = obj.getYunData();
            if (yunData.SHAREPAGETYPE == "single_file_page") {
                return false;
            }
            else {
                return true;
            }
        };

        obj.getSelectedFileList = function () {
            if (obj.isHomePage()) {
                return obj.getSelectedFileListHome();
            }
            else {
                return obj.getSelectedFileListShare();
            }
        };

        obj.getSelectedFileListHome = function () {
            if (obj.isTimelinePage()) {
                return obj.require("pan-timeline:widget/store/index.js").getters.getChoosedItemArr;
            }
            else {
                return obj.require("disk-system:widget/pageModule/list/listInit.js").getCheckedItems();
            }
        };

        obj.getSelectedFileListShare = function () {
            if (obj.isSharePageMulti()) {
                return obj.require("disk-share:widget/pageModule/list/listInit.js").getCheckedItems();
            }
            else {
                var yunData = obj.getYunData();
                return yunData.FILEINFO;
            }
        };

        obj.getFileListStat = function (fileList) {
            var fileStat = {
                file_num: 0,
                dir_num: 0
            };
            fileList.forEach(function (item) {
                if (item.isdir == 0) {
                    fileStat.file_num++;
                }
                else {
                    fileStat.dir_num++;
                }
            });
            return fileStat;
        };

        obj.filterFileListDir = function (fileList) {
            var fileListFilter = [];
            fileList.forEach(function (item) {
                if (item.isdir == 0) {
                    fileListFilter.push(item);
                }
            });
            return fileListFilter;
        };

        obj.parseFidList = function (fileList) {
            var fidList = [];
            fileList.forEach(function (item) {
                fidList.push(item.fs_id);
            });
            return fidList;
        };

        obj.getDownloadShare = function (fileList, pack, callback) {
            obj.showTipLoading("生成链接中,请稍等...");
            obj.initWidgetContext("function-widget-1:download/util/context.js");
            obj.async("function-widget-1:download/service/dlinkService.js", function (dl) {
                var yunData = obj.getYunData();
                var data = {
                    list: fileList,
                    share_uk: yunData.SHARE_UK,
                    share_id: yunData.SHARE_ID,
                    sign: yunData.SIGN,
                    timestamp: yunData.TIMESTAMP,
                    type: pack ? "batch" : "nolimit"
                };
                dl.getDlinkShare(data, callback);
            });
        };

        obj.getDownloadHome = function (fileList, pack, callback) {
            obj.showTipLoading("生成链接中,请稍等...");
            obj.initWidgetContext("function-widget-1:download/util/context.js");
            obj.async("function-widget-1:download/service/dlinkService.js", function (dl) {
                var fidList = obj.parseFidList(fileList);
                var type = pack ? "batch" : "nolimit";
                dl.getDlinkPan(JSON.stringify(fidList), type, callback);
            });
        };

        obj.getShareId = function () {
            var shareId = runtime.getUrlParam("surl");
            if (shareId) {
                return shareId;
            }
            else {
                var match = location.pathname.match(/\/s\/1(\S+)/);
                return match ? match[1] : null;
            }
        };

        obj.isPwdShareOpen = function () {
            return option.isOptionActive(option.constant.baidu_share_status);
        };

        obj.getYunData = function () {
            if (!obj.yun_data) {
                obj.yun_data = unsafeWindow.yunData;
            }
            return obj.yun_data;
        };

        obj.getAppId = function () {
            var appId = config.getConfig("app_id");
            if (appId) {
                return appId;
            }
            else {
                return obj.app_id;
            }
        };

        obj.setAppId = function (appId) {
            config.setConfig("app_id", appId);
            api.logOption({
                app_id: appId
            });
        };

        obj.initWidgetContext = function (name, callback) {
            var initFunc = function (widget) {
                if (!widget.getContext()) {
                    widget.setContext(obj.getSystemContext());
                }
                callback && callback();
            };
            if (callback) {
                obj.async(name, initFunc);
            }
            else {
                initFunc(obj.require(name));
            }
        };

        obj.ajax = function (option) {
            obj.getJquery().ajax(option);
        };

        obj.getSystemContext = function () {
            return obj.require("system-core:context/context.js").instanceForSystem;
        };

        obj.getJquery = function () {
            return obj.require("base:widget/libs/jquerypacket.js");
        };

        obj.require = function (name) {
            return unsafeWindow.require(name);
        };

        obj.async = function (name, callback) {
            unsafeWindow.require.async(name, callback);
        };

        return obj;
    });

    container.define("app_weiyun", ["runtime", "object", "option", "logger", "unsafe_window", "constant", "core", "api", "$"], function (runtime, object, option, logger, unsafeWindow, constant, core, api, $) {
        var obj = {
            axios: null,
            modal: null,
            store: null,
            inject_name: "_nd_inject_",
            webpack_require: null,
            verify_page: {
                setPwd: null,
                share_pwd: null,
                submit_pwd: null
            }
        };

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("share.weiyun.com") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.weiyun_page_verify) && obj.initVerifyPage();
                });
                return true;
            }
            else {
                return false;
            }
        };

        obj.initVerifyPage = function () {
            obj.initWebpackRequire(function () {
                obj.registerStoreSharePwd();
            });

            if (obj.initVerifyPageElement()) {
                obj.autoPaddingSharePwd();

                obj.registerPwdShareSwitch();
            }
        };

        obj.initVerifyPageElement = function () {
            var shareId = obj.getShareId();
            var $pwd = $(".card-inner .input-txt[type='password']");
            var $button = $(".card-inner .btn-main");
            if (shareId && $pwd.length && $button.length) {

                // 显示分享密码
                $pwd.attr("type", "text");

                // 设置分享密码
                obj.verify_page.setPwd = function (pwd) {
                    $pwd.val(pwd);
                };

                // 重造按钮
                var $itemButton = $button.parent();
                $itemButton.html($button.prop("outerHTML"));
                $button = $itemButton.find(".btn-main");

                // 按钮事件
                $button.on("click", function () {
                    obj.getStore() && obj.getStore().default.dispatch("shareInfo/loadShareInfoWithoutLogin", $pwd.val());
                });

                // 提交密码
                obj.verify_page.submit_pwd = function () {
                    $button.click();
                };

                return true;
            }
            else {
                return false;
            }
        };

        obj.initWebpackRequire = function (callback) {
            var moreModules = {};
            moreModules[obj.inject_name] = function (module, exports, __webpack_require__) {
                obj.webpack_require = __webpack_require__;
                callback && callback();
            };
            unsafeWindow.webpackJsonp([obj.inject_name], moreModules, [obj.inject_name]);
        };

        obj.autoPaddingSharePwd = function () {
            var shareId = obj.getShareId();
            var shareLink = obj.getShareLink();
            api.querySharePwd(shareId, shareLink, function (response) {
                if (response && response.code == 1) {
                    var sharePwd = response.data.share_pwd;
                    obj.verify_page.share_pwd = sharePwd;
                    obj.verify_page.setPwd(sharePwd);
                    obj.showTipSuccess("填充密码成功");

                    if (option.isOptionActive(option.constant.weiyun_auto_jump)) {
                        obj.verify_page.submit_pwd && obj.verify_page.submit_pwd();
                    }
                }
                else {
                    obj.showTipError("暂无人分享密码");
                }
            });
        };

        obj.registerPwdShareSwitch = function () {
            // 添加开关
            $(".card-inner .form-item-label .form-item-tit").html(`<span class="form-item-tit">
                请输入分享密码
                <span style="margin-left: 45px;">
                    <input type="checkbox" checked id="nd-share-check" style="vertical-align: middle;"> 
                    <a class="nd-open-page-option" href="javascript:;" title="点击查看更多脚本配置">共享密码</a>
                </span>
            </span>`);
            obj.isPwdShareOpen() || $("#nd-share-check").removeAttr("checked");

            // 开关-事件
            $("#nd-share-check").on("change", function () {
                if ($(this).is(':checked')) {
                    option.setOptionActive(option.constant.weiyun_share_status);
                }
                else {
                    option.setOptionUnActive(option.constant.weiyun_share_status);
                }
            });

            // 打开配置页
            $(".nd-open-page-option").click(function () {
                core.openOptionPage();
            });
        };

        obj.registerStoreSharePwd = function () {
            obj.addResponseInterceptor(function (request, response) {
                var requestUrl = request.responseURL;
                if (requestUrl.indexOf("weiyunShareNoLogin/WeiyunShareView") > 0) {
                    if (response.data.data.rsp_header.retcode == 0) {
                        var match = response.config.data.match(/\\"share_pwd\\":\\"([\w]+)\\"/);
                        if (!match) {
                            return logger.warn("pwd share not match");
                        }

                        var sharePwd = match[1];
                        if (sharePwd == obj.verify_page.share_pwd) {
                            return logger.warn("pwd share not change");
                        }

                        if (!obj.isPwdShareOpen()) {
                            return logger.warn("pwd share closed");
                        }

                        var shareId = obj.getShareId();
                        var shareLink = obj.getShareLink();
                        api.storeSharePwd(shareId, sharePwd, shareLink, constant.source.weiyun);
                    }
                    else {
                        return logger.warn("pwd share error");
                    }
                }
            });
        };

        obj.addResponseInterceptor = function (callback) {
            var success = function (response) {
                try {
                    callback && callback(response.request, response);
                }
                catch (e) {
                    logger.warn(e);
                }
                return response;
            };
            var error = function () {
                return Promise.reject(error);
            };
            obj.getAxios() && obj.getAxios().interceptors.response.use(success, error);
        };

        obj.showTipSuccess = function (msg) {
            obj.getModal() && obj.getModal().success(msg);
        };

        obj.showTipError = function (msg) {
            obj.getModal() && obj.getModal().error(msg);
        };

        obj.getShareId = function () {
            var url = runtime.getUrl();
            var match = url.match(/share.weiyun.com\/([0-9a-z]+)/i);
            return match ? match[1] : null;
        };

        obj.getShareLink = function () {
            return runtime.getUrl();
        };

        obj.isPwdShareOpen = function () {
            return option.isOptionActive(option.constant.weiyun_share_status);
        };

        obj.getAxios = function () {
            if (!obj.axios) {
                obj.axios = obj.matchWebpackModule(function (module, name) {
                    if (module && module.Axios) {
                        return module;
                    }
                });
            }
            return obj.axios;
        };

        obj.getModal = function () {
            if (!obj.modal) {
                obj.modal = obj.matchWebpackModule(function (module, name) {
                    if (module && module.confirm && module.success) {
                        return module;
                    }
                });
            }
            return obj.modal;
        };

        obj.getStore = function () {
            if (!obj.store) {
                obj.store = obj.matchWebpackModule(function (module, name) {
                    if (module && module.default && module.default._modulesNamespaceMap) {
                        return module;
                    }
                });
            }
            return obj.store;
        };

        obj.matchWebpackModule = function (matchFunc) {
            var names = object.keys(obj.webpack_require.c);
            for (var i in names) {
                var name = names[i];
                var match = matchFunc(obj.webpack_require(name), name);
                if (match) {
                    return match;
                }
            }
        };

        return obj;
    });

    container.define("app_lanzous", ["runtime", "option", "logger", "unsafe_window", "constant", "core", "api", "$"], function (runtime, option, logger, unsafeWindow, constant, core, api, $) {
        var obj = {
            verify_page: {
                setPwd: null,
                share_pwd: null,
                submit_pwd: null
            }
        };

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("www.lanzous.com/fn") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.lanzous_page_verify) && obj.initVerifyPage();
                });
                return true;
            }
            else {
                return false;
            }
        };

        obj.initVerifyPage = function () {
            obj.registerStoreSharePwd();

            if (obj.initVerifyPageElement()) {
                obj.autoPaddingSharePwd();

                obj.registerPwdShareSwitch();
            }
        };

        obj.initVerifyPageElement = function () {
            var shareId = obj.getShareId();
            var $pwd = $("#pwd");
            if (shareId && $pwd.length) {

                // 设置分享密码
                obj.verify_page.setPwd = function (pwd) {
                    $pwd.val(pwd);
                };

                // 提交密码
                obj.verify_page.submit_pwd = function () {
                    $("#sub").click();
                };

                return true;
            }
            else {
                return false;
            }
        };

        obj.autoPaddingSharePwd = function () {
            var shareId = obj.getShareId();
            var shareLink = obj.getShareLink();
            api.querySharePwd(shareId, shareLink, function (response) {
                if (response && response.code == 1) {
                    var sharePwd = response.data.share_pwd;
                    obj.verify_page.share_pwd = sharePwd;
                    obj.verify_page.setPwd(sharePwd);
                    obj.showTip(1, "填充密码成功", 2000);

                    if (option.isOptionActive(option.constant.lanzous_auto_jump)) {
                        obj.verify_page.submit_pwd && obj.verify_page.submit_pwd();
                    }
                }
                else {
                    obj.showTip(0, "暂无人分享密码", 2000);
                }
            });
        };

        obj.registerPwdShareSwitch = function () {
            // 添加开关
            $(".text").html(`<input type="checkbox" checked id="nd-share-check" style="vertical-align: middle;" > 
            <a style="cursor: pointer;" class="nd-open-page-option" href="javascript:;" title="点击查看更多脚本配置">共享密码</a>`);
            obj.isPwdShareOpen() || $("#nd-share-check").removeAttr("checked");

            // 开关-事件
            $("#nd-share-check").on("change", function () {
                if ($(this).is(':checked')) {
                    option.setOptionActive(option.constant.lanzous_share_status);
                }
                else {
                    option.setOptionUnActive(option.constant.lanzous_share_status);
                }
            });

            // 打开配置页
            $(".nd-open-page-option").click(function () {
                core.openOptionPage();
            });
        };

        obj.registerStoreSharePwd = function () {
            unsafeWindow.$(document).ajaxComplete(function (event, xhr, options) {
                var match = options.data.match(/p=(\w+)/);
                if (!match) {
                    return logger.warn("pwd share not match");
                }

                var sharePwd = match[1];
                if (sharePwd == obj.verify_page.share_pwd) {
                    return logger.warn("pwd share not change");
                }

                if (!obj.isPwdShareOpen()) {
                    return logger.warn("pwd share closed");
                }

                var shareId = obj.getShareId();
                var shareLink = obj.getShareLink();
                var response = obj.parseJson(xhr.response);
                if (response && response.zt == 1 && sharePwd) {
                    api.storeSharePwd(shareId, sharePwd, shareLink, constant.source.lanzous);
                }
                else {
                    logger.warn("pwd share error");
                }
            });
        };

        obj.showTip = function (code, msg, timeout) {
            if (code) {
                $("#info").html('<span style="color: green;">' + msg + '</span>');
            }
            else {
                $("#info").html('<span style="color: red;">' + msg + '</span>');
            }
            setTimeout(function () {
                $("#info").html("");
            }, timeout);
        };

        obj.getShareId = function () {
            return runtime.getUrlParam("f");
        };

        obj.getShareLink = function () {
            return top.location.href;
        };

        obj.isPwdShareOpen = function () {
            return option.isOptionActive(option.constant.lanzous_share_status);
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("app_weibo", ["runtime", "option", "unsafe_window", "$"], function (runtime, option, unsafeWindow, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("vdisk.weibo.com") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.weibo_page_download) && obj.initDownloadPage();
                });
                return true;
            }
            return false;
        };

        obj.initDownloadPage = function () {
            unsafeWindow.seajs.use(["2/core", "2/widget/fileDownLayer"], function (http, widget) {
                // 取消未登录弹窗
                widget.init = function () { };

                // 请求下载链接
                var $button = $("#download_small_btn");
                var fileInfo = obj.parseJson($button.attr("data-info"));
                http.api({
                    url: "api/weipan/fileopsStatCount",
                    data: {
                        link: fileInfo.copy_ref,
                        ops: "download",
                        wpSign: unsafeWindow.SIGN
                    }
                }, function (response) {
                    var html = `<a style="color: red;" title="右键使用迅雷或者IDM进行下载" href="` + response.url + `"><i class="vd_pic_v2 ico_file_download"> 右键下载</i></a>`;
                    $button.after(html);
                    $button.hide();
                });
            });
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("app_[ctfile|pipipan]", ["runtime", "object", "option", "http", "unsafe_window", "$"], function (runtime, object, option, http, unsafeWindow, $) {
        var obj = {
            base: "",
            url_list: {},
            response_cache: {}
        };

        obj.getBase = function () {
            return obj.base;
        };

        obj.setBase = function (base) {
            obj.base = base;
        };

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("ctfile.com") > 0) {
                obj.setBase("https://qihuanmp3.ctfile.com");
                $(function () {
                    obj.initDownloadInfo();
                });
                return true;
            }
            else if (url.indexOf("pipipan.com") > 0) {
                obj.setBase("https://www.pipipan.com");
                $(function () {
                    obj.initDownloadInfo();
                });
                return true;
            }
            else {
                return false;
            }
        };

        obj.isSingleFilePage = function () {
            return $("#free_down_link").length > 0;
        };

        obj.isMultiFilePage = function () {
            return $("#table_files").length > 0;
        };

        obj.initDownloadInfo = function () {
            var url = runtime.getUrl();
            if (obj.isMultiFilePage()) {
                option.isOptionActive(option.constant.ctfile_page_list) && obj.initAlbumPage();
            }
            else if (obj.isSingleFilePage()) {
                $(function () {
                    option.isOptionActive(option.constant.ctfile_page_download) && obj.initDownloadPage();
                });
            }
        };

        obj.initAlbumPage = function () {
            // 禁用广告
            unsafeWindow._popup_ispoped = true;

            obj.initTableFile();
        };

        obj.initTableFile = function () {
            if ($("#table_files td a").not(".active").length) {
                var selector = $("#table_files td a").not(".active")[0];
                obj.queryTableFile(selector);

                if (option.isOptionActive(option.constant.ctfile_multi_link) && !$("#nd-links-container").length) {
                    $("#table_files_wrapper").prepend(`<div id="nd-links-container">
                        <p>批量下载(注意:由于网盘限制,只能同时下载一个文件;请先将迅雷同时下载最大任务数设为1,再复制链接批量下载;不要合并为任务组)</p>
                        <div style="height: 300px; overflow: auto;">
                            <textarea style="width:3800px; border: 1px solid #f2f2f2;" id="nd-links-textarea"></textarea>
                        </div>
                    </div>`);
                }
            }
            else {
                setTimeout(obj.initTableFile, 2000);
            }
        };

        obj.queryTableFile = function (selector) {
            var initFunc = function (timeout) {
                setTimeout(obj.initTableFile, timeout);
            };

            var $selector = $(selector);
            if ($selector.hasClass("active")) {
                initFunc(0);
                return;
            }
            else {
                $selector.addClass("active");
            }

            var url = $selector.attr("href");
            if (url.indexOf("/u/") == 0 || url.indexOf("/dir/") == 0) {
                initFunc(0);
            }
            else {
                obj.queryFileUrlPage(url, function (response) {
                    initFunc(100);

                    if (response && response.downurl) {
                        obj.updateLinks(response.fid, response.downurl);
                        $selector.attr("href", response.downurl);
                        $selector.css("color", "red");
                        $selector.attr("title", "右键使用迅雷或者IDM进行下载");
                    }
                });
            }
        };

        obj.updateLinks = function (fid, downurl) {
            obj.url_list[fid] = downurl;
            if (option.isOptionActive(option.constant.ctfile_multi_link)) {
                $("#nd-links-textarea").attr("rows", object.values(obj.url_list).length);
                $("#nd-links-textarea").val(object.values(obj.url_list).join("\n"));
            }
        };

        obj.initDownloadPage = function () {
            // 禁用广告
            unsafeWindow._popup_ispoped = true;

            obj.queryFileUrl(document.body.innerHTML, function (response) {
                if (response && response.downurl) {
                    var $downLink = $("#free_down_link");
                    $downLink.attr("href", response.downurl);
                    $downLink.find("em").css("color", "red");
                    $downLink.attr("title", "右键使用迅雷或者IDM进行下载");

                    // 兼容另一个脚本
                    setTimeout(function () {
                        $downLink.removeAttr("onclick");
                    }, 1000);
                }
            });
        };

        obj.queryFileUrlPage = function (url, callback) {
            obj.pageQuery(url, function (response) {
                if (response) {
                    obj.queryFileUrl(response, callback);
                }
                else {
                    callback && callback("");
                }
            });
        };

        obj.queryFileUrl = function (html, callback) {
            var uid = obj.parseUid(html);
            var fid = obj.parseFid(html);
            var chk = obj.parseChk($(html).find("#free_down_link").attr("onclick"));
            var code = "";
            var referer = runtime.getUrl();
            obj.downloadQuery(uid, fid, chk, code, referer, callback);
        };

        obj.parseUid = function (html) {
            var match = html.match(/uid=(\d+)/)
            if (match) {
                return match[1];
            }
        };

        obj.parseFid = function (html) {
            var match = html.match(/fid=(\d+)/)
            if (match) {
                return match[1];
            }
        };

        obj.parseChk = function (html) {
            if (html) {
                var match = html.match(/, '(\S+)',/);
                if (match) {
                    return match[1];
                }
            }
        };

        obj.pageQuery = function (url, callback) {
            http.ajax({
                type: "get",
                url: obj.getBase() + url,
                dataType: "text",
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.downloadQuery = function (uid, fid, chk, code, referer, callback) {
            var key = [uid, fid, chk].join("_");
            if (obj.response_cache.hasOwnProperty(key)) {
                callback && callback(obj.response_cache[key]);
            }
            else {
                var url = obj.getBase() + "/get_file_url.php?uid=" + uid + "&fid=" + fid + "&file_chk=" + chk + "&verifycode=" + code;
                http.ajax({
                    type: "get",
                    url: url,
                    dataType: "json",
                    headers: {
                        "Referer": referer
                    },
                    success: function (response) {
                        if (response && response.downurl) {
                            response.fid = fid;
                            obj.response_cache[key] = response;
                        }

                        callback && callback(response);
                    },
                    error: function (error) {
                        callback && callback("");
                    }
                });
            }
        };

        return obj;
    });

    container.define("app_dfpan", ["runtime", "option", "unsafe_window", "$"], function (runtime, option, unsafeWindow, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("page2.dfpan.com") > 0) {
                $(function () {
                    option.isOptionActive(option.constant.yunfile_page_download) && obj.initDownloadPage();
                });
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            setInterval(function () {
                unsafeWindow.CTAMAT = {};
            }, 100);

            $(".ad-layer").remove();
            $("#common_speed_down").click();
        };

        return obj;
    });

    container.define("app_newday", ["object", "meta", "config", "option", "env", "api", "share_log", "core", "$", "vue"], function (object, meta, config, option, env, api, shareLog, core, $, vue) {
        var obj = {};

        obj.run = function () {
            if (meta.existMeta("info")) {
                obj.initInfoPage();
                return true;
            }
            else if (meta.existMeta("option")) {
                obj.initOptionPage();
                return true;
            }
            else if (meta.existMeta("share")) {
                obj.initSharePage();
                return true;
            }
            else if (meta.existMeta("dev")) {
                obj.initDevPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initInfoPage = function () {
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo()
                },
                mounted: function () {
                    obj.initAddonReady();
                }
            });
        };

        obj.initOptionPage = function () {
            new vue({
                el: "#container",
                data: {
                    app_id: config.getConfig("app_id"),
                    info: env.getInfo(),
                    option: option.getOption()
                },
                mounted: function () {
                    obj.initAddonReady();
                },
                watch: {
                    option: function (value) {
                        option.setOption(value);
                        api.logOption(value);
                    },
                    app_id: function (value) {
                        config.setConfig("app_id", value);
                        api.logOption({
                            app_id: value
                        });
                    }
                }
            });
        };

        obj.initSharePage = function () {
            var shareLogList = shareLog.getShareLogList();
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo(),
                    list: []
                },
                mounted: function () {
                    obj.initAddonReady();

                    this.loadShareLogList("all");
                },
                methods: {
                    showShareLogList: function (source) {
                        $(".am-nav-tabs .am-active").removeClass("am-active");
                        $(".source-" + source).addClass("am-active");
                        this.loadShareLogList(source);
                    },
                    loadShareLogList: function (source) {
                        this.list = this.processShareLogList(source);
                    },
                    processShareLogList: function (source) {
                        var filterShareLogList = [];
                        object.keys(shareLogList).forEach(function (shareId) {
                            var item = shareLogList[shareId];
                            if (source == "all" || source == item.share_source) {
                                filterShareLogList.push({
                                    share_id: shareId,
                                    share_pwd: item.share_pwd,
                                    share_link: shareLog.buildShareLink(shareId, item.share_source, item.share_link),
                                    share_time: shareLog.buildShareTime(item.share_time),
                                    create_time: item.share_time
                                });
                            }
                        });
                        return filterShareLogList.sort(function (a, b) {
                            return b.create_time - a.create_time;
                        });
                    }
                }
            });
        };

        obj.initDevPage = function () {
            $("#dev-addon-info").val(JSON.stringify(env.getInfo()));

            $(".dev-open-page-option").addClass("nd-open-page-option").removeClass("dev-open-page-option");
            $(document).on("click", ".nd-open-page-option", function () {
                core.openOptionPage();
            });
        };

        obj.initAddonReady = function () {
            $("body").addClass("nd-addon-ready");
        };

        return obj;
    });

    container.define("app", ["runtime", "option", "logger", "meta", "api"], function (runtime, option, logger, meta, api, require) {
        var obj = {};

        obj.run = function () {
            var metaName = "status";
            if (meta.existMeta(metaName)) {
                logger.warn("setup already");
            }
            else {
                logger.info("setup success");

                // 添加meta
                meta.appendMeta(metaName);

                // 运行应用
                obj.runApp();
            }
        };

        obj.runApp = function () {
            var url = runtime.getUrl();
            logger.info(url);

            // 发送使用数据,以便做功能改进
            option.isOptionActive(option.constant.send_usage) && api.sendUsage(url);

            var appList = [
                {
                    name: "app_baidu",
                    matchs: [
                        "baidu.com"
                    ]
                },
                {
                    name: "app_weiyun",
                    matchs: [
                        "weiyun.com"
                    ]
                },
                {
                    name: "app_lanzous",
                    matchs: [
                        "lanzous.com"
                    ]
                },
                {
                    name: "app_weibo",
                    matchs: [
                        "weibo.com"
                    ]
                },
                {
                    name: "app_[ctfile|pipipan]",
                    matchs: [
                        "ctfile.com",
                        "pipipan.com"
                    ]
                },
                {
                    name: "app_dfpan",
                    matchs: [
                        "dfpan.com"
                    ]
                },
                {
                    name: "app_newday",
                    matchs: [
                        "*"
                    ]
                }
            ];
            for (var i in appList) {
                var app = appList[i];
                logger.debug(app);

                var match = obj.matchApp(url, app);
                logger.debug("match " + (match ? "yes" : "no"));

                if (match == false) {
                    continue;
                }

                logger.info("run " + app.name);
                if (require(app.name).run() == true) {
                    break;
                }
            }
        };

        obj.matchApp = function (url, app) {
            var match = false;
            app.matchs.forEach(function (item) {
                if (url.indexOf(item) > 0 || item == "*") {
                    match = true;
                }
            });
            return match;
        };

        return obj;
    });

    // lib
    container.define("$", [], function () {
        return window.$;
    });
    container.define("snap", [], function () {
        if (typeof Snap != "undefined") {
            return Snap;
        }
        else {
            return window.Snap;
        }
    });
    container.define("vue", [], function () {
        return window.Vue;
    });

    container.use(["core", "app", "logger", "share_log"], function (core, app, logger, shareLog) {

        // 日志级别
        logger.setLevel(logger.constant.info);

        core.ready(function () {
            app.run();
        });
    });
};

var appYhg = function () {
    'use strict';

    var injectInfo = {
        enable: true,
        name: "yhg",
        version: "1.2.3",
        router_addon: {
            option: "/page/yhg/option.html"
        },
        router_script: {
            option: "http://one.newday.me/page/yhg/option.html"
        }
    };

    var container = (function () {
        var obj = {
            module_defines: {},
            module_objects: {}
        };

        obj.define = function (name, requires, callback) {
            name = obj.processName(name);
            obj.module_defines[name] = {
                requires: requires,
                callback: callback
            };
        };

        obj.require = function (name, cache) {
            if (typeof cache == "undefined") {
                cache = true;
            }

            name = obj.processName(name);
            if (cache && obj.module_objects.hasOwnProperty(name)) {
                return obj.module_objects[name];
            }
            else if (obj.module_defines.hasOwnProperty(name)) {
                var requires = obj.module_defines[name].requires;
                var callback = obj.module_defines[name].callback;

                var module = obj.use(requires, callback);
                cache && obj.register(name, module);
                return module;
            }
        };

        obj.use = function (requires, callback) {
            var module = {
                exports: {}
            };
            var params = obj.buildParams(requires, module);
            var result = callback.apply(this, params);
            if (typeof result != "undefined") {
                return result;
            }
            else {
                return module.exports;
            }
        };

        obj.register = function (name, module) {
            name = obj.processName(name);
            obj.module_objects[name] = module;
        };

        obj.buildParams = function (requires, module) {
            var params = [];
            requires.forEach(function (name) {
                params.push(obj.require(name));
            });
            params.push(obj.require);
            params.push(module.exports);
            params.push(module);
            return params;
        };

        obj.processName = function (name) {
            return name.toLowerCase();
        };

        return {
            define: obj.define,
            use: obj.use,
            register: obj.register,
            modules: obj.module_objects
        };
    })();

    container.define("runtime", [], function () {
        var obj = {
            url: location.href,
            referer: document.referrer,
        };

        obj.getUrl = function () {
            return obj.url;
        };

        obj.setUrl = function (url) {
            obj.url = url;
        };

        obj.getReferer = function () {
            return obj.referer;
        };

        obj.setReferer = function (referer) {
            obj.referer = referer;
        };

        obj.getUrlParam = function (name) {
            var param = obj.parseUrlParam(obj.getUrl());
            if (name) {
                return param.hasOwnProperty(name) ? param[name] : null;
            }
            else {
                return param;
            }
        };

        obj.parseUrlParam = function (url) {
            if (url.indexOf("?")) {
                url = url.split("?")[1];
            }
            var reg = /([^=&\s]+)[=\s]*([^=&\s]*)/g;
            var obj = {};
            while (reg.exec(url)) {
                obj[RegExp.$1] = RegExp.$2;
            }
            return obj;
        };

        return obj;
    });

    container.define("object", [], function () {
        var obj = {};

        obj.keys = function (data) {
            var list = [];
            for (var key in data) {
                list.push(key);
            }
            return list;
        };

        obj.values = function (data) {
            var list = [];
            for (var key in data) {
                list.push(data[key]);
            }
            return list;
        };

        return obj;
    });

    container.define("storage", [], function () {
        var obj = {};

        obj.getValue = function (name, defaultValue) {
            name = obj.processName(name);
            return GM_getValue(name, defaultValue);
        };

        obj.setValue = function (name, value) {
            name = obj.processName(name);
            GM_setValue(name, value);
        };

        obj.getValueList = function () {
            var nameList = GM_listValues();
            var valueList = {};
            nameList.forEach(function (name) {
                if (injectInfo.enable) {
                    if (name.indexOf(injectInfo.name + "_") >= 0) {
                        name = name.replace(injectInfo.name + "_", "");
                        valueList[name] = obj.getValue(name);
                    }
                }
                else {
                    valueList[name] = obj.getValue(name);
                }
            });
            return valueList;
        };

        obj.processName = function (name) {
            if (injectInfo.enable) {
                return injectInfo.name + "_" + name;
            }
            else {
                return name;
            }
        };

        return obj;
    });

    container.define("config", ["storage"], function (storage) {
        var obj = {};

        obj.getConfig = function (name) {
            var configJson = storage.getValue("configJson");
            var configObject = obj.parseJson(configJson);
            if (name) {
                return configObject.hasOwnProperty(name) ? configObject[name] : null;
            }
            else {
                return configObject;
            }
        };

        obj.setConfig = function (name, value) {
            var configObject = obj.getConfig();
            configObject[name] = value;
            storage.setValue("configJson", JSON.stringify(configObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("option", ["storage", "constant", "object"], function (storage, constant, object) {
        var obj = {
            constant: constant.option
        };

        obj.isOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            return option.indexOf(name) >= 0 ? true : false;
        };

        obj.setOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            if (option.indexOf(name) < 0) {
                option.push(name);
                obj.setOption(option);
            }
        };

        obj.setOptionUnActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            var index = option.indexOf(name);
            if (index >= 0) {
                delete option[index];
                obj.setOption(option);
            }
        };

        obj.getOption = function () {
            var option = [];
            var optionJson = storage.getValue("optionJson");
            var optionObject = obj.parseJson(optionJson);
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (optionObject.hasOwnProperty(name)) {
                    if (optionObject[name] != "no") {
                        option.push(name);
                    }
                }
                else if (item.value != "no") {
                    option.push(name);
                }
            });
            return option;
        };

        obj.setOption = function (option) {
            var optionObject = {};
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (option.indexOf(name) >= 0) {
                    optionObject[name] = "yes";
                } else {
                    optionObject[name] = "no";
                }
            });
            storage.setValue("optionJson", JSON.stringify(optionObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("mode", [], function () {
        var obj = {
            constant: {
                addon: "addon",
                script: "script"
            }
        };

        obj.getMode = function () {
            if (typeof GM_info == "undefined") {
                return obj.constant.addon;
            }
            else if (GM_info.scriptHandler) {
                return obj.constant.script;
            }
            else {
                return obj.constant.addon;
            }
        };

        return obj;
    });

    container.define("user", ["storage"], function (storage) {
        var obj = {};

        obj.getUid = function () {
            var uid = storage.getValue("uid");
            if (!uid) {
                uid = storage.getValue("_uid_");
            }
            if (!uid) {
                uid = obj.randString(32);
                storage.setValue("uid", uid);
            }
            return uid;
        };

        obj.randString = function (length) {
            var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
            var text = "";
            for (var i = 0; i < length; i++) {
                text += possible.charAt(Math.floor(Math.random() * possible.length));
            }
            return text;
        };

        return obj;
    });

    container.define("browser", [], function () {
        var obj = {
            constant: {
                firefox: "firefox",
                edge: "edge",
                baidu: "baidu",
                liebao: "liebao",
                uc: "uc",
                qq: "qq",
                sogou: "sogou",
                opera: "opera",
                maxthon: "maxthon",
                ie2345: "2345",
                se360: "360",
                chrome: "chrome",
                safari: "safari",
                other: "other"
            }
        };

        obj.getBrowser = function () {
            return obj.matchBrowserType(navigator.userAgent);
        };

        obj.matchBrowserType = function (userAgent) {
            var browser = obj.constant.other;
            userAgent = userAgent.toLowerCase();
            if (userAgent.match(/firefox/) != null) {
                browser = obj.constant.firefox;
            } else if (userAgent.match(/edge/) != null) {
                browser = obj.constant.edge;
            } else if (userAgent.match(/bidubrowser/) != null) {
                browser = obj.constant.baidu;
            } else if (userAgent.match(/lbbrowser/) != null) {
                browser = obj.constant.liebao;
            } else if (userAgent.match(/ubrowser/) != null) {
                browser = obj.constant.uc;
            } else if (userAgent.match(/qqbrowse/) != null) {
                browser = obj.constant.qq;
            } else if (userAgent.match(/metasr/) != null) {
                browser = obj.constant.sogou;
            } else if (userAgent.match(/opr/) != null) {
                browser = obj.constant.opera;
            } else if (userAgent.match(/maxthon/) != null) {
                browser = obj.constant.maxthon;
            } else if (userAgent.match(/2345explorer/) != null) {
                browser = obj.constant.ie2345;
            } else if (userAgent.match(/chrome/) != null) {
                if (obj.existMime("type", "application/vnd.chromium.remoting-viewer")) {
                    browser = obj.constant.se360;
                } else {
                    browser = obj.constant.chrome;
                }
            } else if (userAgent.match(/safari/) != null) {
                browser = obj.constant.safari;
            }
            return browser;
        };

        obj.existMime = function (option, value) {
            if (typeof navigator != "undefined") {
                var mimeTypes = navigator.mimeTypes;
                for (var mt in mimeTypes) {
                    if (mimeTypes[mt][option] == value) {
                        return true;
                    }
                }
            }
            return false;
        };

        return obj;
    });

    container.define("env", ["mode", "user", "browser"], function (mode, user, browser) {
        var obj = {};

        obj.getMode = function () {
            return mode.getMode();
        };

        obj.getAid = function () {
            if (GM_info.addon && GM_info.addon.id) {
                return GM_info.addon.id;
            }
            else if (GM_info.scriptHandler) {
                return GM_info.scriptHandler.toLowerCase();
            }
            else {
                return "unknown";
            }
        };

        obj.getUid = function () {
            return user.getUid();
        };

        obj.getVersion = function () {
            if (injectInfo.enable) {
                return injectInfo.version;
            }
            else {
                return GM_info.script.version;
            }
        };

        obj.getBrowser = function () {
            return browser.getBrowser();
        };

        obj.getInfo = function () {
            return {
                mode: obj.getMode(),
                aid: obj.getAid(),
                uid: obj.getUid(),
                version: obj.getVersion(),
                browser: obj.getBrowser()
            };
        };

        return obj;
    });

    container.define("http", [], function () {
        var obj = {};

        obj.ajax = function (option) {
            var details = {
                method: option.type,
                url: option.url,
                responseType: option.dataType,
                onload: function (result) {
                    option.success && option.success(result.response);
                },
                onerror: function (result) {
                    option.error && option.error(result.error);
                }
            };

            // 提交数据
            if (option.data) {
                if (option.data instanceof FormData) {
                    details.data = option.data;
                }
                else {
                    var formData = new FormData();
                    for (var i in option.data) {
                        formData.append(i, option.data[i]);
                    }
                    details.data = formData;
                }
            }

            // 自定义头
            if (option.headers) {
                details.headers = option.headers;
            }

            // 超时
            if (option.timeout) {
                details.timeout = option.timeout;
            }

            GM_xmlhttpRequest(details);
        };

        return obj;
    });

    container.define("router", [], function () {
        var obj = {};

        obj.goUrl = function (url) {
            obj.eval('location.href = "' + url + '";');
        };

        obj.openUrl = function (url) {
            obj.eval('window.open("' + url + '");');
        };

        obj.openTab = function (url, active) {
            GM_openInTab(url, !active);
        };

        obj.eval = function (script) {
            var node = document.createElementNS(document.lookupNamespaceURI(null) || "http://www.w3.org/1999/xhtml", "script");
            node.textContent = script;
            (document.head || document.body || document.documentElement || document).appendChild(node);
            node.parentNode.removeChild(node)
        };

        return obj;
    });

    container.define("logger", ["env", "constant"], function (env, constant) {
        var obj = {
            level: 3,
            constant: {
                debug: 0,
                info: 1,
                warn: 2,
                error: 3
            }
        };

        obj.debug = function (message) {
            obj.log(message, obj.constant.debug);
        };

        obj.info = function (message) {
            obj.log(message, obj.constant.info);
        };

        obj.warn = function (message) {
            obj.log(message, obj.constant.warn);
        };

        obj.error = function (message) {
            obj.log(message, obj.constant.error);
        };

        obj.log = function (message, level) {
            if (level < obj.level) {
                return false;
            }

            console.group("[" + constant.name + "]" + env.getMode());
            switch (level) {
                case obj.constant.debug:
                    console.log(message);
                    break;
                case obj.constant.info:
                    console.info(message);
                    break;
                case obj.constant.warn:
                    console.warn(message);
                    break;
                case obj.constant.error:
                    console.error(message);
                    break;
                default:
                    console.log(message);
                    break;
            }
            console.groupEnd();
        };

        obj.setLevel = function (level) {
            obj.level = level;
        };

        return obj;
    });

    container.define("meta", ["constant", "$"], function (constant, $) {
        var obj = {};

        obj.existMeta = function (name) {
            name = obj.processName(name);
            if ($("meta[name='" + name + "']").length) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.appendMeta = function (name, content) {
            name = obj.processName(name);
            content || (content = "on");
            $('<meta name="' + name + '" content="on">').appendTo($("head"));
        };

        obj.processName = function (name) {
            return constant.name + "::" + name;
        };

        return obj;
    });

    container.define("calendar", ["object"], function (object) {
        var obj = {};

        obj.formatTime = function (timestamp, format) {
            timestamp || (timestamp = (new Date()).getTime());
            format || (format = "Y-m-d H:i:s");
            var date = new Date(timestamp);
            var year = 1900 + date.getYear();
            var month = "0" + (date.getMonth() + 1);
            var day = "0" + date.getDate();
            var hour = "0" + date.getHours();
            var minute = "0" + date.getMinutes();
            var second = "0" + date.getSeconds();
            var vars = {
                "Y": year,
                "m": month.substring(month.length - 2, month.length),
                "d": day.substring(day.length - 2, day.length),
                "H": hour.substring(hour.length - 2, hour.length),
                "i": minute.substring(minute.length - 2, minute.length),
                "s": second.substring(second.length - 2, second.length)
            };
            return obj.replaceVars(vars, format);
        };

        obj.replaceVars = function (vars, value) {
            object.keys(vars).forEach(function (key) {
                value = value.replace(key, vars[key]);
            });
            return value;
        };

        return obj;
    });

    /** custom start **/
    container.define("constant", ["mode", "browser"], function (mode, browser) {
        return {
            name: "yhg",
            mode: mode.constant,
            browser: browser.constant,
            option: {
                chart_scale: {
                    name: "chart_scale",
                    value: "yes"
                },
                chart_point: {
                    name: "chart_point",
                    value: "yes"
                },
                chart_zoom: {
                    name: "chart_zoom",
                    value: "no"
                },
                taobao_detail: {
                    name: "taobao",
                    value: "yes"
                },
                taobao_coupon: {
                    name: "taobao_coupon",
                    value: "yes"
                },
                taobao_search: {
                    name: "taobao_search",
                    value: "yes"
                },
                taobao_shop: {
                    name: "taobao_shop",
                    value: "yes"
                },
                taobao_other: {
                    name: "taobao_other",
                    value: "no"
                },
                jd_detail: {
                    name: "jd",
                    value: "yes"
                },
                kaola_detail: {
                    name: "kaola",
                    value: "yes"
                },
                yanxuan_detail: {
                    name: "yanxuan",
                    value: "yes"
                },
                yhd_detail: {
                    name: "yhd",
                    value: "yes"
                },
                amazon_detail: {
                    name: "amazon",
                    value: "yes"
                },
                suning_detail: {
                    name: "suning",
                    value: "yes"
                },
                dangdang_detail: {
                    name: "dangdang",
                    value: "yes"
                },
                guomei_detail: {
                    name: "guomei",
                    value: "yes"
                },
                vip_detail: {
                    name: "vip",
                    value: "no"
                }
            },
            site: {
                taobao: "taobao",
                jd: "jd",
                kaola: "kaola",
                guomei: "guomei",
                yanxuan: "yanxuan",
                yhd: "yhd",
                amazon: "amazon",
                suning: "suning",
                dangdang: "dangdang",
                vip: "vip",
                newday: "newday"
            },
            router: {
                home: "http://tb.newday.me",
                option: "http://tb.newday.me/script/option.html"
            }
        };
    });

    container.define("resource", [], function () {
        var obj = {};

        obj.getText = function (name) {
            if (name == "style") {
                return obj.getStyleText();
            }
            else {
                return null;
            }
        };

        obj.getStyleText = function () {
            return `#tb-cool-area{border:1px solid #eee;margin:0 auto;position:relative;clear:both;display:none}#tb-cool-area .tb-cool-area-home{position:absolute;top:5px;right:10px;z-index:10000}#tb-cool-area .tb-cool-area-home a{color:#515858;font-size:10px;text-decoration:none}#tb-cool-area .tb-cool-area-home a.new-version{color:#ff0036}#tb-cool-area .tb-cool-area-benefit{width:240px;float:left}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-qrcode{text-align:center;min-height:150px;margin-top:40px}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-qrcode canvas,#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-qrcode img{margin:0 auto}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-title{margin-top:20px;color:#000;font-size:14px;font-weight:700;text-align:center}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-title span{color:#ff0036;font-weight:700}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-action{margin-top:10px;text-align:center}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-action a{text-decoration:none}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-action .tb-cool-quan-button{min-width:120px;padding:0 8px;line-height:35px;color:#fff;background:#ff0036;font-size:13px;font-weight:700;letter-spacing:1.5px;margin:0 auto;text-align:center;border-radius:15px;display:inline-block;cursor:pointer}#tb-cool-area .tb-cool-area-benefit .tb-cool-quan-action .tb-cool-quan-button.quan-none{color:#000;background:#bec5c5}#tb-cool-area .tb-cool-area-history{height:300px;overflow:hidden;position:relative}#tb-cool-area .tb-cool-area-history #tb-cool-area-chart,#tb-cool-area .tb-cool-area-history .tb-cool-area-container{width:100%;height:100%}#tb-cool-area .tb-cool-area-history .tb-cool-history-tip{position:absolute;margin:0;top:50%;left:50%;letter-spacing:1px;font-size:15px;transform:translateX(-50%) translateY(-50%)}#tb-cool-area .tb-cool-area-table{margin-top:10px;position:relative;overflow:hidden}#tb-cool-area .tb-cool-quan-tip{position:absolute;margin:0;top:50%;left:50%;letter-spacing:1px;font-size:15px;opacity:0;transform:translateX(-50%) translateY(-50%)}#tb-cool-area .tb-cool-quan-tip a{color:#333;font-weight:400;text-decoration:none}#tb-cool-area .tb-cool-quan-tip a:hover{color:#ff0036}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table{width:100%;font-size:14px;text-align:center}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table tr td{padding:4px;color:#1c2323;border-top:1px solid #eee;border-left:1px solid #eee}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table tr td span{color:#ff0036;font-weight:700}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table tr td:first-child{border-left:none}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table .tb-cool-quan-link{width:60px;line-height:24px;font-size:12px;background:#ff0036;text-decoration:none;display:inline-block}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table .tb-cool-quan-link-enable{cursor:pointer;color:#fff}#tb-cool-area .tb-cool-area-table .tb-cool-quan-table .tb-cool-quan-link-disable{cursor:default;color:#000;background:#ccc}#tb-cool-area .tb-cool-quan-empty .tb-cool-quan-tip{opacity:1}#tb-cool-area .tb-cool-quan-empty .tb-cool-quan-table{filter:blur(3px);-webkit-filter:blur(3px);-moz-filter:blur(3px);-ms-filter:blur(3px)}.tb-cool-box-area{position:absolute;top:10px;left:5px;z-index:9999}.tb-cool-box-wait{cursor:pointer}.tb-cool-box-already{position:relative}.tb-cool-box-info{width:auto!important;height:auto!important;padding:6px 8px!important;font-size:12px;color:#fff!important;border-radius:15px;cursor:pointer;text-decoration:none!important}.tb-cool-box-info:hover{text-decoration:none!important}.tb-cool-box-info:visited{text-decoration:none!important}.tb-cool-box-info-default{background:#3186fd!important}.tb-cool-box-info-find{background:#ff0036!important}.tb-cool-box-info-empty{color:#000!important;background:#ccc!important}.tb-cool-box-info-translucent{opacity:.33}.mui-zebra-module .tb-cool-box-info{font-size:10px}.zebra-ziying-qianggou .tb-cool-box-area{right:10px;left:auto}.import-shangou-itemcell .tb-cool-box-area{right:10px;left:auto}.item_s_cpb .tb-cool-box-area{top:auto;bottom:10px}.j-mdv-chaoshi .m-floor .tb-cool-box-area a{width:auto;height:auto}.left-wider .proinfo-main{margin-bottom:40px}.detailHd .m-info{margin-bottom:20px}.tb-cool-quan-date{color: #233b3d;font-weight: normal;font-size: 12px;} .tb-cool-area-has-date .tb-cool-quan-qrcode{margin-top: 30px !important;} .tb-cool-area-has-date .tb-cool-quan-title{margin-top: 10px !important;}`;
        };

        return obj;
    });

    container.define("api", ["http", "env", "snap"], function (http, env, snap) {
        var obj = {
            base: "https://api.newday.me"
        };

        obj.versionQuery = function (callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/taobao/tool/version",
                dataType: "json",
                data: {
                    uid: env.getUid(),
                    aid: env.getAid(),
                    version: env.getVersion(),
                    browser: env.getBrowser(),
                    mode: env.getMode()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.itemQuery = function (url, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/taobao/tool/query",
                dataType: "json",
                data: {
                    item_url: url,
                    uid: env.getUid(),
                    aid: env.getAid(),
                    version: env.getVersion(),
                    browser: env.getBrowser(),
                    mode: env.getMode()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.basicQuery = function (itemId, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/taobao/tool/basic",
                dataType: "json",
                data: {
                    item_id: itemId,
                    source: "taobao",
                    uid: env.getUid(),
                    aid: env.getAid(),
                    version: env.getVersion(),
                    browser: env.getBrowser(),
                    mode: env.getMode()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.trendQuery = function (url, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/taobao/tool/trend",
                dataType: "json",
                data: {
                    item_url: url,
                    item_point: obj.getStrPoint(url),
                    uid: env.getUid(),
                    aid: env.getAid(),
                    version: env.getVersion(),
                    browser: env.getBrowser(),
                    mode: env.getMode()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.logOption = function (option, callback) {
            http.ajax({
                type: "post",
                url: obj.base + "/taobao/tool/option",
                dataType: "json",
                data: {
                    option_json: JSON.stringify(option),
                    uid: env.getUid(),
                    aid: env.getAid(),
                    version: env.getVersion(),
                    browser: env.getBrowser(),
                    mode: env.getMode()
                },
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.couponQueryShop = function (itemId, shopId, callback) {
            http.ajax({
                type: "get",
                url: "https://cart.taobao.com/json/GetPriceVolume.do?sellerId=" + shopId,
                dataType: "json",
                success: function (response) {
                    callback && callback(response);
                },
                error: function (error) {
                    callback && callback("");
                }
            });
        };

        obj.getStrPoint = function (str) {
            if (str.length < 2) {
                return "0:0";
            }

            var path = "";
            var current, last = str[0].charCodeAt();
            var sum = last;
            for (var i = 1; i < str.length; i++) {
                current = str[i].charCodeAt();
                if (i == 1) {
                    path = path + "M";
                } else {
                    path = path + " L";
                }
                path = path + current + " " + last;
                last = current;
                sum = sum + current;
            }
            path = path + " Z";
            var index = sum % str.length;
            var data = snap.path.getPointAtLength(path, str[index].charCodeAt());
            return data.m.x + ":" + data.n.y;
        };

        return obj;
    });

    container.define("updater", ["config", "env", "calendar", "api"], function (config, env, calendar, api) {
        var obj = {};

        obj.getLatest = function () {
            var versionLatest = config.getConfig("version_latest");
            if (versionLatest) {
                return versionLatest;
            }
            else {
                return env.getVersion();
            }
        };

        obj.init = function () {
            var versionDate = config.getConfig("version_date");
            var currentDate = calendar.formatTime(null, "Ymd");
            if (!versionDate || versionDate < currentDate) {
                api.versionQuery(function (response) {
                    config.setConfig("version_date", currentDate);
                    if (response && response.code == 1) {
                        config.setConfig("dialog", response.data.dialog);
                        config.setConfig("version_latest", response.data.version);
                    }
                });
            }
        };

        return obj;
    });

    container.define("core", ["config", "env", "router", "constant", "resource", "updater", "$"], function (config, env, router, constant, resource, updater, $) {
        var obj = {};

        obj.appendStyle = function () {
            var styleText = resource.getText("style");
            $("<style></style>").text(styleText).appendTo($("head"));
        };

        obj.jumpLink = function (jumpUrl, jumpMode) {
            switch (jumpMode) {
                case 9:
                    // self
                    router.goUrl(jumpUrl);
                    break;
                case 6:
                    // new
                    router.openUrl(jumpUrl);
                    break;
                case 3:
                    // new & not active
                    router.openTab(jumpUrl, false);
                    break;
                case 1:
                    // new & active
                    router.openTab(jumpUrl, true);
                    break;
            }
        };

        obj.jumpCouponLink = function (jumpUrl, jumpMode) {
            var callback = function () {
                obj.jumpLink(jumpUrl, jumpMode);
            };
            if (!window.layer || env.getMode() == constant.mode.script) {
                callback();
            }
            else if (env.getBrowser() != constant.browser.se360 || config.getConfig("dialog") == 0) {
                callback();
            }
            else if (config.getConfig("remember")) {
                callback();
            }
            else {
                layer.open({
                    type: 1,
                    title: false,
                    closeBtn: false,
                    area: "400px",
                    shade: 0.8,
                    id: "nd-coupon-dialog",
                    btn: ["同意跳转", "还是算了"],
                    btnAlign: "c",
                    zIndex: 199999999,
                    content: '<div style="padding: 30px 50px 20px 50px; line-height: 30px; background-color: #008a98; font-size: 13px; color: #fff; text-align: center;">即将跳转到淘宝客链接领取优惠券...<br/>只是去领取优惠券,对购物没有任何影响哦!<br/><input class="nd-ignore-dialog" type="checkbox" style="vertical-align: middle;"> <span>不再提示</span></div>'
                    , success: function (layero) {
                        var $checkbox = layero.find(".nd-ignore-dialog");
                        var $buttonYes = layero.find(".layui-layer-btn0");
                        $buttonYes.on("click", function () {
                            if ($checkbox.prop("checked")) {
                                config.setConfig("remember", "yes");
                            }
                            setTimeout(callback, 500);
                        });
                    }
                });
            }
        };

        obj.openOptionPage = function () {
            if (injectInfo.enable) {
                if (env.getMode() == constant.mode.addon) {
                    router.openTab(injectInfo.router_addon.option, true);
                }
                else {
                    router.openTab(injectInfo.router_script.option, true);
                }
            }
            else if (GM_info.addon && GM_info.addon.options_page) {
                router.openTab(GM_info.addon.options_page, true);
            }
            else {
                router.openTab(constant.router.option, true);
            }
        };

        obj.initVersion = function () {
            updater.init();
        };

        obj.ready = function (callback) {
            obj.initVersion();

            callback && callback();
        };

        return obj;
    });

    /** app start **/
    container.define("app_detail", ["runtime", "object", "option", "env", "logger", "calendar", "constant", "core", "api", "echarts", "$"], function (runtime, object, option, env, logger, calendar, constant, core, api, echarts, $) {
        var obj = {
            trendData: null
        };

        obj.getSite = function () {
            return obj.matchSite(runtime.getUrl());
        };

        obj.getItemUrl = function () {
            return obj.matchItemUrl(runtime.getUrl());
        };

        obj.run = function () {
            var site = obj.getSite();
            switch (site) {
                case constant.site.taobao:
                    option.isOptionActive(option.constant.taobao_detail) && obj.initDetailTaoBao();
                    break;
                case constant.site.jd:
                    option.isOptionActive(option.constant.jd_detail) && obj.initDetailJd();
                    break;
                case constant.site.kaola:
                    option.isOptionActive(option.constant.kaola_detail) && obj.initDetailKaoLa();
                    break;
                case constant.site.yanxuan:
                    option.isOptionActive(option.constant.yanxuan_detail) && obj.initDetailYanXuan();
                    break;
                case constant.site.yhd:
                    option.isOptionActive(option.constant.yhd_detail) && obj.initDetailYhd();
                    break;
                case constant.site.suning:
                    option.isOptionActive(option.constant.suning_detail) && obj.initDetailSuNing();
                    break;
                case constant.site.amazon:
                    option.isOptionActive(option.constant.amazon_detail) && obj.initDetailAmazon();
                    break;
                case constant.site.dangdang:
                    option.isOptionActive(option.constant.dangdang_detail) && obj.initDetailDangDang();
                    break;
                case constant.site.guomei:
                    option.isOptionActive(option.constant.guomei_detail) && obj.initDetailGuoMei();
                    break;
                case constant.site.vip:
                    option.isOptionActive(option.constant.vip_detail) && obj.initDetailVip();
                    break;
                default:
                    return false;
            }
            return true;
        };

        obj.initDetailTaoBao = function () {
            if ($('#detail').length || $(".ju-wrapper").length) {
                var html = obj.getAppendHtml();
                if ($("#J_DetailMeta").length) {
                    $("#J_DetailMeta").append(html);
                } else {
                    $("#detail").append(html + "<br/>");
                }

                var onEmpty = function () {
                    obj.showText("打开淘宝扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailTaoBao();
                }, 1000);
            }
        };

        obj.initDetailJd = function () {
            if ($(".product-intro").length) {
                var html = obj.getAppendHtml();
                $(".product-intro").append(html);

                var onEmpty = function () {
                    obj.showText("打开京东扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailJd();
                }, 1000);
            }
        };

        obj.initDetailKaoLa = function () {
            if ($("#j-producthead").length) {
                var html = obj.getAppendHtml();
                $("#j-producthead").after(html);

                var onEmpty = function () {
                    obj.showText("打开考拉扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailKaoLa();
                }, 1000);
            }
        };

        obj.initDetailYanXuan = function () {
            if ($(".detailHd").length) {
                var html = obj.getAppendHtml();
                $(".detailHd").append(html);

                var onEmpty = function () {
                    obj.showText("打开严选扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailYanXuan();
                }, 1000);
            }
        };

        obj.initDetailYhd = function () {
            if ($(".fm_detail_one").length) {
                var html = obj.getAppendHtml();
                $(".fm_detail_one").append(html);

                var onEmpty = function () {
                    obj.showText("打开一号店扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailYhd();
                }, 1000);
            }
        };

        obj.initDetailSuNing = function () {
            if ($(".proinfo-container").length) {
                var html = obj.getAppendHtml();
                $(".proinfo-container").append(html);

                var onEmpty = function () {
                    obj.showText("打开苏宁扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailSuNing();
                }, 1000);
            }
        };

        obj.initDetailAmazon = function () {
            if ($("#centerCol").length) {
                var html = obj.getAppendHtml();
                $("#centerCol").after(html);

                var onEmpty = function () {
                    obj.showText("手机扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailAmazon();
                }, 1000);
            }
        };

        obj.initDetailDangDang = function () {
            if ($(".product_main").length) {
                var html = obj.getAppendHtml();
                $(".product_main").append(html);

                var onEmpty = function () {
                    obj.showText("打开当当扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailDangDang();
                }, 1000);
            }
        };

        obj.initDetailGuoMei = function () {
            if ($(".gome-container").length) {
                var html = obj.getAppendHtml();
                $(".gome-container").append(html);

                var onEmpty = function () {
                    obj.showText("打开国美扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailGuoMei();
                }, 1000);
            }
        };

        obj.initDetailVip = function () {
            if ($(".FW-product").length) {
                var html = obj.getAppendHtml();
                $(".FW-product").append(html);

                var onEmpty = function () {
                    obj.showText("打开唯品会扫一扫");
                };
                obj.initDetail(onEmpty);
            } else {
                setTimeout(function () {
                    obj.initDetailVip();
                }, 1000);
            }
        };

        obj.initDetail = function (onEmpty) {
            // 版本信息
            obj.showVersion();

            // 注册事件
            var site = obj.getSite();
            if (site == constant.site.amazon) {
                obj.initAmazonEvent();
            }

            // 商品查询
            api.itemQuery(runtime.getUrl(), function (response) {
                logger.debug(response);
                $("#tb-cool-area").show();

                if (response && response.code == 1) {
                    var data = response.data;

                    // 价格趋势
                    obj.showChart(data.good_url);

                    // 隐藏优惠券
                    if (data.coupon_money > 0) {
                        obj.showCoupon(data);
                    }
                    else {
                        onEmpty();
                    }

                    // 优惠券列表
                    if (obj.getSite() == constant.site.taobao && option.isOptionActive(option.constant.taobao_coupon)) {
                        obj.showCouponList(data.item_id, data.shop_id);
                    }

                    // 二维码
                    obj.showQrcode(data.app_url);
                }
                else {
                    var itemUrl = obj.getItemUrl();

                    // 价格趋势
                    obj.showChart(itemUrl);

                    // 无优惠券
                    onEmpty();

                    // 二维码
                    obj.showQrcode(itemUrl);
                }
            });
        };

        obj.initAmazonEvent = function () {
            $(window).resize(function () {
                obj.showChartRefresh();
            });
        };

        obj.openCouponLink = function (couponId, shopId) {
            var couponLink = obj.buildCouponLink(couponId, shopId);
            window.open(couponLink, "领取优惠券", "width=600,height=600,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no");
        };

        obj.showCoupon = function (data) {
            var html = "<p>券后价 <span>" + data.coupon_price.toFixed(2) + "</span> 元</p>";
            if (data.start_time && data.end_time) {
                html += "<p class=\"tb-cool-quan-date\">(" + data.start_time + " ~ " + data.end_time + ")</p>";

                $(".tb-cool-area-benefit").addClass("tb-cool-area-has-date");
            }
            $(".tb-cool-quan-title").html(html);

            html = '<a class="tb-cool-quan-button quan-exist" data-url="' + data.jump_url + '" data-mode="' + data.jump_mode + '">领' + data.coupon_money + '元优惠券</a>';
            $(".tb-cool-quan-action").html(html);

            $(".tb-cool-quan-button.quan-exist").each(function () {
                var $this = this;
                var jumpUrl = $($this).attr("data-url");
                var jumpMode = parseInt($($this).attr("data-mode"));
                $this.onclick = function () {
                    core.jumpCouponLink(jumpUrl, jumpMode);
                };
            });
        };

        obj.showQrcode = function (url) {
            var qr = qrcode(5, "M");
            qr.addData(url);
            qr.make();
            $(".tb-cool-quan-qrcode").html(qr.createImgTag(4, 2));
        };

        obj.showText = function (buttonText, infoText) {
            var infoTextArr = ["移动端<span>快捷</span>购买"];
            if (!infoText) {
                var index = (new Date()).valueOf() % infoTextArr.length;
                infoText = infoTextArr[index];
            }
            var infoHtml = "<p>" + infoText + "</p>";
            $(".tb-cool-quan-title").html(infoHtml);

            buttonText || (buttonText = "手机扫一扫");
            var buttonHtml = '<a class="tb-cool-quan-button quan-none">' + buttonText + '</a>';
            $(".tb-cool-quan-action").html(buttonHtml);
        };

        obj.showVersion = function () {
            var html = '<a class="nd-open-page-option" title="当前版本:' + env.getVersion() + '" href="javascript:;">[ 配置 ]</a>';
            $(".tb-cool-area-home").html(html);

            // 打开配置页
            $(".nd-open-page-option").each(function () {
                this.onclick = function () {
                    core.openOptionPage();
                };
            });
        };

        obj.showChart = function (itemUrl) {
            $(".tb-cool-history-tip").html("查询历史价格中...");

            api.trendQuery(itemUrl, function (response) {
                logger.debug(response);

                obj.trendData = obj.parseTrendResponse(response);
                obj.showChartRefresh();
            });
        };

        obj.showChartRefresh = function () {
            obj.showChartData(obj.trendData);
        };

        obj.showChartData = function (trendData) {
            if (trendData) {
                var option = obj.buildChartOption(trendData);
                $(".tb-cool-area-container").html('<div id="tb-cool-area-chart"></div>');
                echarts.init(document.getElementById("tb-cool-area-chart")).setOption(option);
                $(".tb-cool-history-tip").html("");
            }
            else {
                $(".tb-cool-history-tip").html("暂无商品历史价格信息");
            }
        };

        obj.showCouponList = function (itemId, shopId) {
            api.couponQueryShop(itemId, shopId, function (response) {
                var couponList;
                if (response) {
                    couponList = obj.parseCouponListShop(itemId, shopId, response);
                    obj.showCouponListLoginYes(couponList);
                }
                else {
                    couponList = obj.parseCouponListPadding();
                    obj.showCouponListLoginNo(couponList);
                }
            });
        };

        obj.showCouponListLoginYes = function (couponList) {
            obj.buildCouponListTable(couponList);
        };

        obj.showCouponListLoginNo = function (couponList) {
            obj.buildCouponListTable(couponList);

            var loginUrl = obj.buildLoginUrl();
            $(".tb-cool-quan-tip").html('<a href="' + loginUrl + '">登录后可以查看店铺优惠券哦</a>');
            $(".tb-cool-area-table").addClass("tb-cool-quan-empty");
        };

        obj.buildCouponListTable = function (couponList) {
            var list = object.values(couponList);
            var compare = function (a, b) {
                if (a.coupon_money == b.coupon_money) {
                    if (a.coupon_money_start > b.coupon_money_start) {
                        return 1;
                    } else if (a.coupon_money_start == b.coupon_money_start) {
                        return 0;
                    } else {
                        return -1;
                    }
                } else {
                    if (a.coupon_money > b.coupon_money) {
                        return 1;
                    } else if (a.coupon_money == b.coupon_money) {
                        return 0;
                    } else {
                        return -1;
                    }
                }
            };
            list.sort(compare);

            var html = "";
            list.forEach(function (item) {
                html += "<tr>";
                html += "<td>满 " + item.coupon_money_start + " 减 <span>" + item.coupon_money + "</span> 元</td>";
                var couponCommon;
                if (item.coupon_common == 1) {
                    couponCommon = "限定商品";
                } else if (item.coupon_common == 0) {
                    couponCommon = "<span>通用</span>";
                } else {
                    couponCommon = "--";
                }
                html += "<td> " + couponCommon + "</td>";
                html += "<td>" + item.coupon_start + " ~ <span>" + item.coupon_end + "</span></td>";
                html += "<td>已领 <span>" + item.coupon_num + "</span> 张</td>";
                if (item.coupon_receive) {
                    html += '<td><a class="tb-cool-quan-link tb-cool-quan-link-disable">已领取</a></td>';
                } else {
                    html += '<td><a class="tb-cool-quan-link tb-cool-quan-link-enable" data-shop="' + item.shop_id + '" data-coupon="' + item.coupon_id + '">领 取</a></td>';
                }
                html += "</tr>";
            });
            $(".tb-cool-quan-table").html(html);

            $(".tb-cool-quan-link-enable").each(function () {
                var $this = this;
                var couponId = $($this).attr("data-coupon");
                var shopId = $($this).attr("data-shop");
                $this.onclick = function () {
                    obj.openCouponLink(couponId, shopId);
                };
            });
        };

        obj.buildLoginUrl = function () {
            var itemUrl = obj.getItemUrl();
            return "https://login.tmall.com/?redirectURL=" + escape(itemUrl);
        };

        obj.buildCouponLink = function (couponId, shopId) {
            return "https://market.m.taobao.com/apps/aliyx/coupon/detail.html?wh_weex=true&activity_id=" + couponId + "&seller_id=" + shopId;
        };

        obj.buildChartOption = function (trendData) {
            logger.debug(trendData);

            var text = "历史低价:{red|¥" + parseFloat(trendData.stat.min_price).toFixed(2) + "} ( {red|" + trendData.stat.min_date + "} )";
            var chartOption = {
                title: {
                    left: "center",
                    subtext: text,
                    subtextStyle: {
                        color: "#000",
                        rich: {
                            red: {
                                color: "red"
                            }
                        }
                    }
                },
                tooltip: {
                    trigger: "axis",
                    axisPointer: {
                        type: "cross"
                    },
                    formatter: function (params) {
                        params = params[0];
                        var year = params.name.getFullYear();
                        var month = params.name.getMonth() + 1;
                        var day = params.name.getDate();
                        if (month < 10) {
                            month = "0" + month;
                        }
                        if (day < 10) {
                            day = "0" + day;
                        }
                        return "日期:" + year + "-" + month + "-" + day + "<br/>价格:¥" + params.value[1].toFixed(2);
                    }
                },
                grid: {
                    left: 0,
                    right: 20,
                    top: 50,
                    bottom: 10,
                    containLabel: true
                },
                xAxis: {
                    type: "time"
                },
                yAxis: {
                    type: "value"
                },
                series: [
                    {
                        type: "line",
                        step: "end",
                        data: trendData.data,
                        symbolSize: 3,
                        lineStyle: {
                            width: 1.5,
                            color: "#ed5700"
                        }
                    }
                ]
            };

            // 自动刻度
            if (option.isOptionActive(option.constant.chart_scale)) {
                var step = 10;
                var Ymin = Math.floor(trendData.stat.min_price * 0.9 / step) * step;
                var Ymax = Math.ceil(trendData.stat.max_price * 1.1 / step) * step;
                chartOption.yAxis.min = Ymin;
                chartOption.yAxis.max = Ymax;
            }

            // 标记极值
            if (option.isOptionActive(option.constant.chart_point)) {
                var series = chartOption.series[0];
                series.markPoint = {
                    data: [
                        {
                            value: trendData.stat.min_price,
                            coord: [trendData.stat.min_time, trendData.stat.min_price],
                            name: "最小值",
                            itemStyle: {
                                color: "green"
                            }
                        },
                        {
                            value: trendData.stat.max_price,
                            coord: [trendData.stat.max_time, trendData.stat.max_price],
                            name: "最大值",
                            itemStyle: {
                                color: "red"
                            }
                        }
                    ]
                };
            }

            // 自由缩放
            if (option.isOptionActive(option.constant.chart_zoom)) {
                chartOption.dataZoom = [
                    {
                        type: "inside",
                        start: 0,
                        end: 100
                    }
                ];
            }

            logger.debug(chartOption);
            return chartOption;
        };

        obj.parseTrendResponse = function (response) {
            if (response && response.code == 1 && response.data.list.length) {
                var list = response.data.list;

                var trendData = {
                    stat: {
                        min_price: 0,
                        min_time: null,
                        min_date: null,
                        max_price: 0,
                        max_time: null,
                        max_date: null
                    },
                    data: []
                };
                list.forEach(function (item, index) {
                    var price = Math.ceil(item.price);
                    var time = new Date(item.time * 1000);
                    var date = calendar.formatTime(item.time * 1000, "Y-m-d");

                    var point = {
                        name: time,
                        value: [
                            date,
                            price
                        ]
                    };
                    trendData.data.push(point);

                    if (trendData.stat.min_price == 0 || trendData.stat.min_price >= price) {
                        trendData.stat.min_price = price;
                        trendData.stat.min_time = time;
                        trendData.stat.min_date = date;
                    }

                    if (trendData.stat.max_price <= price) {
                        trendData.stat.max_price = price;
                        trendData.stat.max_time = time;
                        trendData.stat.max_date = date;
                    }
                });
                return trendData;
            }
            else {
                return null;
            }
        };

        obj.parseCouponListPadding = function () {
            return [
                {
                    shop_id: "",
                    coupon_receive: false,
                    coupon_num: 0,
                    coupon_id: "",
                    coupon_money: 10,
                    coupon_money_start: 20,
                    coupon_start: "2018-01-01",
                    coupon_end: "2018-12-12",
                    coupon_common: 0
                },
                {
                    shop_id: "",
                    coupon_receive: false,
                    coupon_num: 0,
                    coupon_id: "",
                    coupon_money: 20,
                    coupon_money_start: 40,
                    coupon_start: "2018-01-01",
                    coupon_end: "2018-12-12",
                    coupon_common: 1
                },
                {
                    shop_id: "",
                    coupon_receive: false,
                    coupon_num: 0,
                    coupon_id: "",
                    coupon_money: 40,
                    coupon_money_start: 80,
                    coupon_start: "2018-01-01",
                    coupon_end: "2018-12-12",
                    coupon_common: 0
                }
            ];
        };

        obj.parseCouponListShop = function (itemId, shopId, response) {
            var couponList = {};
            if (response && response.priceVolumes) {
                response.priceVolumes.forEach(function (item) {
                    var couponId = item.id;
                    var receive = item.status == "received";
                    if (couponList.hasOwnProperty(couponId)) {
                        couponList[couponId].coupon_receive = receive;
                        couponList[couponId].coupon_num = item.receivedAmount;
                    }
                    else {
                        var couponMoneyStart = item.condition.replace("满", "").split("减")[0];
                        var couponStart = item.timeRange.split("-")[0];
                        var couponEnd = item.timeRange.split("-")[1];
                        couponList[couponId] = {
                            shop_id: shopId,
                            coupon_receive: receive,
                            coupon_num: item.receivedAmount,
                            coupon_id: couponId,
                            coupon_money: parseFloat(item.price).toFixed(2),
                            coupon_money_start: parseFloat(couponMoneyStart).toFixed(2),
                            coupon_start: couponStart,
                            coupon_end: couponEnd,
                            coupon_common: -1
                        };
                    }
                });
            }
            return couponList;
        };

        obj.matchItemUrl = function (url) {
            var site = obj.matchSite(url);
            var itemId = runtime.getUrlParam("id");

            if (site == constant.site.taobao) {
                if (itemId) {
                    return "https://item.taobao.com/item.htm?id=" + itemId;
                } else {
                    return url;
                }
            }

            if (site == constant.site.yanxuan) {
                if (itemId) {
                    return "http://you.163.com/item/detail?id=" + itemId;
                } else {
                    return url;
                }
            }

            // 去除参数和哈希
            url = url.split("?")[0];
            url = url.split("#")[0];

            if (site == constant.site.guomei) {
                url = url.replace("https", "http");
                return url;
            }

            if (site == constant.site.vip) {
                url = url.replace("https", "http");
                url = url.replace("detail.vip.com", "www.vip.com");
                return url;
            }

            return url;
        };

        obj.matchSite = function (url) {
            // 淘宝
            if (url.indexOf("//item.taobao.com/item.htm") > 0 || url.indexOf("//detail.tmall.com/item.htm") > 0 || url.indexOf("//chaoshi.detail.tmall.com/item.htm") > 0 || url.indexOf("//detail.tmall.hk/hk/item.htm") > 0 || url.indexOf("//detail.liangxinyao.com/item.htm") > 0 || url.indexOf("//detail.yao.95095.com/item.htm") > 0) {
                return constant.site.taobao;
            }

            // 京东
            if (url.indexOf("item.jd.com") > 0 || url.indexOf("item.jd.hk") > 0) {
                return constant.site.jd;
            }

            // 考拉
            if (url.indexOf("goods.kaola.com") > 0) {
                return constant.site.kaola;
            }

            // 严选
            if (url.indexOf("you.163.com/item") > 0) {
                return constant.site.yanxuan;
            }

            // 一号店
            if (url.indexOf("item.yhd.com") > 0) {
                return constant.site.yhd;
            }

            // 苏宁
            if (url.indexOf("product.suning.com") > 0) {
                return constant.site.suning;
            }

            // 亚马逊
            if (url.indexOf("www.amazon.cn/dp") > 0 || url.indexOf("www.amazon.cn/gp") > 0) {
                return constant.site.amazon;
            }

            // 当当
            if (url.indexOf("product.dangdang.com") > 0) {
                return constant.site.dangdang;
            }

            // 国美
            if (url.indexOf("item.gome.com.cn") > 0) {
                return constant.site.guomei;
            }

            // 唯品会
            if (url.indexOf("detail.vip.com") > 0) {
                return constant.site.vip;
            }

            // 插件主页
            if (url.indexOf("tb.newday.me") > 0) {
                return constant.site.newday;
            }

            return null;
        };

        obj.getAppendHtml = function () {
            return `<div id="tb-cool-area">
                <div class="tb-cool-area-home"></div>
                <div class="tb-cool-area-benefit">
                    <div class="tb-cool-quan-qrcode"></div>
                    <div class="tb-cool-quan-title"></div>
                    <div class="tb-cool-quan-action"></div>
                </div>
                <div id="tb-cool-area-history" class="tb-cool-area-history">
                    <div class="tb-cool-area-container"></div>
                    <p class="tb-cool-history-tip"></p>
                </div>
                <div class="tb-cool-area-table">
                    <table class="tb-cool-quan-table"></table>
                    <p class="tb-cool-quan-tip"></p>
                </div>
            </div>`;
        };

        return obj;
    });

    container.define("app_search_taobao", ["runtime", "option"], function (runtime, option) {
        var obj = {};

        obj.matchSelectorList = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//s.taobao.com/search") > 0 || url.indexOf("//s.taobao.com/list") > 0) {
                // 搜索
                if (option.isOptionActive(option.constant.taobao_search)) {
                    selectorList.push(".items .item");
                }
            }
            else if (url.indexOf("//www.taobao.com/markets") > 0) {
                // 活动
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList = obj.matchSelectorListMarkets();
                }
            }
            else if (url.indexOf("//www.taobao.com") > 0) {
                // 首页
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".tbh-hotsale .item");
                }
            }
            else if (url.indexOf("//neiyi.taobao.com") > 0) {
                // 内衣
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".item-list li");
                }
            }
            else if (url.indexOf("//qiang.taobao.com") > 0) {
                // 淘抢购
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".qg-limit-list .qg-item");
                }
            }
            else if (url.indexOf("//ju.taobao.com") > 0) {
                // 聚划算
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".ju-wrapper li");
                }
            }
            else if (url.indexOf("//mei.taobao.com") > 0) {
                // 美妆
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".item-list .item-box li");
                    selectorList.push(".n-mei-category .J_pannel li");
                    selectorList.push(".J_dynamic .float-box");
                    selectorList.push(".item-list .J_ItemHover");
                    selectorList.push(".ju-box li");
                    selectorList.push(".spu-item .spu-img");
                }
            }
            else if (url.indexOf("//g.taobao.com") > 0) {
                // 全球购
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".items .item");
                }
            }
            else if (url.indexOf("//pei.taobao.com") > 0) {
                // 配件
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".module-wrap .item-box");
                }
            }
            else if (url.indexOf("//wujin.taobao.com") > 0) {
                // 五金
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".module-wrap .item-show");
                }
            }
            else {
                // 店铺
                if (option.isOptionActive(option.constant.taobao_shop)) {
                    selectorList.push("#J_ShopSearchResult .item");
                }
            }
            return selectorList;
        };

        // 市场
        obj.matchSelectorListMarkets = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//www.taobao.com/markets/nvzhuang/") > 0) {
                // 女装
                selectorList.push(".item-box li");
            }
            else if (url.indexOf("//www.taobao.com/markets/nanzhuang/") > 0) {
                // 男装
                selectorList.push(".module-wrap .shop_list");
            }
            else if (url.indexOf("//www.taobao.com/markets/xie/") > 0) {
                // 鞋靴
                selectorList.push(".item-box li");
            }
            else if (url.indexOf("//www.taobao.com/markets/xiangbao/") > 0) {
                // 箱包
                selectorList.push(".item-box li");
            }
            else if (url.indexOf("//www.taobao.com/markets/qbb/") > 0) {
                // 亲宝贝
                selectorList.push(".brand-items .brand-item");
            }
            else if (url.indexOf("//www.taobao.com/markets/3c/") > 0) {
                // 电场
                selectorList.push(".parttwo-ul li");
                selectorList.push(".pro-ul li");
            }
            else if (url.indexOf("//www.taobao.com/markets/amusement/") > 0) {
                // 乐器
                selectorList.push(".item-wrap .arrival-item");
                selectorList.push(".pz-list .pz-li");
            }
            else if (url.indexOf("//www.taobao.com/markets/acg/") > 0) {
                // 动漫
                selectorList.push(".item-pannel li");
            }
            else if (url.indexOf("//www.taobao.com/markets/bangong/") > 0) {
                // 办公
                selectorList.push(".module-wrap .qiang-item");
                selectorList.push(".module-wrap .item-show");
            }
            else if (url.indexOf("//www.taobao.com/markets/dingzhi/") > 0) {
                // 定制
                selectorList.push(".item-wrap .arrival-item");
                selectorList.push(".pz-list .pz-li");
            }
            else if (url.indexOf("//www.taobao.com/markets/wujin/") > 0) {
                // 五金
                selectorList.push(".module-wrap .item-show");
            }
            else if (url.indexOf("//www.taobao.com/markets/promotion/") > 0) {
                // 家庭保障
                selectorList.push(".module-wrap .item");
            }
            else {
                selectorList.push(".module-wrap .item");
                selectorList.push(".module-wrap .shop_list");
                selectorList.push(".module-wrap .item-show");
                selectorList.push(".item-box li");
                selectorList.push(".item-wrap .arrival-item");
                selectorList.push(".brand-items .brand-item");
            }
            return selectorList;
        };

        return obj;
    });

    container.define("app_search_tmall", ["runtime", "option"], function (runtime, option) {
        var obj = {};

        obj.matchSelectorList = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//list.tmall.com/search_product.htm") > 0) {
                // 搜索
                if (option.isOptionActive(option.constant.taobao_search)) {
                    selectorList.push(".product");
                    selectorList.push(".chaoshi-recommend-list .chaoshi-recommend-item");
                }
            }
            else if (url.indexOf("//www.tmall.com/wow/") > 0) {
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList = obj.matchSelectorListWow();
                }
            }
            else if (url.indexOf("//pages.tmall.com") > 0 || url.indexOf("//618.tmall.com") > 0 || url.indexOf("//1111.tmall.com") > 0) {
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList = obj.matchSelectorListPages();
                }
            }
            else if (url.indexOf("//www.tmall.com") > 0) {
                // 首页
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".middle-column-con .one-grid-price");
                    selectorList.push(".wonderful-line .wonderful-item");
                }
            }
            else if (url.indexOf("//import.tmall.com") > 0) {
                // 天猫国际
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .item");
                }
            }
            else if (url.indexOf("//chaoshi.tmall.com") > 0) {
                // 天猫超市
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".list .j_ItemInfo");
                }
            }
            else if (url.indexOf("//3c.tmall.com") > 0) {
                // 天猫电器城
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .item");
                    selectorList.push(".itemlist .itemlist-mod");
                    selectorList.push(".floor-recommand .item");
                }
            }
            else if (url.indexOf("//miao.tmall.com") > 0) {
                // 天猫鲜生
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .j_ItemContainer li");
                }
            }
            else if (url.indexOf("//yao.tmall.com") > 0) {
                // 天猫医药馆
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".zebra-yao-indexItem li");
                    selectorList.push(".yao-qiangCon li");
                }
            }
            else if (url.indexOf("//wt.tmall.com") > 0) {
                // 天猫营业厅
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".J_ItemListWrap li");
                }
            }
            else if (url.indexOf("//suning.tmall.com") > 0) {
                // 苏宁易购
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".J_TModule .itemarea");
                    selectorList.push(".J_TModule .tb-module .jdb");
                    selectorList.push("#J_ShopSearchResult .item");
                }
            }
            else if (url.indexOf("//good.tmall.com") > 0) {
                // 天猫心选
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".J_TModule .item");
                }
            }
            else if (url.indexOf("//zhineng.tmall.com") > 0) {
                // 天猫精灵智能
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .item");
                }
            }
            else if (url.indexOf("//nvzhuang.tmall.com") > 0) {
                // 天猫女装
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .w-lev2-lit");
                }
            }
            else if (url.indexOf("//nvxie.tmall.com") > 0) {
                // 天猫女鞋
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".fushi-special-extra a");
                }
            }
            else if (url.indexOf("//bag.tmall.com") > 0) {
                // 天猫箱包
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .good");
                }
            }
            else if (url.indexOf("//watch.tmall.com") > 0) {
                // 天猫腕表
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .item");
                    selectorList.push(".mui-zebra-module li");
                }
            }
            else if (url.indexOf("//dai.tmall.com") > 0) {
                // 天猫珠宝饰品
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .good");
                }
            }
            else if (url.indexOf("//shouji.tmall.com") > 0) {
                // 天猫手机
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .mod-g");
                }
            }
            else if (url.indexOf("//baby.tmall.com") > 0) {
                // 天猫母婴
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .fl-camps");
                }
            }
            else if (url.indexOf("//food.tmall.com") > 0) {
                // 天猫零食
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .item_s_cpa");
                    selectorList.push(".mui-zebra-module .item_s_cpb");
                }
            }
            else if (url.indexOf("//jia.tmall.com") > 0) {
                // 天猫家装
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".item-panel .item");
                }
            }
            else if (url.indexOf("//car.tmall.com") > 0) {
                // 天猫汽车
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .col");
                }
            }
            else if (url.indexOf("//book.tmall.com") > 0) {
                // 天猫图书
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .product a");
                }
            }
            else if (url.indexOf("//new3c.tmall.com") > 0) {
                // 天猫新首发
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".xpkw-container .xpkw-item");
                }
            }
            else if (url.indexOf("//ku.tmall.com") > 0) {
                // 酷玩街
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".new-recommend-content .new-recommend-block");
                    selectorList.push(".all-goods .goods_block");
                }
            }
            else if (url.indexOf("//fenqi.tmall.com") > 0) {
                // 花呗分期
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module .mod-g");
                }
            }
            else if (url.indexOf("//content.tmall.com") > 0) {
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".mui-zebra-module li");
                    selectorList.push(".mui-zebra-module .juitem");
                }
            }
            else {
                // 店铺
                if (option.isOptionActive(option.constant.taobao_shop)) {
                    selectorList.push("#J_ShopSearchResult .item");
                }
            }
            return selectorList;
        };

        obj.matchSelectorListWow = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//www.tmall.com/wow/chaoshi/") > 0) {
                selectorList.push(".mui-chaoshi-item-column");
            }
            else if (url.indexOf("//www.tmall.com/wow/fushi/") > 0) {
                selectorList.push(".mui-zebra-module li");
                selectorList.push(".popular-list .popular-item");
            }
            else {
                selectorList.push(".mui-zebra-module li");
                selectorList.push(".mui-zebra-module .item");
                selectorList.push(".popular-list .popular-item");
            }
            return selectorList;
        };

        obj.matchSelectorListPages = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//pages.tmall.com/wow/import") > 0) {
                selectorList.push(".cell-square");
                selectorList.push(".gwtg-col-item");
            }
            else if (url.indexOf("//pages.tmall.com/wow/chaoshi/") > 0) {
                selectorList.push(".mui-chaoshi-item-column");
            }
            else {
                selectorList.push(".mui-zebra-module li");
                selectorList.push(".mui-zebra-module .item-link");
                selectorList.push(".mui-zebra-module .hot-item");
                selectorList.push(".zebra-recommand-item-container .wrapper");
            }
            return selectorList;
        };

        return obj;
    });

    container.define("app_search_tmall_hk", ["runtime", "option"], function (runtime, option) {
        var obj = {};

        obj.matchSelectorList = function () {
            var url = runtime.getUrl();
            var selectorList = [];
            if (url.indexOf("//list.tmall.hk/search_product.htm") > 0) {
                if (option.isOptionActive(option.constant.taobao_search)) {
                    selectorList.push("#J_ItemList .product");
                }
            }
            else if (url.indexOf("//www.tmall.hk") > 0) {
                if (option.isOptionActive(option.constant.taobao_other)) {
                    selectorList.push(".item-panel .item");
                    selectorList.push(".mui-zebra-module .import-shangou-itemcell");
                }
            }
            else {
                if (option.isOptionActive(option.constant.taobao_shop)) {
                    selectorList.push("#J_ShopSearchResult .item");
                }
            }
            return selectorList;
        };

        return obj;
    });

    container.define("app_search", ["runtime", "option", "api", "$"], function (runtime, option, api, $, require) {
        var obj = {};

        obj.run = function () {
            if (option.isOptionActive(option.constant.taobao_search)) {
                var url = runtime.getUrl();
                var selectorList = [];
                if (url.indexOf("taobao.com") > 0) {
                    selectorList = require("app_search_taobao").matchSelectorList();
                }
                else if (url.indexOf("tmall.com") > 0) {
                    selectorList = require("app_search_tmall").matchSelectorList();
                }
                else if (url.indexOf("tmall.hk") > 0) {
                    selectorList = require("app_search_tmall_hk").matchSelectorList();
                }
                else if (url.indexOf("//maiyao.liangxinyao.com/shop") > 0 || url.indexOf("//maiyao.liangxinyao.com/category") > 0) {
                    if (option.isOptionActive(option.constant.taobao_shop)) {
                        selectorList.push("#J_ShopSearchResult .item");
                    }
                }
                else if (url.indexOf("//www.liangxinyao.com") > 0 || url.indexOf("//maiyao.liangxinyao.com") > 0) {
                    if (option.isOptionActive(option.constant.taobao_other)) {
                        selectorList.push(".mui-zebra-module .item");
                        selectorList.push(".zebra-ziying-qianggou li");
                    }
                }
                else {
                    if (option.isOptionActive(option.constant.taobao_shop)) {
                        selectorList.push("#J_ShopSearchResult .item");
                    }
                }

                if (selectorList && selectorList.length > 0) {
                    obj.initSearchHtml(selectorList);
                    obj.initSearchEvent();
                    obj.basicQuery();
                }
            }
        };

        obj.initSearchHtml = function (selectorList) {
            setInterval(function () {
                selectorList.forEach(function (selector) {
                    obj.initSearchItemSelector(selector);
                });
            }, 3000);
        };

        obj.initSearchEvent = function () {
            $(document).on("click", ".tb-cool-box-area", function () {
                var $this = $(this);
                if ($this.hasClass("tb-cool-box-wait")) {
                    obj.basicQueryItem(this);
                } else if ($this.hasClass("tb-cool-box-info-translucent")) {
                    $this.removeClass("tb-cool-box-info-translucent");
                } else {
                    $this.addClass("tb-cool-box-info-translucent");
                }
            });
        };

        obj.basicQuery = function () {
            setInterval(function () {
                $(".tb-cool-box-wait").each(function () {
                    obj.basicQueryItem(this);
                });
            }, 3000);
        };

        obj.initSearchItemSelector = function (selector) {
            $(selector).each(function () {
                obj.initSearchItem(this);
            });
        };

        obj.initSearchItem = function (selector) {
            var $this = $(selector);
            if ($this.hasClass("tb-cool-box-already")) {
                return;
            } else {
                $this.addClass("tb-cool-box-already")
            }

            var nid = $this.attr("data-id");
            if (!obj.isVailidItemId(nid)) {
                nid = $this.attr("data-itemid");
            }

            if (!obj.isVailidItemId(nid)) {
                if ($this.attr("href")) {
                    nid = location.protocol + $this.attr("href");
                } else {
                    var $a = $this.find("a");
                    if (!$a.length) {
                        return;
                    }

                    nid = $a.attr("data-nid");
                    if (!obj.isVailidItemId(nid)) {
                        if ($a.hasClass("j_ReceiveCoupon") && $a.length > 1) {
                            nid = location.protocol + $($a[1]).attr("href");
                        } else {
                            nid = location.protocol + $a.attr("href");
                        }
                    }
                }
            }

            if (obj.isValidNid(nid)) {
                obj.appenBasicQueryHtml($this, nid);
            }
        };

        obj.appenBasicQueryHtml = function (selector, nid) {
            selector.append('<div class="tb-cool-box-area tb-cool-box-wait" data-nid="' + nid + '"><a class="tb-cool-box-info tb-cool-box-info-default" title="点击查询">待查询</a></div>');
        };

        obj.basicQueryItem = function (selector) {
            var $this = $(selector);
            $this.removeClass("tb-cool-box-wait");

            var nid = $this.attr("data-nid");
            api.basicQuery(nid, function (response) {
                if (response && response.code == 1) {
                    var data = response.data;
                    if (data.coupon_money > 0) {
                        obj.showBasicQueryFind($this, data.item_id, data.item_price_buy, data.coupon_money);
                    } else {
                        obj.showBasicQueryEmpty($this);
                    }
                } else {
                    obj.showBasicQueryEmpty($this);
                }
            });
        };

        obj.showBasicQueryFind = function (selector, itemId, itemPriceBuy, couponMoney) {
            selector.html('<a target="_blank" class="tb-cool-box-info tb-cool-box-info-find" title="切换透明度">券后 ' + itemPriceBuy + '(减' + couponMoney + '元)</a>');
        };

        obj.showBasicQueryEmpty = function (selector) {
            selector.addClass("tb-cool-box-info-translucent");
            selector.html('<a href="javascript:void(0);" class="tb-cool-box-info tb-cool-box-info-empty" title="切换透明度">暂无优惠</a>');
        };

        obj.isVailidItemId = function (itemId) {
            if (!itemId) {
                return false;
            }

            var itemIdInt = parseInt(itemId);
            if (itemIdInt == itemId && itemId > 10000) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.isValidNid = function (nid) {
            if (!nid) {
                return false;
            }
            else if (nid.indexOf('http') >= 0) {
                if (obj.isDetailPageTaoBao(nid) || nid.indexOf("//detail.ju.taobao.com/home.htm") > 0) {
                    return true;
                }
                else {
                    return false;
                }
            }
            else {
                return true;
            }
        };

        obj.isDetailPageTaoBao = function (url) {
            if (url.indexOf("//item.taobao.com/item.htm") > 0 || url.indexOf("//detail.tmall.com/item.htm") > 0 || url.indexOf("//chaoshi.detail.tmall.com/item.htm") > 0 || url.indexOf("//detail.tmall.hk/hk/item.htm") > 0 || url.indexOf("//detail.liangxinyao.com/item.htm") > 0 || url.indexOf("//detail.yao.95095.com/item.htm") > 0) {
                return true;
            } else {
                return false;
            }
        };

        return obj;
    });

    container.define("app_newday", ["option", "env", "api", "meta", "core", "$", "vue"], function (option, env, api, meta, core, $, vue) {
        var obj = {};

        obj.run = function () {
            if (meta.existMeta("info")) {
                obj.initInfoPage();
                return true;
            }
            else if (meta.existMeta("option")) {
                obj.initOptionPage();
                return true;
            }
            else if (meta.existMeta("dev")) {
                obj.initDevPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initInfoPage = function () {
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo()
                },
                mounted: function () {
                    obj.initAddonReady();
                }
            });
        };

        obj.initOptionPage = function () {
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo(),
                    option: option.getOption()
                },
                mounted: function () {
                    obj.initAddonReady();
                },
                watch: {
                    option: function (value) {
                        option.setOption(value);
                        api.logOption(value);
                    }
                }
            });
        };

        obj.initDevPage = function () {
            $("#dev-addon-info").val(JSON.stringify(env.getInfo()));

            $(".dev-open-page-option").addClass("nd-open-page-option").removeClass("dev-open-page-option");
            $(document).on("click", ".nd-open-page-option", function () {
                core.openOptionPage();
            });
        };

        obj.initAddonReady = function () {
            $("body").addClass("nd-addon-ready");
        };

        return obj;
    });

    container.define("app", ["runtime", "meta", "logger", "core", "$"], function (runtime, meta, logger, core, $, require) {
        var obj = {};

        obj.run = function () {
            var metaName = "status";
            if (meta.existMeta(metaName)) {
                logger.warn("setup already");
            }
            else {
                logger.info("setup success");

                // 当前链接
                var url = runtime.getUrl();
                logger.info(url);

                // 添加meta
                meta.appendMeta(metaName);

                // 添加style
                core.appendStyle();

                // 运行应用
                $(obj.runApp);
            }
        };

        obj.runApp = function () {
            var appList = [
                "app_detail",
                "app_newday",
                "app_search"
            ];
            for (var i in appList) {
                if (require(appList[i]).run() == true) {
                    break;
                }
            }
        };

        return obj;
    });

    // lib
    container.define("$", [], function () {
        return window.$;
    });
    container.define("snap", [], function () {
        if (typeof Snap != "undefined") {
            return Snap;
        }
        else {
            return window.Snap;
        }
    });
    container.define("vue", [], function () {
        return window.Vue;
    });
    container.define("echarts", [], function () {
        if (typeof echarts != "undefined") {
            return echarts;
        }
        else {
            return window.echarts;
        }
    });

    container.use(["core", "app", "logger"], function (core, app, logger) {

        // 日志级别
        logger.setLevel(logger.constant.info);

        core.ready(function () {
            app.run();
        });
    });
};

var appXzws = function () {
    'use strict';

    var injectInfo = {
        enable: true,
        name: "xzws",
        version: "0.1.3"
    };

    var container = (function () {
        var obj = {
            module_defines: {},
            module_objects: {}
        };

        obj.define = function (name, requires, callback) {
            name = obj.processName(name);
            obj.module_defines[name] = {
                requires: requires,
                callback: callback
            };
        };

        obj.require = function (name, cache) {
            if (typeof cache == "undefined") {
                cache = true;
            }

            name = obj.processName(name);
            if (cache && obj.module_objects.hasOwnProperty(name)) {
                return obj.module_objects[name];
            }
            else if (obj.module_defines.hasOwnProperty(name)) {
                var requires = obj.module_defines[name].requires;
                var callback = obj.module_defines[name].callback;

                var module = obj.use(requires, callback);
                cache && obj.register(name, module);
                return module;
            }
        };

        obj.use = function (requires, callback) {
            var module = {
                exports: {}
            };
            var params = obj.buildParams(requires, module);
            var result = callback.apply(this, params);
            if (typeof result != "undefined") {
                return result;
            }
            else {
                return module.exports;
            }
        };

        obj.register = function (name, module) {
            name = obj.processName(name);
            obj.module_objects[name] = module;
        };

        obj.buildParams = function (requires, module) {
            var params = [];
            requires.forEach(function (name) {
                params.push(obj.require(name));
            });
            params.push(obj.require);
            params.push(module.exports);
            params.push(module);
            return params;
        };

        obj.processName = function (name) {
            return name.toLowerCase();
        };

        return {
            define: obj.define,
            use: obj.use,
            register: obj.register,
            modules: obj.module_objects
        };
    })();

    container.define("runtime", [], function () {
        var obj = {
            url: location.href
        };

        obj.getUrl = function () {
            return obj.url;
        };

        obj.setUrl = function (url) {
            obj.url = url;
        };

        return obj;
    });

    container.define("object", [], function () {
        var obj = {};

        obj.keys = function (data) {
            var list = [];
            for (var key in data) {
                list.push(key);
            }
            return list;
        };

        obj.values = function (data) {
            var list = [];
            for (var key in data) {
                list.push(data[key]);
            }
            return list;
        };

        return obj;
    });

    container.define("storage", [], function () {
        var obj = {};

        obj.getValue = function (name, defaultValue) {
            name = obj.processName(name);
            return GM_getValue(name, defaultValue);
        };

        obj.setValue = function (name, value) {
            name = obj.processName(name);
            GM_setValue(name, value);
        };

        obj.getValueList = function () {
            var nameList = GM_listValues();
            var valueList = {};
            nameList.forEach(function (name) {
                if (injectInfo.enable) {
                    if (name.indexOf(injectInfo.name + "_") >= 0) {
                        name = name.replace(injectInfo.name + "_", "");
                        valueList[name] = obj.getValue(name);
                    }
                }
                else {
                    valueList[name] = obj.getValue(name);
                }
            });
            return valueList;
        };

        obj.processName = function (name) {
            if (injectInfo.enable) {
                return injectInfo.name + "_" + name;
            }
            else {
                return name;
            }
        };

        return obj;
    });

    container.define("config", ["storage"], function (storage) {
        var obj = {};

        obj.getConfig = function (name) {
            var configJson = storage.getValue("configJson");
            var configObject = obj.parseJson(configJson);
            if (name) {
                return configObject.hasOwnProperty(name) ? configObject[name] : null;
            }
            else {
                return configObject;
            }
        };

        obj.setConfig = function (name, value) {
            var configObject = obj.getConfig();
            configObject[name] = value;
            storage.setValue("configJson", JSON.stringify(configObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("http", [], function () {
        var obj = {};

        obj.ajax = function (option) {
            var details = {
                url: option.url,
                responseType: option.dataType,
                onload: function (result) {
                    option.success && option.success(result.response);
                },
                onerror: function (result) {
                    option.error && option.error(result.error);
                }
            };

            // 提交数据
            if (option.data) {
                details.method = "POST";
                if (option.data instanceof FormData) {
                    details.data = option.data;
                }
                else {
                    var formData = new FormData();
                    for (var i in option.data) {
                        formData.append(i, option.data[i]);
                    }
                    details.data = formData;
                }
            }
            else {
                details.method = "GET";
            }

            // 自定义头
            if (option.headers) {
                details.headers = option.headers;
            }

            // 超时
            if (option.timeout) {
                details.timeout = option.timeout;
            }

            GM_xmlhttpRequest(details);
        };

        return obj;
    });

    container.define("mode", [], function () {
        var obj = {
            constant: {
                addon: "addon",
                script: "script"
            }
        };

        obj.getMode = function () {
            if (typeof GM_info == "undefined") {
                return obj.constant.addon;
            }
            else if (GM_info.scriptHandler) {
                return obj.constant.script;
            }
            else {
                return obj.constant.addon;
            }
        };

        return obj;
    });

    container.define("env", ["mode"], function (mode) {
        var obj = {};

        obj.getMode = function () {
            return mode.getMode();
        };

        obj.getAid = function () {
            if (GM_info.addon && GM_info.addon.id) {
                return GM_info.addon.id;
            }
            else if (GM_info.scriptHandler) {
                return GM_info.scriptHandler.toLowerCase();
            }
            else {
                return "unknown";
            }
        };

        obj.getVersion = function () {
            if (injectInfo.enable) {
                return injectInfo.version;
            }
            else {
                return GM_info.script.version;
            }
        };

        obj.getInfo = function () {
            return {
                mode: obj.getMode(),
                aid: obj.getAid(),
                version: obj.getVersion()
            };
        };

        return obj;
    });

    container.define("option", ["storage", "constant", "object"], function (storage, constant, object) {
        var obj = {
            constant: constant.option
        };

        obj.isOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            return option.indexOf(name) >= 0 ? true : false;
        };

        obj.setOptionActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            if (option.indexOf(name) < 0) {
                option.push(name);
                obj.setOption(option);
            }
        };

        obj.setOptionUnActive = function (item) {
            var name = item.name;
            var option = obj.getOption();
            var index = option.indexOf(name);
            if (index >= 0) {
                delete option[index];
                obj.setOption(option);
            }
        };

        obj.getOption = function () {
            var option = [];
            var optionJson = storage.getValue("optionJson");
            var optionObject = obj.parseJson(optionJson);
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (optionObject.hasOwnProperty(name)) {
                    if (optionObject[name] != "no") {
                        option.push(name);
                    }
                }
                else if (item.value != "no") {
                    option.push(name);
                }
            });
            return option;
        };

        obj.setOption = function (option) {
            var optionObject = {};
            object.values(obj.constant).forEach(function (item) {
                var name = item.name;
                if (option.indexOf(name) >= 0) {
                    optionObject[name] = "yes";
                } else {
                    optionObject[name] = "no";
                }
            });
            storage.setValue("optionJson", JSON.stringify(optionObject));
        };

        obj.parseJson = function (jsonStr) {
            var jsonObject = {};
            try {
                if (jsonStr) {
                    jsonObject = JSON.parse(jsonStr);
                }
            }
            catch (e) { }
            return jsonObject;
        };

        return obj;
    });

    container.define("logger", ["env", "constant"], function (env, constant) {
        var obj = {
            level: 3,
            constant: {
                debug: 0,
                info: 1,
                warn: 2,
                error: 3
            }
        };

        obj.debug = function (message) {
            obj.log(message, obj.constant.debug);
        };

        obj.info = function (message) {
            obj.log(message, obj.constant.info);
        };

        obj.warn = function (message) {
            obj.log(message, obj.constant.warn);
        };

        obj.error = function (message) {
            obj.log(message, obj.constant.error);
        };

        obj.log = function (message, level) {
            if (level < obj.level) {
                return false;
            }

            console.group("[" + constant.name + "]" + env.getMode());
            switch (level) {
                case obj.constant.debug:
                    console.log(message);
                    break;
                case obj.constant.info:
                    console.info(message);
                    break;
                case obj.constant.warn:
                    console.warn(message);
                    break;
                case obj.constant.error:
                    console.error(message);
                    break;
                default:
                    console.log(message);
                    break;
            }
            console.groupEnd();
        };

        obj.setLevel = function (level) {
            obj.level = level;
        };

        return obj;
    });

    container.define("meta", ["constant", "$"], function (constant, $) {
        var obj = {};

        obj.existMeta = function (name) {
            name = obj.processName(name);
            if ($("meta[name='" + name + "']").length) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.appendMeta = function (name, content) {
            name = obj.processName(name);
            content || (content = "on");
            $('<meta name="' + name + '" content="on">').appendTo($("head"));
        };

        obj.processName = function (name) {
            return constant.name + "::" + name;
        };

        return obj;
    });

    /** custom start **/
    container.define("constant", [], function () {
        return {
            name: "xzws",
            option: {
                site_onlinedown: {
                    name: "site_onlinedown",
                    value: "yes"
                },
                site_cr173: {
                    name: "site_cr173",
                    value: "yes"
                },
                site_xiazaiba: {
                    name: "site_xiazaiba",
                    value: "yes"
                },
                site_mydown: {
                    name: "site_mydown",
                    value: "yes"
                },
                site_pc6: {
                    name: "site_pc6",
                    value: "yes"
                },
                site_zol: {
                    name: "site_zol",
                    value: "yes"
                },
                site_pconline: {
                    name: "site_pconline",
                    value: "yes"
                },
                site_jb51: {
                    name: "site_jb51",
                    value: "yes"
                },
                site_cncrk: {
                    name: "site_cncrk",
                    value: "yes"
                },
                site_pc_qq: {
                    name: "site_pc_qq",
                    value: "yes"
                },
                site_crsky: {
                    name: "site_crsky",
                    value: "yes"
                },
                site_duote: {
                    name: "site_duote",
                    value: "yes"
                },
                site_downza: {
                    name: "site_downza",
                    value: "yes"
                },
                site_yesky: {
                    name: "site_yesky",
                    value: "yes"
                },
                site_ddooo: {
                    name: "site_ddooo",
                    value: "yes"
                },
                site_pchome: {
                    name: "site_pchome",
                    value: "yes"
                },
                site_xpgod: {
                    name: "site_xpgod",
                    value: "yes"
                },
                site_52z: {
                    name: "site_52z",
                    value: "yes"
                },
                site_opdown: {
                    name: "site_opdown",
                    value: "yes"
                }
            }
        };
    });

    container.define("core", [], function () {
        var obj = {};

        obj.ready = function (callback) {
            callback && callback();
        };

        return obj;
    });

    // http://www.onlinedown.net/soft/5.htm
    container.define("app_onlinedown", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("onlinedown.net/soft") > 0) {
                option.isOptionActive(option.constant.site_onlinedown) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".onedownbtn2").hide();

            // 底部高速下载
            $($(".downDz h4").get(0)).hide();
            $(".downDz .gaosu").hide();

            // 移除弹窗
            $(".wxWp").remove();
        };

        return obj;
    });

    // https://www.cr173.com/soft/18645.html
    container.define("app_cr173", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("cr173.com/soft") > 0 || url.indexOf("cr173.com/game") > 0) {
                option.isOptionActive(option.constant.site_cr173) && obj.initSoftPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initSoftPage = function () {
            // 顶部高速下载
            $(".downnowgaosu").hide();

            // 底部高速下载
            $(".ul_Address").each(function () {
                if ($(this).find(".f-gsh3").length > 1) {
                    $($(this).find(".f-gsh3").get(0)).hide();
                }
            });
            $(".ul_Address .downurl").hide();
        };

        return obj;
    });

    // https://www.xiazaiba.com/html/82.html
    container.define("app_xiazaiba", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("xiazaiba.com/html") > 0) {
                option.isOptionActive(option.constant.site_xiazaiba) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".hspeed").hide();

            // 底部高速下载
            $(".needfast").parent().hide();
        };

        return obj;
    });

    // http://www.mydown.com/soft/421/472030921.shtml
    container.define("app_mydown", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("mydown.com/soft") > 0) {
                option.isOptionActive(option.constant.site_mydown) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 高速下载
            $(".downbtn").hide();
        };

        return obj;
    });

    // http://www.pc6.com/softview/SoftView_1822.html
    // http://www.pc6.com/mod/647389.html
    // http://www.pc6.com/az/254734.html
    container.define("app_pc6", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("pc6.com/softview") > 0) {
                option.isOptionActive(option.constant.site_pc6) && obj.initDownloadPageSoft();
                return true;
            }
            else if (url.indexOf("pc6.com/mod") > 0) {
                option.isOptionActive(option.constant.site_pc6) && obj.initDownloadPageSoft();
                return true;
            }
            else if (url.indexOf("pc6.com/az") > 0) {
                option.isOptionActive(option.constant.site_pc6) && obj.initDownloadPageAndroid();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPageSoft = function () {
            // 顶部高速下载
            $("#xzbtn .downnow").hide();

            // 底部高速下载
            $(".ul_Address").each(function () {
                if ($(this).find("h3").length > 1) {
                    $($(this).find("h3").get(0)).hide();
                }
            });
            $(".ul_Address #gaosuxiazai").hide();
        };

        obj.initDownloadPageAndroid = function () {
            $(".ul_Address").each(function () {
                if ($(this).find("h3").length > 1) {
                    $($(this).find("h3").get(0)).hide();
                }
            });
            $(".ul_Address #gaosuxiazai").hide();
        };

        return obj;
    });

    // http://xiazai.zol.com.cn/detail/9/89734.shtml
    // http://xiazai.zol.com.cn/index.php?c=Detail_DetailMini&n=e4bd1f21d0c761d05&softid=89734
    container.define("app_zol", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("zol.com.cn/detail") > 0) {
                option.isOptionActive(option.constant.site_zol) && obj.initDownloadPage();
                return true;
            }
            else if (url.indexOf("zol.com.cn/index.php") > 0) {
                option.isOptionActive(option.constant.site_zol) && obj.initDownloadPageMini();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".soft-text-l").hide();
            $(".soft-text-r").addClass("soft-text-l").removeClass("soft-text-r");

            // 底部高速下载
            $(".box-top-ad").hide();
        };

        obj.initDownloadPageMini = function () {
            $(".down-h4").parent().hide();
            $(".down-jisu").hide();
        };

        return obj;
    });

    // https://dl.pconline.com.cn/download/91034.html
    container.define("app_pconline", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("pconline.com.cn/download") > 0) {
                option.isOptionActive(option.constant.site_pconline) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $("#JhsBtn").hide();

            // 底部高速下载
            $($(".links p").get(0)).hide();

            // 误导性广告
            $(".ivy").hide();
        };

        return obj;
    });

    // https://www.jb51.net/softs/40589.html
    // https://www.jb51.net/fonts/658225.html
    // https://www.jb51.net/game/649384.html
    // https://www.jb51.net/codes/575492.html
    container.define("app_jb51", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("jb51.net/softs") > 0) {
                option.isOptionActive(option.constant.site_jb51) && obj.initDownloadPage();
                return true;
            }
            else if (url.indexOf("jb51.net/fonts") > 0) {
                option.isOptionActive(option.constant.site_jb51) && obj.initDownloadPage();
                return true;
            }
            else if (url.indexOf("jb51.net/game") > 0) {
                option.isOptionActive(option.constant.site_jb51) && obj.initDownloadPage();
                return true;
            }
            else if (url.indexOf("jb51.net/codes") > 0) {
                option.isOptionActive(option.constant.site_jb51) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".gsdw").hide();

            // 底部高速下载
            $($(".address-wrap .gs").get(0)).hide();
            $("#gaosu").hide();
        };

        return obj;
    });

    // http://www.cncrk.com/downinfo/180262.html
    container.define("app_cncrk", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("cncrk.com/downinfo") > 0) {
                option.isOptionActive(option.constant.site_cncrk) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 高速下载
            $(".downfile_hits").hide();
            $(".download-address").html("<p>全是高(捆)速(绑)下载,已作隐藏处理</p>");
        };

        return obj;
    });

    // https://pc.qq.com/detail/8/detail_11488.html
    container.define("app_qq", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("pc.qq.com/detail") > 0) {
                option.isOptionActive(option.constant.site_pc_qq) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 高速下载
            $(".detail-install-fast").hide();
        };

        return obj;
    });

    // https://www.crsky.com/soft/48442.html
    container.define("app_crsky", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("crsky.com/soft") > 0) {
                option.isOptionActive(option.constant.site_crsky) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            $($(".i_dwon a").get(1)).hide();

            $(".Adown_dli").hide();
        };

        return obj;
    });

    // http://www.duote.com/soft/314065.html
    container.define("app_duote", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("duote.com/soft") > 0) {
                option.isOptionActive(option.constant.site_duote) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 误导广告
            $(".dl-banner").hide();

            // 底部高速下载
            $(".down-lists").each(function () {
                if ($(this).find(".download-box").length > 1) {
                    $($(this).find(".download-box").get(0)).hide();
                }
            });
        };

        return obj;
    });

    // http://www.downza.cn/soft/193456.html
    container.define("app_downza", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("downza.cn/soft") > 0 || url.indexOf("downza.cn/android") > 0) {
                option.isOptionActive(option.constant.site_downza) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $("#xzqIMG1").hide();

            // 底部高速下载
            $($(".pc-down_url_left .pull-left div").get(0)).hide();
            $(".pc-down_url_left .down_top").hide();
        };

        return obj;
    });

    // http://mydown.yesky.com/pcsoft/266126.html
    container.define("app_yesky", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("yesky.com/pcsoft") > 0) {
                option.isOptionActive(option.constant.site_yesky) && obj.initDownloadPage();
                return true;
            }
            else if (url.indexOf("yesky.com/game") > 0) {
                option.isOptionActive(option.constant.site_yesky) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".bkdown").hide();
            $("#local_down").show();

            // 底部高速下载
            $($(".bk-soft_downurl .url h4").get(0)).hide();
            $(".bk-soft_downurl .down_referer").hide();
            $(".bk-soft_downurl hr").hide();
        };

        return obj;
    });

    // http://www.ddooo.com/softdown/65448.htm
    container.define("app_ddooo", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("ddooo.com/softdown") > 0) {
                option.isOptionActive(option.constant.site_ddooo) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $(".gsbtn1").hide();

            // 底部高速下载
            $($(".txtfont").get(0)).hide();
            $(".c_down").hide();
        };

        return obj;
    });

    // https://download.pchome.net/mobile/games/other/download-193583.html
    container.define("app_pchome", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("download.pchome.net") > 0 && url.indexOf("/download-") > 0) {
                option.isOptionActive(option.constant.site_pchome) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 不需提示
            $(".dl-tip").hide();

            // 混淆广告
            $(".mod_banner").hide();
        };

        return obj;
    });

    // https://www.xpgod.com/soft/121.html
    container.define("app_xpgod", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("xpgod.com/soft") > 0) {
                option.isOptionActive(option.constant.site_xpgod) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 顶部高速下载
            $($("#bzxz a").get(1)).hide();

            // 底部高速下载
            $(".show_xzq").hide();
        };

        return obj;
    });

    // https://www.52z.com/soft/389669.html
    container.define("app_52z", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("52z.com/soft") > 0) {
                option.isOptionActive(option.constant.site_52z) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 高速下载
            setTimeout(function () {
                $($(".elYxxzIn").get(0)).hide();
            }, 1000);
        };

        return obj;
    });

    // http://www.opdown.com/soft/23485.html
    container.define("app_opdown", ["runtime", "option", "$"], function (runtime, option, $) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();
            if (url.indexOf("opdown.com/soft") > 0) {
                option.isOptionActive(option.constant.site_opdown) && obj.initDownloadPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initDownloadPage = function () {
            // 高速下载
            $(".downnows").hide();
            $(".listaddr").hide();
        };

        return obj;
    });

    container.define("app_newday", ["runtime", "env", "option", "meta", "vue"], function (runtime, env, option, meta, vue) {
        var obj = {};

        obj.run = function () {
            if (meta.existMeta("info")) {
                obj.initInfoPage();
                return true;
            } else if (meta.existMeta("option")) {
                obj.initOptionPage();
                return true;
            }
            else {
                return false;
            }
        };

        obj.initInfoPage = function () {
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo()
                },
                mounted: function () {
                    obj.initAddonReady();
                }
            });
        };

        obj.initOptionPage = function () {
            new vue({
                el: "#container",
                data: {
                    option: option.getOption()
                },
                mounted: function () {
                    obj.initAddonReady();
                },
                watch: {
                    option: function (value) {
                        option.setOption(value);
                    }
                }
            });
        };

        obj.initAddonReady = function () {
            $("body").addClass("nd-addon-ready");
        };

        return obj;
    });

    container.define("app", ["runtime", "logger", "meta", "$"], function (runtime, logger, meta, $, require) {
        var obj = {};

        obj.run = function () {
            var metaName = "status";
            if (meta.existMeta(metaName)) {
                logger.info("addon setup already");
            }
            else {
                logger.info("addon setup success");

                // 添加meta
                meta.appendMeta(metaName);

                // 运行应用
                $(obj.runApp);
            }
        };

        obj.runApp = function () {
            var appList = [
                {
                    name: "app_onlinedown",
                    matchs: [
                        "onlinedown.net"
                    ]
                },
                {
                    name: "app_cr173",
                    matchs: [
                        "cr173.com"
                    ]
                },
                {
                    name: "app_xiazaiba",
                    matchs: [
                        "xiazaiba.com"
                    ]
                },
                {
                    name: "app_mydown",
                    matchs: [
                        "mydown.com"
                    ]
                },
                {
                    name: "app_pc6",
                    matchs: [
                        "pc6.com"
                    ]
                },
                {
                    name: "app_zol",
                    matchs: [
                        "zol.com.cn"
                    ]
                },
                {
                    name: "app_pconline",
                    matchs: [
                        "pconline.com.cn"
                    ]
                },
                {
                    name: "app_jb51",
                    matchs: [
                        "jb51.net"
                    ]
                },
                {
                    name: "app_cncrk",
                    matchs: [
                        "cncrk.com"
                    ]
                },
                {
                    name: "app_qq",
                    matchs: [
                        "pc.qq.com"
                    ]
                },
                {
                    name: "app_crsky",
                    matchs: [
                        "www.crsky.com"
                    ]
                },
                {
                    name: "app_duote",
                    matchs: [
                        "duote.com"
                    ]
                },
                {
                    name: "app_downza",
                    matchs: [
                        "downza.cn"
                    ]
                },
                {
                    name: "app_yesky",
                    matchs: [
                        "yesky.com"
                    ]
                },
                {
                    name: "app_ddooo",
                    matchs: [
                        "ddooo.com"
                    ]
                },
                {
                    name: "app_pchome",
                    matchs: [
                        "pchome.net"
                    ]
                },
                {
                    name: "app_xpgod",
                    matchs: [
                        "xpgod.com"
                    ]
                },
                {
                    name: "app_52z",
                    matchs: [
                        "52z.com"
                    ]
                },
                {
                    name: "app_opdown",
                    matchs: [
                        "opdown.com"
                    ]
                },
                {
                    name: "app_newday",
                    matchs: [
                        "*"
                    ]
                }
            ];
            var url = runtime.getUrl();
            for (var i in appList) {
                var app = appList[i];
                if (obj.matchApp(url, app) && require(app.name).run() == true) {
                    break;
                }
            }
        };

        obj.matchApp = function (url, app) {
            var match = false;
            app.matchs.forEach(function (item) {
                if (url.indexOf(item) > 0 || item == "*") {
                    match = true;
                }
            });
            return match;
        };

        return obj;
    });

    // 注册模块
    container.define("$", [], function () {
        return window.$;
    });
    container.define("vue", [], function () {
        return window.Vue;
    });

    container.use(["logger", "core", "app"], function (logger, core, app) {

        // 日志级别
        logger.setLevel(logger.constant.info);

        core.ready(function () {
            app.run();
        });
    });
};

(function () {
    'use strict';

    var container = (function () {
        var obj = {
            module_defines: {},
            module_objects: {}
        };

        obj.define = function (name, requires, callback) {
            name = obj.processName(name);
            obj.module_defines[name] = {
                requires: requires,
                callback: callback
            };
        };

        obj.require = function (name, cache) {
            if (typeof cache == "undefined") {
                cache = true;
            }

            name = obj.processName(name);
            if (cache && obj.module_objects.hasOwnProperty(name)) {
                return obj.module_objects[name];
            }
            else if (obj.module_defines.hasOwnProperty(name)) {
                var requires = obj.module_defines[name].requires;
                var callback = obj.module_defines[name].callback;

                var module = obj.use(requires, callback);
                cache && obj.register(name, module);
                return module;
            }
        };

        obj.use = function (requires, callback) {
            var module = {
                exports: {}
            };
            var params = obj.buildParams(requires, module);
            var result = callback.apply(this, params);
            if (typeof result != "undefined") {
                return result;
            }
            else {
                return module.exports;
            }
        };

        obj.register = function (name, module) {
            name = obj.processName(name);
            obj.module_objects[name] = module;
        };

        obj.buildParams = function (requires, module) {
            var params = [];
            requires.forEach(function (name) {
                params.push(obj.require(name));
            });
            params.push(obj.require);
            params.push(module.exports);
            params.push(module);
            return params;
        };

        obj.processName = function (name) {
            return name.toLowerCase();
        };

        return {
            define: obj.define,
            use: obj.use,
            register: obj.register,
            modules: obj.module_objects
        };
    })();

    container.define("runtime", [], function () {
        var obj = {
            url: location.href,
            referer: document.referrer,
        };

        obj.getUrl = function () {
            return obj.url;
        };

        obj.setUrl = function (url) {
            obj.url = url;
        };

        obj.getReferer = function () {
            return obj.referer;
        };

        obj.setReferer = function (referer) {
            obj.referer = referer;
        };

        obj.getUrlParam = function (name) {
            var param = obj.parseUrlParam(obj.getUrl());
            if (name) {
                return param.hasOwnProperty(name) ? param[name] : null;
            }
            else {
                return param;
            }
        };

        obj.parseUrlParam = function (url) {
            if (url.indexOf("?")) {
                url = url.split("?")[1];
            }
            var reg = /([^=&\s]+)[=\s]*([^=&\s]*)/g;
            var obj = {};
            while (reg.exec(url)) {
                obj[RegExp.$1] = RegExp.$2;
            }
            return obj;
        };

        return obj;
    });

    container.define("router", [], function () {
        var obj = {};

        obj.goUrl = function (url) {
            obj.eval('location.href = "' + url + '";');
        };

        obj.openUrl = function (url) {
            obj.eval('window.open("' + url + '");');
        };

        obj.openTab = function (url, active) {
            GM_openInTab(url, !active);
        };

        obj.eval = function (script) {
            var node = document.createElementNS(document.lookupNamespaceURI(null) || "http://www.w3.org/1999/xhtml", "script");
            node.textContent = script;
            (document.head || document.body || document.documentElement || document).appendChild(node);
            node.parentNode.removeChild(node)
        };

        return obj;
    });

    container.define("env", [], function () {
        var obj = {};

        obj.getVersion = function () {
            return GM_info.script.version;
        };

        obj.getInfo = function () {
            return {
                version: obj.getVersion()
            };
        };

        return obj;
    });

    container.define("meta", ["constant", "$"], function (constant, $) {
        var obj = {};

        obj.existMeta = function (name) {
            name = obj.processName(name);
            if ($("meta[name='" + name + "']").length) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.appendMeta = function (name, content) {
            name = obj.processName(name);
            content || (content = "on");
            $('<meta name="' + name + '" content="on">').appendTo($("head"));
        };

        obj.processName = function (name) {
            return constant.name + "::" + name;
        };

        return obj;
    });

    container.define("constant", [], function () {
        return {
            name: "jzx",
            router: {
                option: "http://one.newday.me/page/jzx/info.html"
            }
        };
    });

    container.define("core", ["router", "constant"], function (router, constant) {
        var obj = {};

        obj.openOptionPage = function () {
            if (GM_info.addon && GM_info.addon.options_page) {
                router.openTab(GM_info.addon.options_page, true);
            }
            else {
                router.openTab(constant.router.option, true);
            }
        };

        obj.ready = function (callback) {
            callback && callback();
        };

        return obj;
    });

    container.define("app_wpzs", [], function () {
        var obj = {};

        obj.run = function () {
            appWpzs();
        };

        return obj;
    });

    container.define("app_yhg", [], function () {
        var obj = {};

        obj.run = function () {
            appYhg();
        };

        return obj;
    });

    container.define("app_xzws", [], function () {
        var obj = {};

        obj.run = function () {
            appXzws();
        };

        return obj;
    });

    container.define("app_newday", ["env", "meta", "core", "$", "vue"], function (env, meta, core, $, vue) {
        var obj = {};

        obj.run = function () {
            if (obj.existMetaList(["wpzs::dev", "wpzs::info", "wpzs::option", "wpzs::share"])) {
                appWpzs();
            }
            else if (obj.existMetaList(["yhg::dev", "yhg::info", "yhg::option"])) {
                appYhg();
            }
            else if (obj.existMetaList(["xzws::dev", "xzws::info", "xzws::option"])) {
                appXzws();
            }
            else if (meta.existMeta("info")) {
                obj.initInfoPage();
            } else if (meta.existMeta("dev")) {
                obj.initDevPage();
            }
        };

        obj.existMetaList = function (nameList) {
            for (var i in nameList) {
                if (obj.existMeta(nameList[i])) {
                    return true;
                }
            }
            return false;
        };

        obj.existMeta = function (name) {
            if ($("meta[name='" + name + "']").length) {
                return true;
            }
            else {
                return false;
            }
        };

        obj.initInfoPage = function () {
            new vue({
                el: "#container",
                data: {
                    info: env.getInfo()
                },
                mounted: function () {
                    obj.initAddonReady();
                }
            });
        };

        obj.initDevPage = function () {
            $("#dev-addon-info").val(JSON.stringify(env.getInfo()));

            $(".dev-open-page-option").addClass("nd-open-page-option").removeClass("dev-open-page-option");
            $(document).on("click", ".nd-open-page-option", function () {
                core.openOptionPage();
            });
        };

        obj.initAddonReady = function () {
            $("body").addClass("nd-addon-ready");
        };

        return obj;
    });

    container.define("app", ["runtime"], function (runtime, require) {
        var obj = {};

        obj.run = function () {
            var url = runtime.getUrl();

            var appList = [
                {
                    name: "app_wpzs",
                    matchs: [
                        "baidu.com",
                        "weiyun.com",
                        "lanzous.com",
                        "weibo.com",
                        "ctfile.com",
                        "pipipan.com",
                        "dfpan.com"
                    ]
                },
                {
                    name: "app_yhg",
                    matchs: [
                        "taobao.com",
                        "tmall.com",
                        "tmall.hk",
                        "liangxinyao.com",
                        "95095.com",
                        "jd.com",
                        "jd.hk",
                        "kaola.com",
                        "163.com",
                        "yhd.com",
                        "suning.com",
                        "amazon.cn",
                        "dangdang.com",
                        "gome.com.cn",
                        "vip.com"
                    ]
                },
                {
                    name: "app_xzws",
                    matchs: [
                        "onlinedown.net",
                        "cr173.com",
                        "xiazaiba.com",
                        "mydown.com",
                        "pc6.com",
                        "zol.com.cn",
                        "pconline.com.cn",
                        "jb51.net",
                        "cncrk.com",
                        "pc.qq.com",
                        "crsky.com",
                        "duote.com",
                        "downza.cn",
                        "yesky.com",
                        "ddooo.com",
                        "pchome.net",
                        "xpgod.com",
                        "52z.com",
                        "opdown.com"
                    ]
                },
                {
                    name: "app_newday",
                    matchs: [
                        "*"
                    ]
                }
            ];
            for (var i in appList) {
                var app = appList[i];
                if (obj.matchApp(url, app)) {
                    require(app.name).run();
                    break;
                }
            }
        };

        obj.matchApp = function (url, app) {
            var match = false;
            app.matchs.forEach(function (item) {
                if (url.indexOf(item) > 0 || item == "*") {
                    match = true;
                }
            });
            return match;
        };

        return obj;
    });

    container.define("$", [], function () {
        return window.$;
    });
    container.define("vue", [], function () {
        return window.Vue;
    });

    container.use(["app"], function (app) {
        app.run();
    });

})();