MCBBS Extender

MCBBS行为拓展/样式修复

当前为 2022-11-09 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MCBBS Extender
// @namespace    https://i.zapic.cc
// @version      release-2.1.0
// @description  MCBBS行为拓展/样式修复
// @author       Zapic
// @match        https://*.mcbbs.net/*
// @run-at       document-body
// @license      MIT
// ==/UserScript==

// Core
(() => {
    let ShouldRun = true;
    // jQuery检查
    if (typeof jQuery == "undefined") {
        console.error("This page does NOT contain JQuery,MCBBS Extender will not work.");
        ShouldRun = false;
    }
    //在手机页面主动禁用
    if (document.getElementsByTagName('meta').viewport) {
        console.log("MCBBS Extender not fully compatible with Moblie page,exit manually");
        ShouldRun = false;
    }
    //夹带私货
    console.log(" %c Zapic's Homepage %c https://i.zapic.moe ", "color: #ffffff; background: #E91E63; padding:5px;", "background: #000; padding:5px; color:#ffffff");
    // Gear浏览器上的Polyfill
    if(typeof console.debug == "undefined") {
        console.debug = function() {};
    }
    // 基本信息初始化
    let version = "v2.1.0";
    let vercode = 121140;
    let valueList = {};
    let configList = [];
    // 加载ValueStorage
    try {
        valueList = JSON.parse(localStorage.getItem("MExt_config"));
        if (typeof valueList != "object" || valueList == null) {
            valueList = {};
            localStorage.setItem("MExt_config", "{}")
        }
    } catch (ignore) {
        valueList = {};
        localStorage.setItem("MExt_config", "{}")
    }
    // 导出模块
    let exportModule = (...modules) => {
        if (!ShouldRun) { return; }
        for (let m of modules) {
            try {
                moduleLoader(m);
            } catch (e) {
                console.error("Error occurred while try to load a module:\n" + e);
            }
        }
    }
    let $ = unsafeWindow.jQuery;
    let dlg = (m) => {
        console.debug("[MCBBS Extender]" + m);
    };
    let setValue = (name, val) => {
        valueList[name] = val;
        localStorage.setItem("MExt_config", JSON.stringify(valueList));
    }
    let getValue = (name) => {
        return valueList[name];
    }
    let deleteValue = (name) => {
        delete valueList[name];
        localStorage.setItem("MExt_config", JSON.stringify(valueList));
    }
    $('head').append('<style id="MExt_CoreStyle"></style>');
    let appendStyle = (style) => {
        document.getElementById('MExt_CoreStyle').innerHTML += "\n" + style;
    };
    let getRequest = (variable, url = "") => {
            let query = url ? /\?(.*)/.exec(url)[1] : window.location.search.substring(1);
            let vars = query.split("&");
            for (let i = 0; i < vars.length; i++) {
                let pair = vars[i].split("=");
                if (pair[0] == variable) {
                    return pair[1];
                }
            }
            return (false);
        }
        // 模块加载器
    let moduleLoader = (module) => {
        // 载入配置项
        if (typeof module.config !== "undefined") {
            module.config.forEach((v) => {
                if (typeof getValue(v.id) == "undefined") {
                    setValue(v.id, v.default);
                }
                let config = v;
                v.value = getValue(v.id);
                configList.push(config);
            });
        }
        // 判断是否应该运行
        if (typeof module.runcase == "function") {
            if (!module.runcase()) {
                return;
            }
        }
        // 加载模块CSS
        if (typeof module.style == 'string') {
            appendStyle(module.style);
        }
        // 运行模块Core
        if (typeof module.core == "function") {
            module.core();
        }
    }

    // 钩住DiscuzAjax函数,使其触发全局事件
    let __ajaxpost = ajaxpost;
    ajaxpost = (formid, showid, waitid, showidclass, submitbtn, recall) => {
        let relfunc = () => {
            if (typeof recall == 'function') {
                recall();
            } else {
                eval(recall);
            }
            $(this).trigger('DiscuzAjaxPostFinished');
        }
        __ajaxpost(formid, showid, waitid, showidclass, submitbtn, relfunc);
    }
    let __ajaxget = ajaxget;
    ajaxget = (url, showid, waitid, loading, display, recall) => {
        let relfunc = () => {
            if (typeof recall == 'function') {
                recall();
            } else {
                eval(recall);
            }
            $(this).trigger('DiscuzAjaxGetFinished');
        }
        __ajaxget(url, showid, waitid, loading, display, relfunc);
    }
    dlg("Hooked into Discuz Ajax");

    // 对外暴露API
    let MExt = {
        "ValueStorage": {
            "get": getValue,
            "set": setValue,
            "delete": deleteValue
        },
        "exportModule": exportModule,
        "debugLog": dlg,
        "versionName": version,
        "versionCode": vercode,
        "jQuery": $,
        "configList": configList,
        "Units": {
            "appendStyle": appendStyle,
            "getRequest": getRequest
        }
    };
    unsafeWindow.MExt = MExt;
    dlg("Core loaded.");
})();

// Settings
(() => {
    let MExt = unsafeWindow.MExt;
    let $ = MExt.jQuery;
    let Md = {
        "style": `.conf_contain {
            max-height: 45vh;
            overflow-y: auto;
            padding-right: 5px;
            overflow-x: hidden;
            scrollbar-color: rgba(0, 0, 0, 0.17) #f7f7f7;
            scrollbar-width: thin;
        }

        .alert_info ::-webkit-scrollbar {
            background: #f7f7f7;
            height: 7px;
            width: 7px
        }

        .alert_info ::-webkit-scrollbar-thumb:hover {
            background: rgba(0, 0, 0, 0.35);
        }

        .alert_info ::-webkit-scrollbar-thumb {
            background: rgba(0, 0, 0, 0.17);
        }

        .conf_item {
            line-height: 1.2;
            margin-bottom: 5px;
        }

        .conf_title {
            font-weight: 1000;
        }

        .conf_subtitle {
            font-size: 10px;
            color: rgba(0, 0, 0, 0.5);
            padding-right: 40px;
            display: block;
        }

        .conf_check {
            float: right;
            margin-top: -25px;
        }

        .conf_input {
            float: right;
            width: 30px;
            margin-top: -27px;
        }

        .conf_longinput {
            width: 100%;
            margin-top: 5px;
        }

        .conf_textarea {
            width: calc(100% - 4px);
            margin-top: 5px;
            resize: vertical;
            min-height: 50px;
        }`,
        "core": () => {
            let getRequest = MExt.Units.getRequest;
            $(() => {
                // 发送警告
                if (location.pathname == "/forum.php" && getRequest('mod') == "post" && getRequest('action') == "newthread" && getRequest('fid') == "246") {
                    $("body").append($(`<div id="close_script_alert" style="max-width:430px;position: fixed; left: 20px; top: 80px; z-index: 9999; transform: matrix3d(1, 0, 0, 0.0001, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.025) translateX(-120%); background: rgba(228, 0, 0, 0.81); color: white; padding: 15px; transition-duration: 0.3s; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.66) 2px 2px 5px 0px;"><h1 style="font-size: 3em;float: left;margin-right: 12px;font-weight: 500;margin-top: 6px;">警告</h1><span style="font-size: 1.7em;">您正在向反馈与投诉版发表新的帖子</span><br>如果您正在向论坛报告论坛内的Bug,请先关闭此脚本再进行一次复现,以确保Bug不是由MCBBS Extender造成的.</div>`));
                    setTimeout(() => { $("#close_script_alert")[0].style.transform = "matrix3d(1, 0, 0, 0.0001, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.025)"; }, 10);
                    setTimeout(() => { $("#close_script_alert")[0].style.transform = "none"; }, 300);
                    setTimeout(() => { $("#close_script_alert")[0].style.transform = "translateX(-120%)"; }, 10000);
                    MExt.debugLog("Warning send");
                }
                // 设置界面初始化
                $("#user_info_menu .user_info_menu_btn").append("<li><a href='javascript: void(0);' id=\"MExt_config\">MCBBS Extender 设置</a></li>");
                let confwinContent = '<style>body{overflow:hidden}.altw{width:700px;max-width:95vw;}.alert_info {background-image: unset;padding-left: 20px;padding-right: 17px;}</style><div class="conf_contain">';
                let inputType = {
                    "check": '',
                    "num": '',
                    "text": '',
                    "textarea": ''
                };
                MExt.configList.forEach((v) => {
                    switch (v.type) {
                        case "check":
                            inputType.check += '<p class="conf_item"><span class="conf_title">' + v.name + '</span><br><span class="conf_subtitle">' + v.desc + '</span><input class="conf_check" type="checkbox" id="in_' + v.id + '"></input></p>';
                            break;
                        case "num":
                            inputType.num += '<p class="conf_item"><span class="conf_title">' + v.name + '</span><br><span class="conf_subtitle">' + v.desc + '</span><input type="number" class="conf_input" id="in_' + v.id + '"></input></p>';
                            break;
                        case "text":
                            inputType.text += '<p class="conf_item"><span class="conf_title">' + v.name + '</span><br><span class="conf_subtitle">' + v.desc + '</span><input type="text" class="conf_longinput" id="in_' + v.id + '"></input></p>';
                            break;
                        case "textarea":
                            inputType.textarea += '<p class="conf_item"><span class="conf_title">' + v.name + '</span><br><span class="conf_subtitle">' + v.desc + '</span><textarea class="conf_textarea" id="in_' + v.id + '"></textarea></p>';
                            break;
                        default:
                            inputType.check += '<p class="conf_item"><span class="conf_title">' + v.name + '</span><br><span class="conf_subtitle">' + v.desc + '</span><input class="conf_check" type="checkbox" id="in_' + v.id + '"></input></p>';
                            break;
                    }
                });
                confwinContent += inputType.check + inputType.num + inputType.text + inputType.textarea + '</div>';
                MExt.debugLog('Setting window content loaded.');
                $("#MExt_config").on("click", () => {
                    unsafeWindow.showDialog(
                        confwinContent,
                        "confirm",
                        "MCBBS Extender 设置<a href=\"https://afdian.net/@Zapic\" target=\"_blank\" style=\"margin-left: 385px;color: #369;text-decoration: underline;\">爱发电赞助</a><a href=\"https://github.com/Proj-MExt/Modules-Repo/\" target=\"_blank\" style=\"margin-left: 15px;color: #369;text-decoration: underline;\">插件市场</a>",
                        () => {
                            MExt.configList.forEach((v) => {
                                let val = '';
                                if (v.type == "num" || v.type == "text" || v.type == "textarea") {
                                    val = $("#in_" + v.id).val();
                                } else {
                                    val = $("#in_" + v.id).prop("checked");
                                }
                                MExt.ValueStorage.set(v.id, val);
                            });
                            setTimeout(() => {
                                unsafeWindow.showDialog("设置已保存,刷新生效<style>.alert_info{background:url(https://www.mcbbs.net/template/mcbbs/image/right.gif) no-repeat 8px 8px}</style>", "confirm", "", () => { location.reload() }, true, () => {}, "", "刷新", "确定");
                            });
                        },
                        true,
                        () => {},
                        "MCBBS Extender " + MExt.versionName + " - 世予可爱捏"
                    );
                    MExt.configList.forEach((v) => {
                        if (v.type == "num" || v.type == "text" || v.type == "textarea") {
                            $("#in_" + v.id).val(MExt.ValueStorage.get(v.id));
                        } else {
                            $("#in_" + v.id).prop("checked", MExt.ValueStorage.get(v.id));
                        }
                    });
                });
            });
        }
    };
    MExt.exportModule(Md);
})();

// Update Manager
(() => {
    let updatelist = [
        "1. 修复 帖子高亮 部分用户高亮出现异常的情况",
        "2. 孩子没有钱了, 赏口饭吃吧! -> <a href=\"https://afdian.net/@Zapic\" target=\"_blank\" style=\"color: #369;text-decoration: underline;\">爱发电赞助</a>"
    ];
    unsafeWindow.MExt.exportModule({
        "core": () => {
            if (typeof unsafeWindow.MExt.ValueStorage.get("LastVersion") == "undefined") {
                unsafeWindow.MExt.ValueStorage.set("LastVersion", unsafeWindow.MExt.versionCode);
                showDialog("<b>欢迎使用MCBBS Extender</b>.<br>本脚本的设置按钮已经放进入了您的个人信息菜单里,如需调整设置请在个人信息菜单里查看.<br><a href=\"https://afdian.net/@Zapic\" target=\"_blank\" style=\"color: #E91E63;text-decoration: underline;\">在爱发电赞助我!</a>", "right", "欢迎", () => {
                    showMenu('user_info');
                    unsafeWindow.MExt.jQuery("#MExt_config").css("background-color", "#E91E63").css("color", "#fff");
                    setTimeout(() => {
                        hideMenu('user_info_menu');
                        unsafeWindow.MExt.jQuery("#MExt_config").css("background-color", "").css("color", "");
                    }, 3000);
                });
                return;
            }
            if (unsafeWindow.MExt.ValueStorage.get("LastVersion") == unsafeWindow.MExt.versionCode) { return; }
            let updateContent = '';
            updatelist.forEach((v) => {
                updateContent += "<br>" + v;
            });
            showDialog("<b>MCBBS Extender 已经更新至 " + unsafeWindow.MExt.versionName + "</b>" + updateContent, "right");
            unsafeWindow.MExt.ValueStorage.set("LastVersion", unsafeWindow.MExt.versionCode);
        }
    });
})();

//Modules
(() => {
    let staticRes = {
        "atBtnImage": "data:image/png;base64,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",
        "medalReflectImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAA3CAYAAACGnvPUAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA1UlEQVRYw+3Qy6rBARRGcQcjl1zCG5AkkY48gUiEMHU/7/8GS/vUHoqif1/ZgzX/tVLAn0qpwAQmMIH5NsxECWM1gYMKxsoBUxWM1wKOKhgrD8xUMF47yUvPMFYBmKtgvA5wUsFYRWChgrF+gC5wVsB4JWCpgvFLvU9dehfjlYGVCsYv9YGLAsarAGsVjJUGBsBVAeNVgY0Kxi8NX7mUBMarAVsVjF/6fXQpaYxXB3YqGCsDjICbAsZrAHsVjJUFxiqY/wITmMAEJjCBCUxgAhOYb8PcAbo5rkGPsZmjAAAAAElFTkSuQmCC",
        "rainbowBtnImage": "data:image/png;base64,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"
    };
    let MExt = unsafeWindow.MExt;
    let $ = MExt.jQuery;
    let dlg = MExt.debugLog;
    let Stg = MExt.ValueStorage;
    let fixCodeBlock = {
        "style": `pre:not([id]) code {
    background: #f7f7f7;
    display: block;
    font-family: Monaco, Consolas, 'Lucida Console', 'Courier New', serif;
    font-size: 12px;
    line-height: 1.8em;
    padding: 10px;
    border: #ccc solid 1px;
    position: relative;
}

.pl .blockcode ol li:hover {
    background: none;
    color: #666
}

.pl .blockcode ol li {
    white-space: nowrap;
    list-style: none;
    padding-left:0;
    margin-left:0;
}

.pl pre em, .pl .blockcode em {
    font-size: 0;
}

.pl pre em::after, .pl .blockcode em::after {
    content: 'Copy';
    position: absolute;
    top: 3px;
    right: 7px;
    display: block;
    font-size: 14px;
    border: #369 dashed 1px;
    padding: 0 7px;
    border-radius: 3px;
    transition-duration: .1s;
    opacity: 0.3;
    color: #369;
    cursor: pointer;
    font-family: Monaco, Consolas, 'Lucida Console', 'Courier New', serif;
}

.pl .blockcode,.pl pre:not([id]) {
    position: relative;
    padding: 0;
}

.pl pre em:active::after, .pl .blockcode em:active::after {
    background: #369;
    border: #369 solid 2px;
    color: white;
}

.pl .blockcode em:hover::after, .pl pre em:hover::after {
    opacity: 1;
}

.pl .blockcode div[id], pre:not([id]) code {
    max-height: 500px;
    overflow: auto;
    padding: 10px 30px 5px 50px;
    background: #F7F7F7 url(https://www.mcbbs.net/template/mcbbs/image/codebg.gif) repeat-y 0 0;
    scrollbar-width: thin;
}

.pl .blockcode div[id]::-webkit-scrollbar, pre:not([id]) code::-webkit-scrollbar {
    width: 7px;
    height: 7px;
}

.pl .blockcode div[id]::-webkit-scrollbar-thumb, pre:not([id]) code::-webkit-scrollbar-thumb {
    background: #00000040
}

.line-counter {
    position: sticky;
    float: left;
    left: -50px;
    line-height: 1.8em;
    padding-top: 3px;
    user-select: none;
    margin: -4px 0px -50px -50px;
    border-right: #d6d6d6 solid 1px;
    width: 38px;
    background: #ededed;
    font-size: 12px;
    font-family: Monaco, Consolas, 'Lucida Console', 'Courier New', serif;
    padding-right: 4px;
    text-align: right;
}

.pl .blockcode ol {
    margin: 0!important;
}

.pl .t_table .blockcode ol li {
    width:0;
}
pre:not([id]) code br{
    display: none;
}
`,
        "core": () => {
            // 构建代码行计数器
            let LnBuilder = (ln) => {
                let str = "";
                for (let i = 1; i <= ln; i++) {
                    str += (i < 10 ? "0" + i.toString() : i.toString()) + ".\n";
                }
                return str;
            };
            // 为代码块添加行数显示与复制按钮
            let fixCode = () => {
                $(".pl pre:not([id]) code:not([code-fixed])").attr("code-fixed",'').each((i, v) => {
                    // 构建计数器
                    let ln = v.innerHTML.split("\n").length;
                    let lnC = LnBuilder(ln);
                    let counter = document.createElement("div");
                    counter.className = "line-counter";
                    counter.innerText = lnC;
                    // 构建按钮
                    let copy = document.createElement("em");
                    copy.className = "code-copy";
                    copy.addEventListener("click", (e) => {
                        let n = e.currentTarget.previousSibling;
                        copycode(n);
                    });
                    v.prepend(counter);
                    v.parentElement.append(copy);
                });
                $(".pl div.blockcode:not([code-fixed])").attr("code-fixed",'').each((i, v) => {
                    // 构建计数器
                    let ln = v.firstElementChild.firstElementChild.childElementCount;
                    let lnC = LnBuilder(ln);
                    let counter = document.createElement("div");
                    counter.className = "line-counter";
                    counter.innerText = lnC;
                    v.firstElementChild.prepend(counter);
                });
                dlg('Line counter appended.');
            }
            copycode = (t) => {
                    console.log(t.firstElementChild);
                    setCopy(t.innerText.replace(/\n\n/g, "\n").replace(t.firstElementChild.innerText,''), "代码已复制到剪贴板");
                    dlg("Code copied.");
                };
            $(fixCode);
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", fixCode);
        },
        "config": [{
            "id": "fixCodeBlock",
            "default": true,
            "type": "check",
            "name": "美化代码块样式",
            "desc": "修正代码块的一些样式,如滚动条."
        }],
        "runcase": () => { return MExt.ValueStorage.get("fixCodeBlock"); }
    };
    let queryMessage = {
        "runcase": () => { return MExt.ValueStorage.get("queryMessage") },
        "config": [{
            "id": "queryMessage",
            "default": true,
            "type": "check",
            "name": "后台轮询消息",
            "desc": "在后台自动查询是否有新的消息并推送,需保证至少打开一个页面."
        }, {
            "id": "queryMessageInterval",
            "default": 60,
            "type": "num",
            "name": "后台轮询消息间隔",
            "desc": "两次轮询消息之间的间隔,单位秒.注意,过低的值可能会导致你被论坛屏蔽,超过200的值可能会导致消息反复推送."
        }],
        "core": () => {
            let checkNotifica = (noNotifica = false) => {
                    if (localStorage.getItem("MExt_ActiveQueryId") != queryId) {
                        return false;
                    }
                    dlg("Checking message...");
                    $.get("/forum.php?mod=misc", (d) => {
                        // 设置最后通知时间为当前时间,以防止反复推送
                        localStorage.setItem('notifica-time', new Date().getTime());
                        let dom = $(d);
                        // 获得顶栏图标类
                        let noticlass = dom.find("#myprompt").attr("class");
                        // 获得通知菜单元素
                        let notimenu = dom.filter("#myprompt_menu");
                        // 将顶栏图标类写入当前页
                        $("#myprompt").attr("class", noticlass);
                        // 将通知菜单写入当前页
                        $("#myprompt_menu").html(notimenu.html());
                        // 获得消息内容,用作缓存
                        let noticontent = notimenu.html();
                        // 判断是否应该发送消息
                        if (!noNotifica && localStorage.getItem("MExt_LastNoticeContent") != noticontent) {
                            // 获得通知脚本(暴力)
                            let scp = dom.filter("script[src*=html5notification]").nextUntil("div").last().text();
                            // 将最后通知时间设置为1,强行启用通知
                            localStorage.setItem('notifica-time', 1);
                            // 执行通知脚本
                            eval(scp);
                            dlg("Notifica sent.");
                            // 写入消息缓存
                            localStorage.setItem("MExt_LastNoticeContent", noticontent);
                            localStorage.setItem("MExt_LastNoticeCount", noticlass);
                        }
                    });
                }
                // 刷新消息缓存
            let flushContent = () => {
                    $.get("/forum.php?mod=misc", (d) => {
                        let dom = $(d);
                        let noticontent = dom.filter("#myprompt_menu").html();
                        let noticlass = dom.find("#myprompt").attr("class");
                        // 写入消息缓存
                        localStorage.setItem("MExt_LastNoticeContent", noticontent);
                        localStorage.setItem("MExt_LastNoticeCount", noticlass);
                    });
                }
                // 生成queryID,用于页面间的互斥
            let queryId = hash(new Date().getTime().toLocaleString(), 16);
            // 判断是否在消息页面||最后通知时间是否超过200秒
            if ((location.pathname == "/home.php" && (getRequest('do') == "pm" || getRequest('do') == "notice")) || new Date().getTime() - localStorage.getItem("notifica-time") > 200000) {
                flushContent();
            } else {
                checkNotifica();
            }
            dlg("Query id is " + queryId + ".");
            // 运行定时器,用于检查其他页面是否在运行
            setInterval(() => {
                if (localStorage.getItem("MExt_LastQuery") == "") {
                    localStorage.setItem("MExt_LastQuery", 0);
                }
                let nowtime = Math.floor(new Date().getTime() / 1000);
                if ((localStorage.getItem("MExt_ActiveQueryId") == "" || nowtime - localStorage.getItem("MExt_LastQuery") > 5) && localStorage.getItem("MExt_ActiveQueryId") != queryId) {
                    localStorage.setItem("MExt_ActiveQueryId", queryId);
                    checkNotifica();
                    dlg("Kick off inactive querier,start query.");
                }
                if (localStorage.getItem("MExt_ActiveQueryId") == queryId) {
                    localStorage.setItem("MExt_LastQuery", nowtime);
                }
            }, 1000);
            dlg("Running checker actived.");
            // 判断是否有HTML5Notification
            if (!unsafeWindow.Html5notification) {
                $.getScript("data/cache/html5notification.js?xm6");
                dlg("Html5notification added.");
            }
            //
            $(window).on("focus", () => {
                dlg("Get content from cache");
                $("#myprompt_menu").html(localStorage.getItem("MExt_LastNoticeContent"));
                $("#myprompt").attr("class", localStorage.getItem("MExt_LastNoticeCount"));
            });
            // 定时运行检查函数
            setInterval(checkNotifica, MExt.ValueStorage.get('queryMessageInterval') * 1000);
            dlg("Message query actived.");
        }
    };
    let rememberPage = {
        "runcase": () => { return MExt.ValueStorage.get("rememberPage") },
        "config": [{
            "id": "rememberPage",
            "default": true,
            "type": "check",
            "name": "板块内翻页记忆",
            "desc": "点击板块内下一页按钮时记忆当前页."
        }],
        "core": () => {
            $(() => {
                let npbtn = $("#autopbn");
                if (npbtn.length) {
                    // 绑定事件
                    let orgfunc = npbtn[0].onclick;
                    npbtn[0].onclick = null;
                    npbtn.on("click", () => {
                        if (npbtn.html() == "正在加载, 请稍后...") { return false; }
                        let nextpageurl = npbtn.attr('rel');
                        let curpage = parseInt(npbtn.attr('curpage'));
                        npbtn.attr('curpage', curpage + 1);
                        nextpageurl = nextpageurl.replace(/&page=\d+/, '&page=' + (curpage + 1));
                        $("#threadlisttableid").append("<a class=\"mext_rempage\" rel=\"" + nextpageurl + "\"></a>")
                        history.replaceState(null, null, nextpageurl);
                        orgfunc();
                    });
                    $("#separatorline").after("<a class=\"mext_rempage\" rel=\"" + window.location + "\"></a>");
                    let timer = -1;
                    // 事件防抖
                    $(window).on("scroll", () => {
                        clearTimeout(timer);
                        timer = setTimeout(() => {
                            let scroll = document.scrollingElement.scrollTop - window.innerHeight / 2;
                            let url = null;
                            document.querySelectorAll(".mext_rempage").forEach((v, i) => {
                                let vtop = v.offsetTop;
                                if (vtop < scroll || i == 0) {
                                    url = v.rel;
                                }
                            });
                            if (url) {
                                history.replaceState(null, null, url);
                            }
                        }, 250);
                    });
                }
                dlg("Page remember actived.");
            });
        }
    };
    let animationGoToTop = {
        "runcase": () => { return MExt.ValueStorage.get("animationGoToTop") },
        "config": [{
            "id": "animateGoToTopButton",
            "default": true,
            "name": "回到顶部按钮美化",
            "type": "check",
            "desc": "为右侧回到顶部按钮增加动画以及位置修正."
        }],
        "style": `#scrolltop {
    bottom: 270px!important;
    visibility: visible;
    overflow-x: hidden;
    width: 75px;
}

.scrolltopa {
    transition-duration: .15s;
    margin-left: -40px;
    opacity: 0;
}

.scrolltopashow {
    margin-left: 0px;
    opacity: 1;
}`,
        "core": () => {
            unsafeWindow.showTopLink = () => {
                let ft = $('#ft')[0];
                if (ft) {
                    let scrolltop = $('#scrolltop')[0];
                    if (!scrolltop) {
                        return false;
                    }
                    let scrolltopbtn = $(".scrolltopa");
                    let scrollHeight = parseInt(document.body.getBoundingClientRect().top);
                    let basew = parseInt(ft.clientWidth);
                    let sw = scrolltop.clientWidth;
                    if (basew < 1000) {
                        let left = parseInt(fetchOffset(ft)['left']);
                        left = left < sw ? left * 2 - sw : left;
                        scrolltop.style.left = (basew + left + 44) + 'px';
                    } else {
                        scrolltop.style.left = 'auto';
                        scrolltop.style.right = 0;
                    }
                    if (scrollHeight < -100) {
                        scrolltopbtn.addClass("scrolltopashow");
                    } else {
                        scrolltopbtn.removeClass("scrolltopashow");
                    }
                }
            }
            showTopLink();
        }
    };
    let pinnerTopBar = {
        "runcase": () => { return MExt.ValueStorage.get("pinnedTopBar") },
        "config": [{
            "id": "pinnedTopBar",
            "default": true,
            "name": "更好的固定顶栏",
            "type": "check",
            "desc": "优化固定顶栏的行为,如与编辑栏的兼容性,以及在极窄窗口下的显示."
        }],
        "style": `#toptb {
    position: fixed;
    width: 100%;
    z-index: 790;
    top: 0;
    box-shadow: rgba(0, 0, 0, 0.3) 3px 3px 5px 1px;
    min-width: 510px;
}

.new_wp {
    max-width: 1130px;
    width: 100%;
}

.mc_map_wp {
    padding-top: 45px;
}

.mw {
    padding-top: 60px
}

#user_info_menu, #myprompt_menu, #usertools_menu, #sslct_menu, #scbar_type_menu {
    position: fixed!important;
    top: 47px!important
}

#scbar_type_menu {
    top: 38px!important;
}

#e_controls {
    z-index: 790!important
}

@media screen and (max-width: 860px) {
    #toptb .z.light {
        display: none;
    }
    #toptb>.new_wp>.y {
        float: none;
        margin-left: 12px;
    }
}`,
        "core": () => {
            $(() => {
                // 重写editorcontrolpos函数,与固定顶栏兼容
                editorcontrolpos = () => {
                    if (editorisfull) {
                        return;
                    }
                    let scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
                    if (scrollTop + 47 > editorcontroltop && editorcurrentheight > editorminheight) {
                        $("#" + editorid + '_controls').prop("style", "z-index:0!important").css("position", 'fixed').css("top", '47px').css("width", editorcontrolwidth + 'px');
                        $("#" + editorid + '_controls_mask').css("display", '');
                    } else {
                        $("#" + editorid + '_controls').css("position", '').css('top', '').css('width', '');
                        $("#" + editorid + '_controls_mask').css('display', 'none');
                    }
                };
                //增加一个5px的遮罩,防止鼠标经过空隙时碰到底层内容
                $("#toptb").after('<div style="position: fixed;top: 47px;height: 5px;width: 100%;z-index:700;"></div>');
                dlg("Mask appended.");
            });
        }
    };
    let fixTopBarPopMenu = {
        "runcase": () => { return MExt.ValueStorage.get("fixTopBarPopMenu") },
        "config": [{
            "id": "fixTopBarPopMenu",
            "default": true,
            "type": "check",
            "name": "弹出菜单美化",
            "desc": "美化弹出菜单的样式,如个人信息菜单."
        }],
        "style": `.p_pop:not(.blk) a {
border-radius: 5px;
border-bottom: none;
}

div#user_info_menu {
margin-top: 5px;
}

.user_info_menu_info>li {
margin-top: 2px;
}

a.rank {
padding: 2px 7px!important;
border-radius: 14px;
}

a.rank:hover {
text-decoration: none;
}

ul.user_info_menu_btn {
padding-top: 6px;
}

ul.user_info_menu_btn>li>a:hover {
background:

}

ul.user_info_menu_btn>li>a {
padding: 5px 8px;
border-radius: 5px;
}

ul.user_info_menu_btn>li>a[onclick]:hover {
background: red!important;
}

#myprompt_menu {
margin-left: -10px;
}

#myprompt_menu, #usertools_menu, #sslct_menu {
z-index: 791!important;
margin-top: 5px!important;
transform: translateX(-50%);
margin-left: 20px;
}

.p_pop:not(.h_pop) {
border: 1px solid #d1d1d1;
min-width: unset;
border-radius: 5px;
}

#myprompt_menu>li>a, #usertools_menu>li>a, #scbar_type_menu>li>a {
border: none;
border-radius: 5px;
text-align: center;
padding: 3px 15px;
}

#myprompt_menu>li>a:hover, #scbar_type_menu>li>a:hover, #usertools_menu>li>a:hover {
background: #36b030;
color: white;
}

div#sslct_menu {
margin-left: 54px;
padding-left: 14px;
}

.sslct_btn {
border: none!important;
width: 15px;
height: 15px;
padding: 2px;
}

.sslct_btn i {
border-radius: 50%;
width: 13px;
height: 13px;
}

#scbar_type_menu {
background: url(https://www.mcbbs.net/template/mcbbs/image/bg-wool-white.png);
}

a#scbar_type:after {
content: "▼";
margin-left: 10px;
}

#scbar_type_menu>li>a {
padding: 3px 5px;
line-height: 20px;
height: 20px;
}

.scbar_type_td {
background: url(https://www.mcbbs.net/template/mcbbs/image/scbar_txt.png) -95px center no-repeat
}

.y_search {
width: 249px;
border-radius: 3px;
overflow: hidden;
}
.y_search_inp {
float: unset;
}

#scbar_txt {
width: 130px;
background-color: transparent;
}
body.winter{
--MExtBtnClr: #5c8dff!important;
}
body.nether{
--MExtBtnClr: #a42e0b!important;
}
body{
--MExtBtnClr: #36b030!important;
}
.user_info_menu_info li a.rank, .user_info_menu_info li a.rank font, ul.user_info_menu_btn>li>a:hover, .p_pop:not(.blk) a:hover,#myprompt_menu>li>a:hover, #scbar_type_menu>li>a:hover, #usertools_menu>li>a:hover, .p_pop:not(.blk) a:hover {
background: var(--MExtBtnClr);
color: white!important;
}

`,
        "core": () => {
            let __extstyle = extstyle;
            let checkStyle = (style = null) => {
                let theme = style == null ? getcookie('extstyle') : style;
                if (theme == "./template/mcbbs/style/winter") {
                    $("body").removeClass("nether").addClass("winter");
                } else if (theme == "./template/mcbbs/style/default") {
                    $("body").removeClass("winter nether");
                } else {
                    $("body").addClass("nether").removeClass("winter");
                }
            }
            extstyle = (style) => {
                __extstyle(style);
                checkStyle(style);
            }
            checkStyle();
        }
    };
    let hoverableMesdal = {
        "runcase": () => { return MExt.ValueStorage.get("hoverableMedal") },
        "config": [{
            "id": "hoverableMedal",
            "default": true,
            "name": "玻璃质感勋章",
            "type": "check",
            "desc": "亮闪闪的勋章~"
        }],
        "style": `.hoverable-medal:hover:after {
    margin-top: 0px!important;
    opacity: 1!important;
}

.hoverable-medal:after {
    display: block;
    content: '';
    margin-top: -15px;
    opacity: 0.6;
    transition-duration: .4s;
    background-image: url(` + staticRes.medalReflectImage + `);
    width: 100%;
    height: 100%;
    filter: blur(2px);
}

div.tip.tip_4[id*=md_] {
    width: 105px;
    height: 165px;
    border: none;
    box-shadow: black 0px 2px 10px -3px;
    margin-left: 38px;
    margin-top: 115px;
    background: black;
    overflow: hidden;
    pointer-events: none!important;
    border-radius: 5px;
    padding: 0px;
}

div.tip.tip_4[id*=md_] .tip_horn {
    background-size: cover;
    background-position: center;
    height: 200%;
    width: 200%;
    z-index: -1;
    filter: blur(7px) brightness(0.8);
    top: -50%;
    left: -50%;
}

div.tip.tip_4[id*=md_] .tip_c {
    color: rgba(255, 255, 255, 0.98);
}

div.tip.tip_4[id*=md_] h4 {
    text-align: center;
    padding: 10px 5px;
    background-color: rgba(255, 255, 255, 0.3);
}

div.tip.tip_4[id*=md_] p {
    padding: 0px 10px;
    position: absolute;
    top: calc(50% + 38px);
    transform: translateY(calc(-50% - 26px));
}

.md_ctrl {
    margin-left: 17px!important;
    padding-bottom: 15px;
}

.hoverable-medal {
    width: 31px;
    height: 53px;
    transition-duration: 0.4s;
    border-radius: 3px;
    display: inline-block;
    margin: 5px;
    background-position: center;
    box-shadow: 0px 2px 5px 0px black;
    overflow: hidden;
}

.hoverable-medal:hover {
    transform: matrix3d(1, 0, 0, 0, 0, 1, 0, -0.003, 0, 0, 1, 0, 0, -1.5, 0, 0.9);
    box-shadow: 0px 2px 10px -3px black;
}

.pg_medal .mgcl img {
    margin-top: 12px!important
}

.mg_img {
    box-shadow: inset 0 0 10px 4px rgba(0, 0, 0, 0.3);
    border-radius: 5px;
}
.md_ctrl:not([glassmedal]){
    display:none;
}`,
        "core": () => {
            let rewriteMedal = () => {
                // 遍历所有未重写楼层
                $('.md_ctrl:not([glassmedal])').attr("glassmedal", "true").each((t, v) => {
                    // 遍历楼层所有勋章
                    $(v).children(0).children('img').each((b, n) => {
                        // 获得勋章ID
                        let id = 'md' + /\_\d*$/.exec(n.id)[0];
                        // 重写勋章结构
                        $(v).append(
                            $('<span class="hoverable-medal" id="' + n.id + '" style="background-image:url(' + n.src + ')"></span>').on('mouseover', () => {
                                showMenu({
                                    'ctrlid': n.id,
                                    'menuid': id + '_menu',
                                    'pos': '12!'
                                });
                            })
                        );
                        // 重写提示样式
                        $("#" + id + "_menu .tip_horn").css("background-image", "url(" + n.src + ")");
                        // 移除旧的勋章
                        n.remove();
                    });
                });
            };
            //调用重写勋章函数
            $(rewriteMedal);
            // 在Ajax时重新调用Ajax函数,保存勋章样式
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", rewriteMedal);
        }
    };
    let viewWarns = {
        "runcase": () => { return MExt.ValueStorage.get("viewWarns") },
        "config": [{
            "id": "viewWarns",
            "default": true,
            "name": "查看警告记录",
            "type": "check",
            "desc": "为每一层楼和每一个个人主页(除自己)添加查看警告记录按钮"
        }],
        "style": `.view_warns_inposts {
    background: url(template/mcbbs/image/warning.gif) no-repeat 0px 2px;
    background-size: 16px;
    width: 90px!important;
}

.view_warns_home a {
    background: url(template/mcbbs/image/warning.gif) no-repeat 1px 2px!important;
    background-size: 16px!important;
}`,
        "core": () => {
            let addVWLink = () => {
                    $(".plhin:not([vw-added*=true])").each((i, v) => {
                        let href = $(v).find(".authi .xw1").attr("href");
                        if (!href) {
                            return false;
                        }
                        let uid = /uid=(\d*)/.exec(href)[1];
                        $(v).attr("vw-added", "true").find("ul.xl.xl2.o.cl").append($('<li class="view_warns_inposts"><a href="forum.php?mod=misc&action=viewwarning&tid=952104&uid=' + uid + '" title="查看警告记录" class="xi2" onclick="showWindow(\'viewwarning\', this.href)">查看警告记录</a></li>'));
                    });
                    dlg("In-posts view warns link added");
                }
                // 在DiscuzAjax时重新调用添加函数,防止失效
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", addVWLink);
            dlg("add VWLink Ajax Event attached.");
            $(() => {
                // 添加查看警告按钮
                addVWLink();
                // 用户信息界面添加查看警告按钮
                let href = $("#uhd .cl a").attr("href");
                if (!href) {
                    return false;
                }
                let uid = /uid=(\d*)/.exec(href)[1];
                if (!uid) {
                    return false;
                }
                $("#uhd .mn ul").append('<li class="view_warns_home"><a href="forum.php?mod=misc&action=viewwarning&tid=952104&uid=' + uid + '" title="查看警告记录" class="xi2" onclick="showWindow(\'viewwarning\', this.href)">查看警告记录</a></li>');
                dlg("Home page view warns link added.")
            });
        }
    };
    let removeLinkWarn = {
        "runcase": () => { return MExt.ValueStorage.get("removeLinkWarn") && location.pathname == "/plugin.php" && MExt.Units.getRequest('id') == "link_redirect" },
        "config": [{
            "id": "removeLinkWarn",
            "default": true,
            "name": "移除外链警告",
            "type": "check",
            "desc": "去除论坛跳转外链时的警告页面."
        }],
        "core": () => {
            let url = MExt.Units.getRequest('target');
            if (url) {
                // 跳就完事了
                location.href = decodeURIComponent(url);
            }
        }
    };
    let useIgInQuickReply = {
        "runcase": () => { return MExt.ValueStorage.get("useIgInQuickReply") },
        "config": [{
            "id": "useIgInQuickReply",
            "default": true,
            "name": "快速回复使用个人签名",
            "type": "check",
            "desc": "在页脚快速回复帖子时使用个人签名."
        }],
        "core": () => {
            // 快速回复框使用个人签名
            let hookReplyBtn = () => {
                if ($("#fwin_reply #usesig").length > 0) { return false; }
                $("#fwin_reply #postsubmit").after('<label for="usesig" style="margin-left: 10px;float: left;margin-top: 3px;"><input type="checkbox" name="usesig" id="usesig" class="pc" value="1" checked="checked">使用个人签名</label>');
                dlg("Use Ig Checkbox appended.");
            }
            $("#append_parent").on('DOMNodeInserted', hookReplyBtn);
            $(() => {
                // 底部快速回复增加选项
                $("#fastpostsubmit").after('<label for="usesig" style="margin-left: 10px;"><input type="checkbox" name="usesig" id="usesig" class="pc" value="1" checked="checked">使用个人签名</label>');
            });
        }
    };
    let fixImgZoom = {
        "runcase": () => { return MExt.ValueStorage.get("fixImgZoom") },
        "config": [{
            "id": "fixImgZoom",
            "default": true,
            "name": "优化图片缩放",
            "type": "check",
            "desc": "使用更现代的方法实现图片缩放."
        }],
        "style": `#img_scale {
    opacity: 0;
    position: absolute;
    right: 20px;
    bottom: 20px;
    background: #0006;
    transition-duration: .2s;
    color: white;
    padding: 10px;
    pointer-events: none;
    border-radius: 10px;
}

#imgzoom_zoom {
    height: auto;
    transition-duration: .2s
}

#imgzoom_zoomlayer {
    height: auto!important
}

#imgzoom {
    width: auto!important;
    height: auto!important
}`,
        "core": () => {
            let __zoom = zoom;
            let t = 0;
            // 初始化基本缩放信息对象
            let img = { width: 0, height: 0, top: 0, left: 0, radio: 1, scale: 1, orgwidth: 0 };
            // 缩放函数
            let resize = (width) => {
                    dlg("Image resizing...")
                    clearTimeout(t);
                    // 显示缩放比例
                    $("#img_scale").html(parseInt(img.scale * 100) + "%").css("opacity", 1);
                    t = setTimeout(() => { $("#img_scale").css("opacity", 0) }, 2000);
                    // 计算目标大小和位置
                    let ow = img.width;
                    img.width = width;
                    ow = (ow - img.width) / -2;
                    img.left -= ow;
                    img.top -= ow * img.radio;
                    // 修改
                    $("#imgzoom_zoom").css("width", img.width + "px");
                    $("#imgzoom").css("left", img.left + "px");
                    $("#imgzoom").css("top", img.top + "px");
                }
                // 保存基本信息
            let initP = () => {
                dlg("Init Picture info");
                img.width = parseInt($("#imgzoom_zoom").attr("width"));
                img.height = parseInt($("#imgzoom_zoom").attr("height"));
                img.radio = img.height / img.width;
                img.top = parseInt($("#imgzoom").css("top"));
                img.left = parseInt($("#imgzoom").css("left"));
                img.scale = 1;
                img.orgwidth = img.width;
            }
            zoom = (obj, zimg, nocover, pn, showexif) => {
                // 伪装成IE,使原函数的DOMMouseScroll事件监听器以可以被卸除的形式添加
                BROWSER.ie = 6;
                __zoom(obj, zimg, nocover, pn, showexif);
                // 防止翻车,改回去
                setTimeout(() => {
                    BROWSER.ie = 0;
                    dlg("IE canceled.")
                }, 1000);
                // 等待窗口出现
                let wait = setInterval(() => {
                    if ($("#imgzoom_zoom").length) {
                        dlg("Image found");
                        clearInterval(wait);
                        // 信息归零,准备下一次保存
                        img = { width: 0, height: 0, top: 0, left: 0, radio: 1, scale: 1, orgwidth: 0 };
                        // 显示遮罩
                        $("#imgzoom_cover").css("display", "unset");
                        // 判断是否已经监听事件,防止超级加倍
                        if ($("#imgzoom").attr("fixed") == "true") { return true; }
                        // 原始尺寸按钮事件
                        $("#imgzoom_adjust").on("click", () => {
                            dlg("return source size");
                            $("#imgzoom").css("transition-property", "opacity,top,left,transform");
                            img.width == 0 ? initP() : 0;
                            img.scale = 1;
                            resize($("#imgzoom_zoom").attr("width"));
                        });
                        // 屏蔽页面滚动
                        $("#imgzoom_cover").on("mousewheel DOMMouseScroll", (e) => {
                            if (e.ctrlKey || e.altKey || e.shiftKey) { return true; }
                            e.preventDefault();
                        });
                        // 卸除原函数监听器
                        $("#imgzoom")[0].onmousewheel = null;
                        // 增加显示缩放大小元素并监听事件
                        $("#imgzoom").append(`<span id="img_scale"></span>`).on("mousewheel DOMMouseScroll", (e) => {
                            // 判断是否按下功能键
                            if (e.ctrlKey || e.altKey || e.shiftKey) { dlg("Func key pressed."); return true; }
                            // 阻止滚动
                            e.preventDefault();
                            // 兼容火狐,正确判断滚轮方向
                            let scroll = e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -e.originalEvent.detail;
                            // 忽略无效滚动
                            if (scroll == 0) { return true; }
                            // 判断是否需要初始化
                            img.width == 0 ? initP() : 0;
                            // 规定需要显示过渡动画的属性
                            $("#imgzoom").css("transition-property", "opacity,top,left,transform");
                            // 判断是否过小
                            if (scroll < 0 && ((img.width < 350 && img.radio < 1) || (img.width * img.radio < 350 && img.radio >= 1))) {
                                // 回弹动画
                                dlg("Reach min size");
                                $("#imgzoom").css("transform", "scale(0.8)");
                                setTimeout(() => { $("#imgzoom").css("transform", "scale(1)"); }, 200);
                                return true;
                            }
                            // 修改缩放比例
                            img.scale += scroll > 0 ? 0.1 : -0.1;
                            // 判断比例是否过小
                            if (img.scale < 0.1) {
                                img.scale = 0.1;
                                // 回弹动画
                                dlg("Reach min size");
                                $("#imgzoom").css("transform", "scale(0.8)");
                                setTimeout(() => { $("#imgzoom").css("transform", "scale(1)"); }, 200);
                                return true;
                            }
                            // 缩放
                            resize(img.orgwidth * Math.pow(img.scale, 2));
                        }).attr("fixed", "true");
                        // 按下鼠标事件
                        $("#imgzoom").on("mousedown", (e) => {
                            // 按下鼠标时移除修改位置的过渡动画,使窗口跟手
                            dlg("Animate removed");
                            $("#imgzoom").css("transition-property", "opacity");
                        });
                        // 释放鼠标事件
                        $("#imgzoom").on("mouseup", (e) => {
                            // 改回去
                            $("#imgzoom").css("transition-property", "opacity,top,left,transform");
                            // 保存移动后的窗口位置
                            img.top = parseInt($("#imgzoom").css("top"));
                            img.left = parseInt($("#imgzoom").css("left"));
                            dlg("Animate added,Pos saved");
                        });
                    }
                }, 50);
            }
        }
    }
    let disableAutoplay = {
        "runcase": () => { return MExt.ValueStorage.get("disableAutoplay") },
        "config": [{
            "id": "disableAutoplay",
            "default": false,
            "name": "禁止BGM自动播放",
            "type": "check",
            "desc": "阻止页内BGM自动播放."
        }],
        "core": () => {
            let clearAutoPlay = () => {
                $("iframe[id*=iframe_mp3]:not([id*=no_autoplay])").each((i, v) => {
                    // 重构播放器,去除自动播放属性
                    let player = document.createElement("iframe");
                    let hidden = document.createElement("div");
                    hidden.id = v.id;
                    hidden.style.display = "none";
                    player.id = v.id + "_no_autoplay";
                    player.width = v.width;
                    player.height = v.height;
                    player.frameBorder = v.frameBorder;
                    player.allow = v.allow;
                    player.src = v.src.replace("&auto=1", "");
                    v.after(hidden);
                    v.after(player);
                    v.remove();
                    dlg("Canceled all autoplay");
                });
            };
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", () => { setTimeout(clearAutoPlay, 100); });
            $(clearAutoPlay);
        }
    };
    let rememberEditorMode = {
        "runcase": () => { return MExt.ValueStorage.get("remenberEditMode") },
        "config": [{
            "id": "remenberEditMode",
            "default": true,
            "name": "记忆编辑器模式",
            "type": "check",
            "desc": "记忆高级编辑器是纯文本模式还是即时模式."
        }],
        "core": () => {
            if (localStorage.getItem("MExt_EditMode") === null) {
                localStorage.setItem("MExt_EditMode", "false");
            }
            $(() => {
                dlg("Remenber Editor Mode actived.");
                $("#e_switchercheck").on("click", (e) => {
                    dlg("Editor mode switch.");
                    localStorage.setItem("MExt_EditMode", e.currentTarget.checked.toString());
                });
                if (localStorage.getItem("MExt_EditMode") == "true") {
                    dlg("Switch editor mode");
                    $("#e_switchercheck").click();
                }
            });
        }
    };
    let highlightThreads = {
        "runcase": () => { return MExt.ValueStorage.get("highlightThreads") },
        "config": [{
            "id": "highlightThreads",
            "default": true,
            "name": "帖子列表高亮",
            "type": "check",
            "desc": "列表高亮显示帖子类型."
        }],
        "style": `.tl .icn {
    background-color: rgba(200, 200, 200, 0.3)!important;
    background-image: linear-gradient(-90deg, rgb(251 242 219), transparent);
    border-left: 3px solid rgb(200, 200, 200);
    transition-duration: .2s;
}
.tl .icn.newReply {
    background-color: rgba(255, 136, 0, 0.3)!important;
    border-left: 3px solid rgb(255, 136, 0);
}

.tl .icn.newMember {
    background-color: rgba(110, 232, 115, 0.3)!important;
    border-left: 3px solid rgb(110, 232, 115);
}

.tl .icn.hotThread {
    background-color: rgba(235, 132, 132, 0.3)!important;
    border-left: 3px solid rgb(235, 132, 132);
}

.tl .icn.digest {
    background-color: rgba(0, 203, 214, 0.3)!important;
    border-left: 3px solid rgb(0, 203, 214);
}

.tl .icn.digest2 {
    background-color: rgba( 0, 161, 204, 0.3)!important;
    border-left: 3px solid rgb( 0, 161, 204);
}

.tl .icn.digest3 {
    background-color: rgba(0, 123, 194, 0.3)!important;
    border-left: 3px solid rgb(0, 123, 194);
}

.tl .icn.close {
    background-color: rgba(187, 187, 187, 0.3)!important;
    border-left: 3px solid rgb(187, 187, 187);
}

.tl .icn.forumSticker {
    background-color: rgba(161, 215, 252, 0.3)!important;
    border-left: 3px solid rgb(161, 215, 252);
}

.tl .icn.partSticker {
    background-color: rgba(110, 171, 235, 0.3)!important;
    border-left: 3px solid rgb(110, 171, 235);
}

.tl .icn.globalSticker {
    background-color: rgba(33, 106, 207, 0.3)!important;
    border-left: 3px solid rgb(33, 106, 207);
}

.tl .icn.poll {
    background-color: rgba(250, 123, 147, 0.3)!important;
    border-left: 3px solid rgb(250, 123, 147);
}

.tl .icn.debate {
    background-color: rgba(0, 153, 204, 0.3)!important;
    border-left: 3px solid rgb(0, 153, 204);
}`,
        "core": () => {
            let highlighting = () => {
                $('#moderate a[title*="有新回复"]').parent().addClass("newReply");
                $('#moderate img[alt="新人帖"]').parent().parent().children(".icn").addClass("newMember");
                $('#moderate img[alt="热帖"]').parent().parent().children(".icn").addClass("hotThread");
                //精华
                $('#moderate img[alt="digest"]').parent().parent().children(".icn").addClass("digest");
                $('#moderate img[title="精华 2"]').parent().parent().children(".icn").addClass("digest2");
                $('#moderate img[title="精华 3"]').parent().parent().children(".icn").addClass("digest3");
                $('#moderate a[title*="关闭的主题"]').parent().addClass("close");
                $('#moderate a[title*="本版置顶主题"]').parent().addClass("forumSticker");
                $('#moderate a[title*="分类置顶主题"]').parent().addClass("partSticker");
                $('#moderate a[title*="全局置顶主题"]').parent().addClass("globalSticker");
                $('#moderate a[title*="辩论"]').parent().addClass("debate");
                $('#moderate a[title*="投票"]').parent().addClass("poll");
                $('#moderate a[title*="悬赏"]').parent().addClass("newReply");
                $('#moderate a.s.xst[style*=color]').each((i, v) => {
                    const style = v.parentNode.parentNode.querySelector(".icn").style;
                    style.setProperty("background-color", v.style.color.replace(")", ",0.4)").replace("rgb(", "rgba("), "important");
                    style.borderLeftColor = v.style.color;
                });
                dlg("Thread list highlighting done.");
            };
            $(highlighting);
            let waiter = 0;
            $(() => {
                let nxBtn = $("#autopbn");
                nxBtn.on("click", () => {
                    if (waiter == 0) {
                        waiter = setInterval(() => {
                            if (nxBtn.text() != "正在加载, 请稍后...") {
                                clearInterval(waiter);
                                waiter = 0;
                                highlighting();
                            }
                        }, 100);
                    }
                });
            });
        }
    };
    let fixAnchor = {
        "runcase": () => { return MExt.ValueStorage.get("fixAnchor") },
        "config": [{
            "id": "fixAnchor",
            "default": false,
            "name": "帖内锚点修复",
            "type": "check",
            "desc": "防止帖内锚点被意外的赋予样式."
        }],
        "style": `table.plhin td.t_f span[id]:not([id^=anchor-]), .fastpreview span[id]:not([id^=anchor-]) {
    display: none!important
}`,
        "core": () => {
            let lastHash = null;
            let handleAnchorJump = () => {
                if(!location.hash || location.hash.substr(0,1) !== "#" || lastHash === location.hash) return;
                lastHash = location.hash;
                const hash = lastHash.substr(1);
                if (hash.length == 0) return;
                const offset = $(`span#anchor-${hash}`).offset();
                const body = unsafeWindow.document.scrollingElement;
                if (!offset) return;
                $(body).animate({
                    scrollTop: offset.top - 48
                }, 300);
            };
            let fix = () => {
                $("table.plhin td.t_f span[id]:not([id^=anchor-]), .fastpreview .bm_c div[id^=post_] span[id]:not([id^=anchor-])").each((i, v) => {
                    v.id = "anchor-" + v.id;
                });
                handleAnchorJump();
                dlg('Anchor fixed.');
            };
            $(fix);
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", fix).on("hashchange", handleAnchorJump);
        }
    };
    let replaceFlash = {
    "runcase": () => { return MExt.ValueStorage.get("replaceFlash") },
    "config": [{
        "id": "replaceFlash",
        "default": true,
        "name": "Flash播放器替换",
        "type": "check",
        "desc": "将网易云Flash播放器替换成H5播放器."
    }],
    "core": () => {
        let replace = () => {
            $("span[id*=swf] embed").each((i, v) => {
                let player = document.createElement("iframe");
                if(v.src.indexOf("style/swf/widget.swf") == -1){
                    return;
                }
                player.src = v.src.replace("style/swf/widget.swf", "outchain/player").replace("sid=", "id=");
                player.width = v.width;
                player.height = v.height;
                player.frameBorder = "no";
                player.allow = "autoplay; fullscreen";
                player.id = v.parentElement.id + "_no_autoplay";
                v.parentElement.after(player);
                v.parentElement.remove();
            });
        }
        $(replace);
        $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", replace);
    }
};
    let restrictMedalLine = {
        "runcase": () => { return MExt.ValueStorage.get("maxMedalLine") >= 0 },
        "config": [{
            "id": "maxMedalLine",
            "default": -1,
            "type": "num",
            "name": "最大勋章行数",
            "desc": "限制楼层勋章的最大行数,提升鼠标滚轮寿命,设置为-1以禁用此功能."
        }],
        "style": `.md_ctrl span.toggle-all {
            width: 125px;
            display: block;
            position: absolute;
            bottom: 0;
            text-align: center;
            left: 0;
            padding: 30px 0px 5px 0px;
            background-image: linear-gradient(0deg, #e3c99e, #e3c99e, transparent);
            color: #3e6c99;
            cursor: pointer;
            user-select: none;
        }

        .md_ctrl {
            position: relative;
            overflow-y: hidden;
            max-height: ` + (Stg.get('maxMedalLine') * (Stg.get('hoverableMedal') ? 60 : 55) + 45).toString() + `px!important;
            transition:unset!important;
        }

        .md_ctrl.show-all {
            max-height: 3000px!important;
            padding-bottom: 40px;
        }`,
        "core": () => {
            let restrict = () => {
                // 判断是否在个人主页
                if ($("#uhd").length > 0) { $("#restrictMedalLine").remove(); return; }
                // 限制勋章行数
                dlg("Restricting line...");
                $('.md_ctrl:not([restrictline])').attr("restrictline", "true").append($("<span class=\"toggle-all\">展开/收起勋章</span>").on("click", (e) => { $(e.target).parent().toggleClass("show-all") })).each((i, v) => {
                    if ((v.childElementCount - 2 <= Stg.get('maxMedalLine') * 3 && Stg.get('hoverableMedal')) || (v.firstChild.childElementCount - 2 <= Stg.get('maxMedalLine') * 3 && !Stg.get('hoverableMedal'))) {
                        v.removeChild(v.lastChild);
                    }
                });
            }
            $(restrict);
            $(this).on("DiscuzAjaxGetFinished DiscuzAjaxPostFinished", restrict);
        }
    };
    let quickAt = {
        "runcase": () => { return MExt.ValueStorage.get("quickAtList").length > 0 },
        "config": [{
            "id": "quickAtList",
            "default": "",
            "name": "快速 @ 列表",
            "type": "text",
            "desc": "按下Ctrl+Shift+A/或者按钮以快速在当前输入框内插入预定义的@用户名代码.用户名之间用\",\"(半角逗号)分隔."
        }],
        "style": `#fastpostatList.in_editorbtn, #postatList {
            background-size: 54px;
            background-position: -23px 3px;
        }

        #fastpostatList, #postatList {
            background-image: url(` + staticRes.atBtnImage + `);
            background-size: 50px;
            background-position: -6px 2px;
        }`,
        "core": () => {
            let getAtCode = () => {
                    // 分隔list
                    let quickAtList = Stg.get('quickAtList').split(",");
                    let atstr = "";
                    //拼接@代码
                    $(quickAtList).each((i, v) => {
                        atstr += "@" + v + " ";
                    });
                    return atstr;
                }
                // 将函数暴露到全局
            MExt_Func_getAtCode = getAtCode;
            // 监听按键事件
            $(document).on("keydown", (e) => {
                if (e.shiftKey && e.ctrlKey && e.keyCode == 65) {
                    // 判断是否在输入框内
                    if (($(document.activeElement).prop("nodeName") == "INPUT" && $(document.activeElement).prop("type") == "text")) {
                        // 拼接方法插入
                        $(document.activeElement).val($(document.activeElement).val() + getAtCode());
                        dlg("@ string added");
                    } else if ($(document.activeElement).prop("nodeName") == "TEXTAREA") {
                        // discuz内建函数插入
                        seditor_insertunit('fastpost', getAtCode(), '');
                        dlg("@ string added");
                    }
                }
            });
            // 高级编辑模式插入@代码
            $(() => {
                if ($("#e_iframe").length) {
                    // 由于高级模式的输入框是iFrame,无法直接监听,故再次监听高级输入框的按键事件
                    $($("#e_iframe")[0].contentWindow).on("keydown", (e) => {
                        if (e.shiftKey && e.ctrlKey && e.keyCode == 65) {
                            // 判断是否在输入框内
                            if ($(document.activeElement).prop("nodeName") == "IFRAME") {
                                //discuz内建函数插入
                                insertText(getAtCode());
                                dlg("@ string added");
                            }
                        }
                    });
                }
            });
            let hookReplyBtn = () => {
                if ($("#postatList").length > 0) { return false; }
                $("#postat.fat").after('<a id="postatList" href="javascript:;" title="快速@" onclick="seditor_insertunit(\'post\',MExt_Func_getAtCode(), \'\');">快速@</a> ');
                dlg("Reply at bottons appends.");
            }
            $("#append_parent").on('DOMNodeInserted', hookReplyBtn);
            $(() => {
                $("#fastpostat").after('<a id="fastpostatList" href="javascript:;" title="快速@" class="" onclick="seditor_insertunit(\'fastpost\',MExt_Func_getAtCode(), \'\');">快速@</a> ');
                $("#e_adv_s1").append('<a id="fastpostatList" href="javascript:;" title="快速@" class="in_editorbtn" onclick="insertText(MExt_Func_getAtCode());">快速@</a>');
            });
        }
    };
    let miscFix = {
        "runcase": () => { return /^[01]*$/.exec(Stg.get('miscFix')) },
        "config": [{
            "id": "miscFix",
            "default": "",
            "name": "杂项修复",
            "type": "text",
            "desc": "此值用于规定杂项修复的行为,默认值为空,修改为0000000000以关闭全部.错误的值会使该项失效.详情请查阅源码."
        }],
        "style": '',
        "core": () => {
            let fixconf = Stg.get('miscFix').split("");
            let fixlist = [
                // 暗牧悬浮预览
                { "style": ".t_f font[style*=\"background-color:black\"], .t_f font[style*=\"background-color:#000\"] {transition-duration: .3s;transition-delay: .5s;cursor: default;}.t_f font[style*=\"background-color:black\"]:hover, .t_f font[style*=\"background-color:#000\"]:hover {transition-delay: 0s;background-color: transparent!important;}" },
                //增加空方法,用于修复论坛的一个报错.
                { "script": "announcement = () => {};relatekw = ()=>{};" },
                //修复页脚问题
                { "style": ".mc_map_wp{min-height:calc(100vh - 202px)!important;}" },
                //修复用户组页面不对齐的问题
                { "style": ".tdats .tb{margin-top:0px}" },
                // 修复编辑器@超级加倍的问题
                { "script": "$(()=>{if(typeof setEditorEvents != \"undefined\"){let __setEditorEvents = setEditorEvents;setEditorEvents= ()=>{ __setEditorEvents();setEditorEvents=()=>{};}}})" },
                // 允许改变个人签名编辑框大小
                { "style": "#sightmlmessage{resize:vertical;}" },
                // 按住shift点击带有超链接的图片则不打开链接
                { "script": `$(()=>{$("img.zoom").parent().each((i,v)=>{if(v.nodeName=="A"){$(v).on("click",(e)=>{console.log(e);if(e.shiftKey){e.preventDefault();}})}})})` },
                // 修复某些页面书框被撕裂的问题
                { "script": "$(()=>{if(!$('.mc_map_wp .mc_map_border_foot').length){$('.mc_map_border_foot').remove();$('.mc_map_wp').append('<div class=\"mc_map_border_foot\"></div>')}})" },
                 // 主动聚焦编辑器iframe,修复报错问题.
                { "script": "$(()=>{if(typeof wysiwyg !='undefined' && wysiwyg){editwin.document.body.focus()};})" },
                // 小提示样式修复
                { "style": ".pc_inner{padding-left:12px}" }
            ];
            let styleContent = "";

            $(fixlist).each((i, v) => {
                if (typeof fixconf[i] == "undefined") { fixconf[i] = "1" }
                if (fixconf[i] === "1") {
                    // 拼接样式字符串
                    styleContent += fixlist[i].style ? fixlist[i].style : "";
                    // 执行脚本
                    eval(fixlist[i].script ? fixlist[i].script : "");
                }
            });
            MExt.Units.appendStyle(styleContent);
        }
    };
    let myReportReason = {
        "runcase": () => { return MExt.ValueStorage.get("myReportReason").length > 0 },
        "config": [{
            "id": "myReportReason",
            "default": "",
            "name": "自定义举报理由",
            "type": "textarea",
            "desc": "在举报时提供自定义的举报理由,一行一个理由."
        }],
        "core": () => {
            // 获得举报内容列表函数
            let getReasons = () => {
                    // 分隔list
                    let reportReason = Stg.get('myReportReason').split("\n");
                    let rrstr = "<p class=\"mtn mbn\">";
                    //拼接HTML
                    $(reportReason).each((i, v) => {
                        rrstr += '<label><input type="radio" name="report_select" class="pr" onclick="$(\'report_other\').style.display=\'none\';$(\'report_msg\').style.display=\'none\';$(\'report_message\').value=\'' + v + '\'" value="' + v + '"> ' + v + '</label><br>';
                    });
                    rrstr += "</p>";
                    return rrstr;
                }
                // 举报按钮钩子函数
            let hookReportWin = () => {
                if ($("#report_reasons[appended]").length > 0) { return false; };
                let reportContent = getReasons();
                $("#report_reasons").attr("appended", "true").before(reportContent);
            }
            $("#append_parent").on('DOMNodeInserted', hookReportWin);
        }
    };
    let myCSS = {
        "runcase": () => { return MExt.ValueStorage.get("myCSS").length > 0 },
        "config": [{
            "id": "myCSS",
            "default": "",
            "name": "自定义CSS",
            "type": "textarea",
            "desc": "在框内的CSS会被加载到页面内,可自由发挥."
        }],
        "style": MExt.ValueStorage.get("myCSS")
    };
    let myLinks = {
        "runcase": () => { return MExt.ValueStorage.get("myLinks").length > 0 },
        "config": [{
            "id": "myLinks",
            "default": "",
            "name": "自定义工具菜单链接",
            "type": "textarea",
            "desc": "在右上角\"工具\"菜单里添加自定义的链接,以\"[名称] [链接]\"的格式添加(如\"个人主页 home.php\"),一行一个."
        }],
        "core": () => {
            // 分割
            $(Stg.get('myLinks').split("\n")).each((i, v) => {
                try {
                    //判断是否合法
                    if (!v.split(" ")[1] || !v.split(" ")[0]) { return true; }
                    // 添加
                    $(() => { $("#usertools_menu").append('<li><a href="' + v.split(" ")[1] + '">' + v.split(" ")[0] + '</a></li>') });
                } catch (ignore) {}
            });
        }
    };
    MExt.exportModule(fixCodeBlock, queryMessage, rememberPage, animationGoToTop, pinnerTopBar, fixTopBarPopMenu, hoverableMesdal, viewWarns, removeLinkWarn, useIgInQuickReply, fixImgZoom, disableAutoplay, rememberEditorMode,
        highlightThreads, fixAnchor, replaceFlash, restrictMedalLine, quickAt, miscFix, myReportReason, myCSS, myLinks);
})();