Greasy Fork is available in English.

超星学习.智慧树.执教云.雨课堂.自动答题脚本

本脚本支持超星学习.智慧树.执教云.雨课堂等平台的测验考试,内置题库,自动答题功能。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         超星学习.智慧树.执教云.雨课堂.自动答题脚本
// @version      1.1.8
// @namespace    https://www.zbhui.cn/?r=/l&sort=0d
// @description  本脚本支持超星学习.智慧树.执教云.雨课堂等平台的测验考试,内置题库,自动答题功能。
// @author       万能
// @match        *://*.chaoxing.com/*
// @match        *://*.edu.cn/*
// @match        *://*.hnsyu.net/*
// @match        *://*.zhihuishu.com/*
// @match        *://*.bsnc.cn/*
// @match        *://*.xuetangx.com/*
// @match        *://*.yuketang.cn/*
// @match        *://*.icve.com.cn/*
// @match      *://item.taobao.com/*
// @match      *://*detail.tmall.com/*
// @match      *://*detail.tmall.hk/*
// @match      *://*.jkcsjd.com/*
// @match        *://*.taobao.com/*
// @match        *://*.tmall.com/*
// @match        *://*.tmall.hk/*
// @match      *://*.liangxinyao.com/*
// @match        *://*.taobao.com/*
// @match        *://*.tmall.com/*
// @match        *://*.tmall.hk/*
// @match        *://*.jd.com/*
// @match        *://*.jd.hk/*
// @match    *://*.yiyaojd.com/*
// @match        *://*.liangxinyao.com/*
// @compatible   chrome firefox edge
// @contributionURL   https://lyck6.cn/pay
// @license MIT
// @grant        GM_info
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @run-at       document-end
// @connect      yuketang.cn
// @connect      appwk.baidu.com
// @connect      lyck6.cn
// @resource     Table https://www.forestpolice.org/ttf/2.0/table.json
// @require      https://cdn.jsdelivr.net/gh/photopea/Typr.js@15aa12ffa6cf39e8788562ea4af65b42317375fb/src/Typr.min.js
// @require      https://cdn.jsdelivr.net/gh/photopea/Typr.js@f4fcdeb8014edc75ab7296bd85ac9cde8cb30489/src/Typr.U.min.js
// @require      https://cdn.jsdelivr.net/npm/jquery@2.2.3/dist/jquery.min.js
// @require      https://cdn.jsdelivr.net/npm/jquery.md5@1.0.2/index.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js
// @require      https://cdn.jsdelivr.net/gh/zyufstudio/jQuery@3a09ff54b33fc2ae489b5083174698b3fa83f4a7/jPopBox/dist/jPopBox.min.js
// @require      https://cdn.bootcss.com/jquery.qrcode/1.0/jquery.qrcode.min.js
// @require      https://update.greasyfork.org/scripts/451606/1345888/%E7%BA%A2%E5%8C%85%E5%BA%93.js
// ==/UserScript==
 
//全局配置参数
var GLOBAL = {
    time: 3E3, //查题间隔时间,不建议小于5s,如果为了安全起见最好10s以上,即10E3
    delay: 2E3, //延迟加载,页面初始化完毕之后的等待2s之后再去搜题,
    fillAnswerDelay: 1E3 //填充答案的延迟,不建议小于0.5秒,默认一秒
};
 
 
(function (exports) {
    'use strict';
   if(coupon.isRun()){
		coupon.show();
	}else{
    function sleep(time) {
        return new Promise((resolve) => {
            setTimeout(resolve, time);
        })
    }
 
 
    function iframeMsg(type, message) {
        exports.top.document.getElementById('iframeNode').contentWindow.vueDefinedProp(type, message);
    }
 
    function filterImg(dom) {
        return $(dom).clone().find("img[src]").replaceWith(function () {
            return $("<p></p>").text('<img src="' + $(this).attr("src") + '">');
        }).end().find("iframe[src]").replaceWith(function () {
            return $("<p></p>").text('<iframe src="' + $(this).attr("src") + '"></irame>');
        }).end().text().trim();
    }
 
    // 需要创建太多嵌套标签了,没个函数不行
    function createContainer(name, childElem) {
        name = name.toLowerCase();
        let elem = exports.top.document.createElement(name);
        elem.style.display = 'block';
        // id 改成驼峰式
        elem.id = name.replace('hcsearche', 'hcSearche').replace(/\-[a-z]/g, function (w) {
            return w.replace('-', '').toUpperCase();
        });
        if (childElem) {
            if (Array.isArray(childElem) === false)
                childElem = [childElem];
            for (let i = 0; i < childElem.length; i++)
                elem.appendChild(childElem[i]);
        }
        return elem;
    }
 
 
    function dragModel(drag) {
        const TOP = exports.top;
        //获取drag元素
        // let drag = document.getElementById("drag")
        //当鼠标按下时
        drag.onmousedown = function (e) {
            drag.style.cursor = 'move';
            //做到浏览器兼容
            e = e || window.event;
            let diffX = e.clientX - drag.offsetLeft;
            let diffY = e.clientY - drag.offsetTop;
            //当拉着box移动时
            exports.top.onmousemove = function (e) {
 
                // 浏览器兼容
                e = e || top.event;
                let left = e.clientX - diffX;
                let top = e.clientY - diffY;
 
                if (left < 0) {
                    left = 0;
                } else if (left > TOP.innerWidth * 0.95 - drag.offsetWidth) {
                    left = TOP.innerWidth * 0.95 - drag.offsetWidth;
                }
 
                if (top < 0) {
                    top = 0;
                } else if (top > TOP.innerHeight - drag.offsetHeight) {
                    top = TOP.innerHeight - drag.offsetHeight;
                }
 
                console.log(drag.style.left);
                console.log(drag.style.top);
                drag.style.left = left + 'px';
                drag.style.top = top + 'px';
            };
 
            // 当鼠标抬起时
            exports.top.onmouseup = function (e) {
                drag.style.cursor = 'default';
                this.onmousemove = null;
                this.onmouseup = null;
            };
        };
    }
 
    function defaultWorkTypeResolver($options) {
        function count(selector) {
            let c = 0;
            // $options.each(fun)
            for (const option of $options || []) {
                if ($(option).find(selector) !== null) {
                    c++;
                }
            }
            return c;
        }
 
        return count('[type="radio"]') === 2
            ? 3
            : count('[type="radio"]') > 2
                ? 0
                : count('[type="checkbox"]') > 2
                    ? 1
                    : count('textarea') >= 1
                        ? 4
                        : undefined;
    }
 
    function formatAnswer(res) {
        let msg = res.msg, num = res.data.num;
        let success = res.code === 200;
        if (res.code === 104) {
            msg = '积分不足请关闭收费答题答题功能\n或者请点击【获取积分】进行充值';
        }
        return {
            success,
            msg,
            num,
            list: res.data.list
        }
    }
 
    /**
     * 相似度对比
     * @param s 文本1
     * @param t 文本2
     * @param f 小数位精确度,默认2位
     * @returns {string|number|*} 百分数前的数值,最大100. 比如 :90.32
     */
 
    // similar("我不知道啊,不行","我不知道啊,不行",1)
    // xsd("我不知道啊不行", "我也不知道啊不行")
 
    function similar(s, t, f) {
        if (!s || !t) {
            return 0
        }
        if (s === t) {
            return 100;
        }
        var l = s.length > t.length ? s.length : t.length;
        var n = s.length;
        var m = t.length;
        var d = [];
        f = f || 2;
        var min = function (a, b, c) {
            return a < b ? (a < c ? a : c) : (b < c ? b : c)
        };
        var i, j, si, tj, cost;
        if (n === 0) return m
        if (m === 0) return n
        for (i = 0; i <= n; i++) {
            d[i] = [];
            d[i][0] = i;
        }
        for (j = 0; j <= m; j++) {
            d[0][j] = j;
        }
        for (i = 1; i <= n; i++) {
            si = s.charAt(i - 1);
            for (j = 1; j <= m; j++) {
                tj = t.charAt(j - 1);
                if (si === tj) {
                    cost = 0;
                } else {
                    cost = 1;
                }
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
            }
        }
        let res = (1 - d[n][m] / l) * 100;
        return res.toFixed(f)
 
    }
 
    function answerSimilar(src, list) {
        return $.map(list, function (val) {
            return similar(formatString(val), formatString(src), 2)
        })
    }
 
 
    /** 判断答案是否为A-Z的文本, 并且字符序号依次递增, 并且 每个字符是否都只出现了一次 */
    function isPlainAnswer(answer) {
        if (answer.length > 8 || !/[A-Z]/.test(answer)) {
            return false;
        }
        let counter = {};
        let min = 0;
        for (let i = 0; i < answer.length; i++) {
            if (answer.charCodeAt(i) < min) {
                return false;
            }
            min = answer.charCodeAt(i);
            counter[min] = (counter[min] || 0) + 1;
        }
        return true;
    }
 
    /**
     *
     * @param list 获取的答案列表
     * @param data 发送请求的data
     * @param $options 选项的dom
     * @param handler 执行的函数
     */
    async function defaultQuestionResolve(list, data, handler) {
        console.log(data);
        //最后的选项 集合
        let targetOptionsList = [];
        for (const answers of list) {
            console.log('当前答案', JSON.stringify(answers));
            if (data.type === 4 || data.type === 2) {
                let ans = answers.length > data.$options.length ? answers.slice(0, data.$options.length) : answers;
                ans.forEach((val, index) => {
                    handler(data.type, val, data.$options.eq(index));
                });
                return {ok: true, ans: answers.join('===='), question: data.question};
            } else if (data.type === 3) {
                if (answers.join().match(/(^|,)(正确|是|对|√|T|ri|false)(,|$)/)) {
                    if (data.options[0].match(/(^|,)(正确|是|对|√|T|ri|true)(,|$)/)) {
                        handler(data.type, '', data.$options.eq(0));
                    } else if (data.options[0].match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
                        handler(data.type, '', data.$options.eq(1));
                    }
 
 
                    return {ok: true, ans: '正确', question: data.question};
                } else if (answers.join().match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
                    if (data.options[0].match(/(^|,)(正确|是|对|√|T|ri|true)(,|$)/)) {
                        handler(data.type, '', data.$options.eq(1));
                    } else if (data.options[0].match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
                        handler(data.type, '', data.$options.eq(0));
                    }
 
                    handler(data.type, '', data.$options.eq(1));
                    return {ok: true, ans: '错误', question: data.question};
                }
            } else if (data.type === 0 || data.type === 1) {
                let targetOptions = new Set();
                //选项内容
                for (const ans of answers) {
                    if (ans.length === 1 && isPlainAnswer(ans)) {
                        const index = ans.charCodeAt(0) - 65;
                        targetOptions.add(data.$options.eq(index));
                    }
                }
                //文字内容
                answers.forEach((val, index) => {
                    val = formatString(val);
                    //精确匹配
                    let optIndex = $.inArray(val, data.options);
                    if (optIndex >= 0) {
                        targetOptions.add(data.$options.eq(optIndex));
                    } else {
                        if ((targetOptions.size > 1 && data.type === 1)) {
                            console.log('多选题已经有合适的选项,不进行模糊匹配');
                        } else {
                            //模糊匹配
                            const ratings = answerSimilar(val, data.options);
                            /**  找出最相似的选项 */
                            let max = 0;
                            ratings.forEach((rating, i) => {
                                if (rating > max) {
                                    max = rating;
                                    optIndex = i;
                                }
                            });
                            if (optIndex !== -1 && max > 60) {
                                /** 经自定义的处理器进行处理 */
                                targetOptions.add(data.$options.eq(optIndex));
                            }
                        }
                    }
                });
                //已经判断完毕
                targetOptionsList.push(targetOptions);
            }
        }
        console.log(targetOptionsList);
        let set = new Set();//最后的set集合
        let index = 0;//取用的第几个答案
        if (data.type === 0) {
            for (let targetOptionsListElement of targetOptionsList) {
                if (targetOptionsListElement && targetOptionsListElement.size === 1) {
                    set = targetOptionsListElement;
                    index = targetOptionsList.indexOf(targetOptionsListElement);
                    break;
                }
            }
        } else if (data.type === 1) {
            for (let targetOptionsListElement of targetOptionsList) {
                if (targetOptionsListElement && targetOptionsListElement.size > set.size) {
                    set = targetOptionsListElement;
                    index = targetOptionsList.indexOf(targetOptionsListElement);
                }
            }
        }
        console.log(set);
        if (set.size > 0) {
            let items = Array.from(set);
            //set 遍历无法设置延迟,转为list后循环
            for (let i in items) {
                setTimeout(() => {
                    handler(data.type, '', items[i]);
                }, i * GLOBAL.fillAnswerDelay);
            }
            await sleep(GLOBAL.fillAnswerDelay * set.size);
            return {ok: true, ans: list[index].join('===='), question: data.question};
        } else {
            return {ok: false, question: data.question, ans: list.join('====')};
        }
 
    }
 
    //HTML反转义
    function HTMLDecode(text) {
        var temp = document.createElement("div");
        temp.innerHTML = text;
        var output = temp.innerText || temp.textContent;
        temp = null;
        return output;
    }
 
    function formatString(src) {
        return (src.includes('img') ? src : HTMLDecode(src)).replace(/\s+/, ' ').replace(/[\uff01-\uff5e]/g, function (str) {
            return String.fromCharCode(str.charCodeAt(0) - 65248);
        }).replace(/^[A-Z]\./, '').replace(/\(\d+\s分\)$/, '')
            .replace(/[“”]/g, '"')
            .replace(/[‘’]/g, "'")
            .replace(/。/g, '.')
            .replace(/\+/g, '').replace(/;$/, '').toLowerCase().trim();
    }
 
 
    const TYPE = {
        单项选择题: 0,
        单选题: 0,
        多选题: 1,
        填空题: 2,
        判断题: 3,
        简答题: 4,
        名词解释: 5,
        论述题: 6,
        计算题: 7,
        其它: 8,
        分录题: 9,
        资料题: 10,
        连线题: 11,
        排序题: 13,
        完形填空: 14,
        阅读理解: 15,
        口语题: 18,
        听力题: 19,
    };
 
    /**
     * 图片url 转 base64
     * @param url
     * @returns {Promise<unknown>}
     */
    const url2Base64 = (url) => new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            url: url,
            responseType: 'blob',
            onload: function (r) {
                // "s".replaceAll()
                const fileReader = new FileReader();
                fileReader.readAsDataURL(r.response);
                fileReader.onload = (e) => {
                    resolve(e.target.result);
                };
            }
        });
    });
 
    /**
     * 图片透明背景转白色
     * @param base64
     * @returns {Promise<unknown>}
     */
    const imgHandle = (base64) => new Promise((resolve, reject) => {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
 
        const image = new Image();
        image.setAttribute("crossOrigin", 'Anonymous');
        image.src = base64;
        image.onload = function () {
            canvas.width = image.width;
            canvas.height = image.height;
            context.fillStyle = "#fff"; /// set white fill style
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.drawImage(image, 0, 0);
            canvas.toBlob((blob) => {
                resolve(blob);
            });
        };
    });
 
 
    const imgOcr = (blob) => new Promise((resolve, reject) => {
        var fd = new FormData();
        fd.append("image", blob, "1.png");
        GM_xmlhttpRequest({
            url: "https://appwk.baidu.com/naapi/api/totxt",
            method: "POST",
            responseType: 'json',
            data: fd,
            onload: function (r) {
                const res = r.response.words_result.map(item => {
                    return item.words
                }).join('');
                resolve(res);
            }
        });
    });
 
    const yuketangOcr = async url => {
        //将图片下载转 base64
        const base64 = await url2Base64(url);
        //图片转白色背景
        const img_blob = await imgHandle(base64);
        //识别图片
        const res = await imgOcr(img_blob);
        return res
    };
 
    function showPanel() {
        let html =
            `
        <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- import CSS -->
    <link rel="stylesheet" href="//lib.baomitu.com/element-ui/2.15.9/theme-chalk/index.min.css">
    <style>
      .el-table .warning-row {
        background: oldlace;
      }
      .el-table .success-row {
        background: #f0f9eb;
      }
      *{
        padding: 0px;
        margin: 0px;
      }
      .el-form-item{
        display: flex;
        justify-content: center
      }
</style>
</head>
<body>
<div id="app">
    <div id="drag_auto_answer" style="position: absolute;">
        <el-main
                class="onlinekf"
                style="min-width: 328px;margin-top: 0px;margin-left: 0px;border: 0px solid #666;width: 100%;background-color: #ffffff; padding: 15px 0px 0px; z-index: 99999;">
            <el-row>
                <el-form>
                    <el-form-item label="请输入手机号" style="margin-top: -20px">
                        <el-input v-model="opt.token" placeholder="请输入内容" style="max-width: 130px" size="mini"></el-input>
                        <el-button  @click="btnClick(opt.token,'opt.confim')" size="mini" type="warning">确定</el-button>
                    </el-form-item>
                </el-form>
            </el-row>
            <el-row style="margin-top: -20px;margin-bottom: 5px;display: flex">
                <el-alert
                        style="display: block"
                        :title="tip"
                        :closable="false"
                        type="success">
                    <el-button v-if="need_jump" @click="btnClick(opt.jump,'opt.jump')" size="mini" type="info">跳过本题</el-button>
                    <el-button v-if="!hidden" @click="btnClick(opt.auto_jump,'opt.auto_jump')" size="mini" type="warning">{{opt.auto_jump ? '停止自动切换': '开启自动切换'}}</el-button>
                </el-alert>
            </el-row>
            <el-row style="display: flex;flex-flow: wrap;width: 100%;align-items: flex-start;">
                <el-button v-if="!hidden" @click="btnClick(opt.stop,'opt.stop')" size="mini" type="success" style="margin-left: 5px">{{!opt.stop ? '暂停答题': '继续答题'}}</el-button>
                <el-button size="mini" type="info" style="margin-left: 5px">重新查询</el-button>
                <el-button @click="btnClick(opt.start_pay,'opt.start_pay')" size="mini" type="primary" style="margin-left: 5px">{{opt.start_pay ?'关闭收费题库' : '开启收费题库'}}</el-button>
                <el-button size="mini" type="danger" style="margin-left: 5px"><a style="text-decoration:none;color: aliceblue" target="_blank" href="https://lyck6.cn/pay" >获取积分</a></el-button>
            </el-row>
 
            <el-table size="mini" :data="tableData" style="width: 100%;margin-top: 5px" :row-class-name="tableRowClassName">
                <el-table-column prop="index" label="题号" width="45"></el-table-column>
                <el-table-column prop="question" label="问题" width="130"></el-table-column>
                <el-table-column prop="answer" label="答案" width="130"></el-table-column>
            </el-table>
        </el-main>
    </div>
</div>
</body>
<!-- import Vue before Element -->
<script src="//lib.baomitu.com/vue/2.6.0/vue.min.js"></script>
<!-- import JavaScript -->
<script src="//lib.baomitu.com/element-ui/2.15.9/index.js"></script>
 
<style>
  .el-table .warning-row {
    background: oldlace;
  }
 
  .el-table .success-row {
    background: #f0f9eb;
  }
</style>
<script>
    new Vue({
        el: '#app',
        data: function () {
            return {
                hidden: false,
                need_jump: false,
                tip: '正在搜索',
                opt:{
                    token: '` + GM_getValue('token') + `',
                    auto_jump: ` + GM_getValue('auto_jump') + `,
                    stop: false,
                    start_pay: `+GM_getValue('start_pay')+`
                },
                input: '',
                visible: false,
                tableData: []
            }
        },
        mounted() {
        },
        created(){
            /**
            *  油猴脚本 给 iframe 通信的方法
            * @param type 消息类型
            * @param receiveParams 消息参数
            */
            window['vueDefinedProp'] = (type,receiveParams) => {
                //**
                if (type === 'push'){
                    let length = this.tableData.length
                    this.tableData.push({index: length + 1,question: receiveParams.question,answer: receiveParams.answer,ok:receiveParams.ok})
                }else if (type === 'clear'){
                    this.tableData = []
                }else if (type === 'tip'){
                    if (receiveParams.type && receiveParams.type === 'jump'){
                         window.parent.postMessage({"type": 'jump'}, '*');
                    }else if (receiveParams.type && receiveParams.type === 'error'){
                         this.need_jump = true
                    }else if (receiveParams.type && receiveParams.type === 'hidden'){
                         this.hidden = true
                    }else if (receiveParams.type && receiveParams.type === 'stop'){
                         this.opt.stop = true
                    }
 
                    this.tip = receiveParams.tip
                }
            }
        },
        methods: {
            tableRowClassName({row, rowIndex}) {
                return row.ok ? 'success-row': 'warning-row'
            },
            btnClick(e,type){
                if (type === 'opt.stop'){//暂停搜索
                    this.opt.stop = !this.opt.stop
                    this.tip = this.opt.stop? '已暂停搜索': '继续搜索'
                     window.parent.postMessage({type: 'stop',val:this.opt.stop}, '*');
                }else if (type === 'opt.start_pay'){
                    this.opt.start_pay = ! this.opt.start_pay
                     window.parent.postMessage({type: 'start_pay',flag:this.opt.start_pay}, '*');
                }else if (type === 'opt.auto_jump'){//开启自动切换
                    this.opt.auto_jump = ! this.opt.auto_jump
                    window.parent.postMessage({type: 'auto_jump',flag:this.opt.auto_jump}, '*');
                }else if (type === 'opt.jump'){//跳过本题
                    window.parent.postMessage({type: 'jump'}, '*');
                    this.need_jump = false
                }else if (type === 'opt.confim'){
                    window.parent.postMessage({type: 'confim',token:e}, '*');
                }
            }
        }
    })
</script>
</html>
`;
        addModal2(html);
    }
    function addModal2(html, newPos, footerChildNode = false) {
        // // // header link
        let headersNode = createContainer('headers-node');
        let adNode = exports.top.document.createElement('img');
        adNode.setAttribute('src', 'http://lyck6.cn/img/6.png');
        adNode.setAttribute("draggable", "false");
        adNode.setAttribute("width", "98%");
        adNode.setAttribute("height", "121px");
        adNode.setAttribute("style", "display: block;margin-bottom: -2%;padding-left: 1%;");
        // linkNode.setAttribu/te('data-seindex', 0);
        // linkNode.setAttribute('data-seclass', 'baidu');
        // linkNode.innerHTML =
        // linkNode.setAttribute('data-securrent', 'true');
        // linkNode.style.color = '#586069';
        //
        // linkNode.addEventListener('click', function () {
        //     window.open('https://www.itihey.com')
        // });
        //
        headersNode.appendChild(adNode);
 
 
        // iframe
        let iframeNode = exports.top.document.createElement('iframe');
        iframeNode.id = 'iframeNode';
        iframeNode.setAttribute('width', '100%');
        iframeNode.setAttribute("height", "350px");
        iframeNode.setAttribute('frameborder', '0');
        iframeNode.srcdoc = html;
 
        // let headerNode = createContainer('hcsearche-modal-header', [linksNode]);
        // let bodyNode = createContainer('hcsearche-modal-body', iframeNode);
        //
        // let footerNode = createContainer('hcsearche-modal-footer', footerChildNode);
        //
        let contentNode = createContainer('content-modal', [headersNode, iframeNode]);
 
        let modal = renderModal(contentNode);
        // return model
        dragModel(modal);
    }
 
 
    // 搜索窗口可以根据设置决定是相对文档还是相对窗口定位
    function renderModal(childElem, newPos) {
        //不是自动关闭就是绝对定位 或者依据用户设置
        return render('modal', 'model-id', childElem);
    }
 
    function render(tagName, elemId, childElem, isFixed, newPos) {
        // console.log('开始渲染 model', isFixed)
        let doc = exports.top.document;
        let elem = doc.getElementById(elemId);
        if (elem) {
            elem.innerHTML = '';
        } else {
            elem = doc.createElement(tagName);
            elem.id = elemId;
            doc.body.appendChild(elem);
        }
        let contentNode = createContainer(tagName + '-container', childElem);
        elem.appendChild(contentNode);
        // class ID same
        elem.classList.add(elemId);
        // let X = false;
        // let Y = false;
        // if (!newPos) {
        //     X = elem.style.left.replace('px', '');
        //     console.log(X, "X")
        //     Y = elem.style.top.replace('px', '');
        // }
        // if (!X) {
        //     let pos = getXY(elem.offsetWidth, elem.offsetHeight);
        //     X = pos.X;
        //     Y = pos.Y;
        //     // 相对文档定位时需要将文档滚动距离加上
        //     if (!isFixed) {
        //         Y += window.pageYOffset;
        //     }
        // }
        elem.style.zIndex = '9999999';
        // elem.style.width = '430px'
        // elem.style.height = '660px'
        elem.style.position = 'fixed';
        elem.style.left = '30px';
        elem.style.top = '30px';
        setTimeout(function () {
            elem.classList.add(elemId + '-show');
        }, 10);
        return elem;
    }
 
    async function searchAnswer(data) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST",
                url: "https://lyck6.cn/api/autoAnswer/" + (GM_getValue('start_pay') ? GM_getValue('token') : 0),
                headers: {
                    "Content-Type": "application/json;charset=utf-8",
                    "Version": GM_info.script.version
                },
                data: JSON.stringify(data),
                timeout: 10 * 1000,
                onload: function (r) {
                    console.log(r.responseText);
                    resolve(JSON.parse(r.responseText));
                },
                onerror: function (e) {
                    reject(e);
                }
            });
        })
 
    }
 
    /**
     * 自动答题核心代码
     */
 
    /**
     *
     * @param select 选择的元素{
     *             root: '.questionLi',
     *             elements: {
     *                 question: 'h3 div',
     *                 options: '.answerBg .answer_p, .textDIV, .eidtDiv',
     *                 type: 'input[name^=type]:eq(0)'
     *             }
     *         }
     * @param searchHander 规范化 题目 选项 类型
     * @param fillHander 填充答案的函数
     * @param onFinish 答题完成之后的回调函数 need_jump是否需要跳转
     * @constructor
     */
 
    var WorkerJS = function (select, searchHander, fillHander, onFinish = function (need_jump) {
    }, fillFinish = function () {
    }) {
 
        GLOBAL.index = 0;
        /**
         * 根据传入的 元素进行初始化
         */
        this.init = async function ($TiMu, select) {
            let question = formatString(filterImg($TiMu.find(select.elements.question)));
            let data = {
                question: question.length === 0 ? $TiMu.find(select.elements.question) : question,
                $options: $TiMu.find(select.elements.$options),
                options: jQuery.map($TiMu.find(select.elements.options), function (val) {
                    return formatString(filterImg(val))
                })
            };
            data.type = select.elements.type ? ($TiMu.find(select.elements.type).text() || $TiMu.find(select.elements.type).val()) : $TiMu;
 
            return await searchHander(data)
 
        };
 
        this.fillAnswer = async function () {
            let arr = jQuery(select.root);
            console.log(arr.length);
            GLOBAL.setInterval = async () => {
                console.log('当前index', GLOBAL.index);
                if (GLOBAL.index >= arr.length) {
                    clearInterval(GLOBAL.loop);
                    delete GLOBAL.loop;
                    let auto_jump = GM_getValue('auto_jump') === undefined || GM_getValue('auto_jump');
 
                    //答题事件监听,如果完成还要继续重新运行则返回 true
                    const next = onFinish(auto_jump);
                    if (next) {
                        GLOBAL.index = 0;
                        setTimeout(() => {
                            this.fillAnswer();
                        }, GLOBAL.time);
                    }
 
 
                    if (auto_jump) {
                        iframeMsg('tip', {type: 'jump', tip: '自动答题已完成,即将切换下一题'});
                        //如果在5秒内 没有切换就是答题完成了
                        next || setTimeout(() => {
                            iframeMsg('tip', {type: 'hidden', tip: '自动答题已完成,请检查提交'});
                        }, GLOBAL.time);
                    } else {
                        iframeMsg('tip', {tip: '自动答题已完成' + (arr.length === 1 ? ',请手动切换' : '请检查提交')});
                    }
 
                    return true
                }
                try {
                    let data = await this.init(jQuery(arr[GLOBAL.index++]), select);// arr[GLOBAL.index]
                    if (!data) return
                    iframeMsg('tip', {tip: '准备答第' + (GLOBAL.index) + '题'});
                    //格式化返回答案 成为二维数组
                    const formatAns = data.answer ? {
                        success: true,
                        num: '免费',
                        list: [data.answer]
                    } : formatAnswer(await searchAnswer({question: data.question}));
                    if (formatAns.success) {
                        //解析答案
                        iframeMsg('tip', {tip: '准备填充答案,' + (formatAns.num.includes('免费题库') ? '免费题库不扣积分' : '剩余积分:' + formatAns.num)});
                        let r = await defaultQuestionResolve(formatAns.list, data, fillHander);
                        iframeMsg('push', {index: GLOBAL.index, question: r.question, answer: r.ans, ok: r.ok});
                    } else {
                        iframeMsg('tip', {tip: formatAns.msg});
                    }
 
                } catch (e) {
                    iframeMsg('tip', {type: 'error', tip: '发生异常' + e});
                } finally {
                    fillFinish();
                }
 
            };
 
            GLOBAL.loop = setInterval(GLOBAL.setInterval, GLOBAL.time);
            console.log('GLOBAL.loop', GLOBAL.loop);
        };
    };
 
    /**
     * 借鉴 网页限制解除(改)
     * 原作者 qxin i
     * 开源地址 https://greasyfork.org/zh-CN/scripts/28497-%E7%BD%91%E9%A1%B5%E9%99%90%E5%88%B6%E8%A7%A3%E9%99%A4-%E6%94%B9/code
     */
    // 初始化 init func  这里才是核心
    function init() {
        rule = rwl_userData.rules.rule_def;
        hook_eventNames = rule.hook_eventNames.split("|");
        // TODO Allowed to return value
        unhook_eventNames = rule.unhook_eventNames.split("|");
        eventNames = hook_eventNames.concat(unhook_eventNames);
 
        if (rule.dom0) {
            setInterval(clearLoop, 10 * 1000);
            setTimeout(clearLoop, 1500);
            window.addEventListener('load', clearLoop, true);
            clearLoop();
        }
 
        // hook addEventListener //导致搜索跳转失效的原因
        if (rule.hook_addEventListener) {
            EventTarget.prototype.addEventListener = addEventListener;
            document.addEventListener = addEventListener;
            if (hasFrame) {
                for (let i = 0; i < hasFrame.length; i++) {
                    hasFrame[i].contentWindow.document.addEventListener = addEventListener;
                }
            }
        }
 
        // hook preventDefault
        if (rule.hook_preventDefault) {
            Event.prototype.preventDefault = function () {
                if (hook_eventNames.indexOf(this.type) < 0) {
                    Event_preventDefault.apply(this, arguments);
                }
            };
 
            if (hasFrame) {
                for (let i = 0; i < hasFrame.length; i++) {
                    hasFrame[i].contentWindow.Event.prototype.preventDefault = function () {
                        if (hook_eventNames.indexOf(this.type) < 0) {
                            Event_preventDefault.apply(this, arguments);
                        }
                    };
                }
            }
        }
 
        // Hook set returnValue
        if (rule.hook_set_returnValue) {
            Event.prototype.__defineSetter__('returnValue', function () {
                if (this.returnValue !== true && hook_eventNames.indexOf(this.type) >= 0) {
                    this.returnValue = true;
                }
            });
        }
    }
 
    // Hook addEventListener proc
    function addEventListener(type, func, useCapture) {
        var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
        if (hook_eventNames.indexOf(type) >= 0) {
            _addEventListener.apply(this, [type, returnTrue, useCapture]);
        } else if (unhook_eventNames.indexOf(type) >= 0) {
            var funcsName = storageName + type + (useCapture ? 't' : 'f');
 
            if (this[funcsName] === undefined) {
                this[funcsName] = [];
                _addEventListener.apply(this, [type, useCapture ? unhook_t : unhook_f, useCapture]);
            }
 
            this[funcsName].push(func);
        } else {
            _addEventListener.apply(this, arguments);
        }
    }
 
    // 清理循环
    function clearLoop() {
        rule = clear(); // 对于动态生成的节点,随时检测
        var elements = getElements();
 
        for (var i in elements) {
            for (var j in eventNames) {
                var name = 'on' + eventNames[j];
                if (Object.prototype.toString.call(elements[i]) == "[object String]") {
                    continue;
                }
                if (elements[i][name] !== null && elements[i][name] !== onxxx) {
                    if (unhook_eventNames.indexOf(eventNames[j]) >= 0) {
                        elements[i][storageName + name] = elements[i][name];
                        elements[i][name] = onxxx;
                    } else {
                        elements[i][name] = null;
                    }
                }
            }
        }
 
        document.onmousedown = function () {
            return true;
        };
    }
 
    // 返回true的函数
    function returnTrue(e) {
        return true;
    }
 
    function unhook_t(e) {
        return unhook(e, this, storageName + e.type + 't');
    }
 
    function unhook_f(e) {
        return unhook(e, this, storageName + e.type + 'f');
    }
 
    function unhook(e, self, funcsName) {
        var list = self[funcsName];
        for (var i in list) {
            list[i](e);
        }
 
        e.returnValue = true;
        return true;
    }
 
    function onxxx(e) {
        var name = storageName + 'on' + e.type;
        this[name](e);
 
        e.returnValue = true;
        return true;
    }
 
    // 获取所有元素 包括document
    function getElements() {
        var elements = Array.prototype.slice.call(document.getElementsByTagName('*'));
        elements.push(document);
 
        // 循环所有 frame 窗口
        var frames = document.querySelectorAll("frame");
        if (frames) {
            hasFrame = frames;
            var frames_element;
            for (let i = 0; i < frames.length; i++) {
                frames_element = Array.prototype.slice.call(frames[i].contentWindow.document.querySelectorAll("*"));
                elements.push(frames[i].contentWindow.document);
                elements = elements.concat(frames_element);
            }
        }
        return elements;
    }
 
 
    var settingData = {
        "status": 1,
        "version": 0.1,
        "message": "",
        "positionTop": "0",
        "positionLeft": "0",
        "positionRight": "auto",
        "addBtn": false,
        "connectToTheServer": false,
        "waitUpload": [],
        "currentURL": "null",
        "shortcut": 3,
        // 域名规则列表
        "rules": {},
        "data": []
    };
 
    var rwl_userData = null;
    var rule = null;
    var hasFrame = false;
 
    // 储存名称
    var storageName = "storageName";
    // 要处理的 event 列表
    var hook_eventNames, unhook_eventNames, eventNames;
    // 储存被 Hook 的函数
    var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
    var document_addEventListener = document.addEventListener;
    var Event_preventDefault = Event.prototype.preventDefault;
 
    // 查看本地是否存在旧数据
    rwl_userData = GM_getValue("rwl_userData");
    if (!rwl_userData) {
        rwl_userData = settingData;
    }
    // 自动更新数据
    for (let value in settingData) {
        if (!rwl_userData.hasOwnProperty(value)) {
            rwl_userData[value] = settingData[value];
            GM_setValue("rwl_userData", rwl_userData);
        }
    }
 
 
 
 
    /**
     * 原作者 wyn665817@163.com
     * 开源地址 https://scriptcat.org/script-show-page/432/code
     * 特别感谢 wyn大佬 提供的 字典匹配表
     */
    function removeF() {
        var md5 = $.md5;
        // 判断是否存在加密字体
        var $tip = $('style:contains(font-cxsecret)');
        if (!$tip.length) return;
 
    // 解析font-cxsecret字体
        var font = $tip.text().match(/base64,([\w\W]+?)'/)[1];
        font = Typr.parse(base64ToUint8Array(font))[0];
 
    // 匹配解密字体
        var table = JSON.parse(GM_getResourceText('Table'));
        var match = {};
        for (var i = 19968; i < 40870; i++) { // 中文[19968, 40869]
            $tip = Typr.U.codeToGlyph(font, i);
            if (!$tip) continue;
            $tip = Typr.U.glyphToPath(font, $tip);
            $tip = md5(JSON.stringify($tip)).slice(24); // 8位即可区分
            match[i] = table[$tip];
        }
 
    // 替换加密字体
        $('.font-cxsecret').html(function (index, html) {
            $.each(match, function (key, value) {
                key = String.fromCharCode(key);
                key = new RegExp(key, 'g');
                value = String.fromCharCode(value);
                html = html.replace(key, value);
            });
            return html;
        }).removeClass('font-cxsecret'); // 移除字体加密
 
        function base64ToUint8Array(base64) {
            var data = window.atob(base64);
            var buffer = new Uint8Array(data.length);
            for (var i = 0; i < data.length; ++i) {
                buffer[i] = data.charCodeAt(i);
            }
            return buffer;
        }
    }
 
 
    function start() {
 
        setInterval(function () {
            try {removeF();} catch (e) {}
            try {init();} catch (e) {}
 
        }, 500);
    }
 
    function chaoxingOldExam() {
        showPanel();
        setTimeout(() => {
            new WorkerJS({
                root: '.TiMu',
                elements: {
                    question: '.Cy_TItle .clearfix',
                    options: '.Cy_ulTop .clearfix',//文字的选项列表
                    $options: ':radio, :checkbox, .Cy_ulTk textarea',//绑定的事件的 dom列表
                    type: '[name^=type]:not([id])'
                }
            }, (obj) => {
                obj.type = parseInt(obj.type);
                if (obj.type === 3) {
                    obj.options = ['正确', '错误'];
                }
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 3 || type === 1) {
                    $option.get(0).click();
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option.attr('name')).setContent(answer);
                }
            }, (auto_jump) => {
                auto_jump && setInterval(function() {
                    const btn = $('.saveYl:contains(下一题)').offset();
                    var mouse = document.createEvent('MouseEvents'),
                        arr = [btn.left + Math.ceil(Math.random() * 80), btn.top + Math.ceil(Math.random() * 26)];
                    mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, arr[0], arr[1], false, false, false, false, 0, null);
                    _self.event = $.extend(true, {}, mouse);
                    delete _self.event.isTrusted;
                    _self.getTheNextQuestion(1);
                }, Math.ceil(GLOBAL.time * Math.random()) * 2);
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
 
    /**
     * 超星章节测验,新版旧版通用
     */
    function chaoxingQuiz() {
        removeF();
        showPanel();
        setTimeout(() => {
            new WorkerJS({
                root: '.clearfix .TiMu',
                elements: {
                    question: '.Zy_TItle .clearfix',
                    options: 'ul:eq(0) li .after',//文字的选项列表
                    $options: 'ul:eq(0) li :radio,:checkbox,textarea',//绑定的事件的 dom列表
                    type: 'input[name^=answertype]'
                }
            }, (obj) => {
                obj.question = obj.question.replace(/\s+/g,'');
                obj.type = parseInt(obj.type);
                if (obj.type === 3) {
                    obj.options = ['正确', '错误'];
                }
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 3 || type === 1) {
                    $option.get(0).click();
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option.attr('name')).setContent(answer);
                }
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
    function chaoxingNewWork() {
        showPanel();
        setTimeout(() => {
            let cxWork = new WorkerJS({
                root: '.questionLi',
                elements: {
                    question: 'h3',
                    options: '.stem_answer .answerBg .answer_p, .textDIV, .eidtDiv',
                    $options: '.stem_answer .answerBg, .textDIV, .eidtDiv',
                    type: 'input[type^=hidden]:eq(0)'
                }
            }, (obj) => {
                obj.type = parseInt(obj.type);
                //多选题清楚样式,清楚已经保存的结果
                obj.type === 1 && $.each(obj.$options, (index, val) => {
                    $(val).find('.check_answer,.check_answer_dx').length === 1 && $(val).click();
                });
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 1 || type === 3) {
                    if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                        $option.click();
                    }
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option.find('textarea').attr('name')).setContent(answer);
                }
            }, (auto_jump) => {
                /**
                 * 答题成功之后要跳转了
                 */
                auto_jump && setTimeout(() => {
                    $('.nextDiv .jb_btn:contains("下一题")').click();
                }, GLOBAL.time / 5);
            });
            cxWork.fillAnswer();
        }, GLOBAL.delay);
    }
 
 
    function chaoxingNewExam(i) {
        showPanel();
        setTimeout(() => {
            let cxWork = new WorkerJS({
                root: '.questionLi',
                elements: {
                    question: 'h3 div',
                    options: '.answerBg .answer_p, .textDIV, .eidtDiv',
                    $options: '.answerBg, .textDIV, .eidtDiv',
                    type: 'input[name^=type]:eq(' + i + ')'
                }
            }, (obj) => {
                obj.type = parseInt(obj.type);
                //多选题清楚样式,清楚已经保存的结果
                obj.type === 1 && $.each(obj.$options, (index, val) => {
                    $(val).find('.check_answer,.check_answer_dx').length === 1 && $(val).click();
                });
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 1 || type === 3) {
                    if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                        $option.click();
                    }
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option.find('textarea').attr('name')).setContent(answer);
                }
            }, (auto_jump) => {
                /**
                 * 答题成功之后要跳转了
                 */
                auto_jump && setTimeout(() => {
                    $('.nextDiv .jb_btn:contains("下一题")').click();
                }, GLOBAL.time / 5);
            });
            cxWork.fillAnswer();
        }, GLOBAL.delay);
    }
 
    function ZjyExam() {
        showPanel();
        setTimeout(() => {
            GM_xmlhttpRequest({
                method: "GET",
                url: 'https://lyck6.cn/api/init/zjy?id='+unsafeWindow.examRecordId,
                timeout: 10 * 1000,
                onload: function (r) {
                    console.log('初始化',r.responseText);
                }
            });
            new WorkerJS({
                root: '.q_content',
                elements: {
                    question: '.divQuestionTitle',
                    options: '.questionOptions .q_option',
                    $options: '.questionOptions .q_option'
                }
            }, (obj) => {
                obj.question = obj.question.replace(/^\d+、/, '').replace(/(\d+\s+分)$/, '');
                obj.type = defaultWorkTypeResolver(obj.$options);
                obj.options = $.map(obj.options, (val) => {
                    return formatString(val.replace(/[A-G][.|\\.\s+]/, '')).trim()
                });
                return obj
            }, (type, answer, $option) => {
                $option = $option.find('div');
                if (type === 0 || type === 3) {
                    $option.click();
                } else if (type === 1) {
                    if ($option.attr('class') !== 'checkbox_on') {
                        $option.click();
                    }
                }
            }, () => {
                /**
                 * 答题完成的监听
                 */
                if ($('.paging_next').attr('style').includes('block')) {
                    //如果有下一页
                    $('.paging_next').click();
                    return true
                }
 
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
    function mooc_icve_com_cn() {
        showPanel();
        setTimeout(() => {
            new WorkerJS({
                root: '.e-q-r',
                elements: {
                    question: '.e-q-q .ErichText',
                    options: '.e-a-g li .ErichText',
                    $options: 'li',
                    type: '.quiz-type'
                }
            }, (obj) => {
                obj.type = TYPE[obj.type.replaceAll(/\s+/g,'')];
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 3) {
                    $option.click();
                } else if (type === 1) {
                    if (!$option.attr('class').includes('checked')) {
                        $option.click();
                    }
                }
            }, () => {
                /**
                 * 答题完成的监听
                 */
                // if ($('.paging_next').attr('style').includes('block')) {
                //     //如果有下一页
                //     $('.paging_next').click()
                //     return true
                // }
 
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
    function zjyold() {
        showPanel();
        setTimeout(() => {
            new WorkerJS({
                root: '.e-q-r',
                elements: {
                    question: '.e-q-q .ErichText',
                    options: '.e-a-g li,li .ErichText',
                    $options: '.e-a-g li',
                    type: '.quiz-type'
                }
            }, (obj) => {
                obj.type = TYPE[obj.type.replaceAll(/\s+/g,'')];
                obj.options = obj.options.map(i=>{
                    return i.replace(/^[ab]\)\s+/,'').replace(/^[a-z]\s+/,'').trim()
                });
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 3) {
                    $option.click();
                } else if (type === 1) {
                    if (!$option.attr('class').includes('checked')) {
                        $option.click();
                    }
                }
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
    function zhsExam() {
        console.log("我走到这;zhsExam");
        showPanel();
        setTimeout(() => {
            // sleep(3000)
            new WorkerJS({
                root: '.examPaper_subject',
                elements: {
                    question: '.subject_describe div',
                    options: '.subject_node .nodeLab .node_detail',//文字的选项列表
                    $options: '.subject_node .nodeLab',//绑定的事件的 dom列表
                    type: '.subject_type span:eq(0)'
                }
            }, (obj) => {
 
                obj.question = obj.question.get(0).__vue__._data.shadowDom.textContent;
                obj.type = TYPE[obj.type.match('【(.*)】')[1]];
                //多选题清楚样式,清楚已经保存的结果
                obj.type === 1 && $.each(obj.$options, (index, val) => {
                    $(val).find('.node_detail').hasClass('onChecked') && $(val).click();
                });
                if ($(".yidun_popup").hasClass('yidun_popup--light')){
                    console.log('我到这了',GLOBAL.loop);
                    iframeMsg('tip', {type: 'stop', tip: '答题暂停,请自行通过验证'});
                    clearInterval(GLOBAL.loop);
                    delete GLOBAL.loop;
                    return undefined
                }
 
                return obj
            }, (type, answer, $option) => {
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    $option.click();
                    // $('.el-button:contains(下一题)').click()
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }, () => {
                setTimeout(() => {
                    $('.el-button:contains(保存)').click();
                }, GLOBAL.time / 3);
            }, () => {
                setTimeout(() => {
                    $('.el-button:contains(下一题)').click();
                }, GLOBAL.time / 3);
            }).fillAnswer();
        }, GLOBAL.delay*1.5);
    }
 
    function zhsIntegral() {
        showPanel();
        setTimeout(() => {
            // sleep(3000)
            let zhsIn = new WorkerJS({
                root: '.questionBox',
                elements: {
                    question: '.questionContent',
                    options: '.optionUl label .el-radio__label',//文字的选项列表
                    $options: '.optionUl label',//绑定的事件的 dom列表
                    type: '.questionTit'
                }
            }, (obj) => {
                obj.type = TYPE[obj.type.match('【(.*)】')[1]];
                //多选题清楚样式,清楚已经保存的结果
                obj.type === 1 && $.each(obj.$options, (index, val) => {
                    $(val).find('.el-radio__input').hasClass('is-checked') && $(val).click();
                });
                obj.options = obj.options.map(item=>{
                    return formatString(item.replaceAll(/^[a-zA-Z]\./g,''))
                });
                if ($(".yidun_popup").hasClass('yidun_popup--light')){
                    console.log('我到这了',GLOBAL.loop);
                    iframeMsg('tip', {type: 'stop', tip: '答题暂停,请自行通过验证'});
                    clearInterval(GLOBAL.loop);
                    delete GLOBAL.loop;
                    return undefined
                }
 
                return obj
            }, (type, answer, $option) => {
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    $option.click();
                    // $('.el-button:contains(下一题)').click()
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }, () => {
                if ($('.Nextbtndiv .Topicswitchingbtn-gray:contains(下一题)').hasClass('Topicswitchingbtn-gray')) return false
                setTimeout(() => {
                    $('.Nextbtndiv .Topicswitchingbtn:contains(下一题)').click();
                }, GLOBAL.time / 5);
                return true
            });
            zhsIn.fillAnswer();
        }, GLOBAL.delay);
    }
 
    function ybkExam() {
        console.log("我走到这;ybkExam");
        showPanel();
        setTimeout(() => {
            // sleep(3000)
            new WorkerJS({
                root: '.topic-item',
                elements: {
                    question: '.t-con .t-subject',
                    options: '.t-option  .el-radio__label .option-content',//文字的选项列表
                    $options: '.t-option .el-radio__input .nodeLab',//绑定的事件的 dom列表
                    type: '.t-info .t-type'
                }
            }, (obj) => {
                obj.type = TYPE[obj.type];
                return obj
            }, (type, answer, $option) => {
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    $option.click();
                    // $('.el-button:contains(下一题)').click()
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }).fillAnswer();
        }, GLOBAL.delay*1.5);
    }
 
    function hookJSON() {
        const parse = JSON.parse;
        JSON.parse = function (s) {
            const o = parse(s);
            if (location.pathname === '/study/works/works.html') {
                if (o.paper){
                    GLOBAL.json = parseIcve(o.paper.PaperQuestions);
                }
            } else if (location.pathname === '/study/exam/exam.html') {
                if (o.array) {
                    let arr = [];
                    for (let arrayElement of o.array) {
                        arr.push(...arrayElement.Questions);
                    }
                    GLOBAL.json = parseIcve(arr);
                }
            }else if (location.pathname.includes('/v2/web/cloud/student/exercise/')){
                if (o.data && o.data.problems){
                    GLOBAL.json = parseYkt(o.data.problems);
                    // console.log(JSON.stringify(collectYkt(o.data.problems)))
                }
 
            }else if (location.host === 'examination.xuetangx.com' && location.pathname.includes('/exam/') ){
                if (o.data && o.data.problems){
                    GLOBAL.json = parseYktExam(o.data.problems);
                    // console.log(JSON.stringify(collectYkt(o.data.problems)))
                }
            }
 
            return o
        };
    }
    function parseYkt(problems){
        return problems.map(item=>{
            const type = TYPE[item.content.TypeText];
            if (type === 2 || type === 4){
                return {
                    question: filterImg($(item.content.Body)),
                    type
                }
            }
            return {
                question: formatString(item.content.Body),
                options: item.content.Options.map(i=>{return formatString(type === 3 ? i.key :i.value)}),
                type
            }
        })
    }
    function parseYktExam(problems){
        return problems.map(item=>{
            const type = TYPE[item.TypeText];
            if (type === 2 || type === 4){
                return {
                    question: formatString(item.Body),
                    type
                }
            }
            return {
                question: formatString(item.Body),
                options: item.Options.map(i=>{return formatString(type === 3 ? i.key :i.value)}),
                type
            }
        })
    }
 
    function parseIcve(questions) {
        return questions.map(item => {
            const options = item.Selects.map(opt => {
                return formatString(opt)
            });
            const type = TYPE[item.ACHType.QuestionTypeName];
            const answer = item.Answers.map(key => {
                if (type === 0 || type === 1) {
                    return options[key.charCodeAt() - 65]
                } else if (type === 3) {
                    return key === '1' ? '正确' : '错误'
                }
 
            });
            const answerKey = (type === 0 || type === 1) ? item.Answers : answer;
            return {
                id: item.Id,
                question: item.ContentText,
                answerKey,
                options,
                answer,
                type
            }
        })
    }
 
    /**
     * http://www.icve.com.cn/study/works/works.html
     */
    function icve_works() {
        hookJSON();
 
        function get_element(id) {
            for (let jsonElement of GLOBAL.json) {
                if (jsonElement.id === id) {
                    return jsonElement
                }
            }
        }
 
        showPanel();
        setTimeout(() => {
            console.log(GLOBAL.json);
            new WorkerJS({
                root: '.questions',
                elements: {
                    question: '.tigan',
                    options: 'label ',//文字的选项列表
                    $options: '.dy_input',//绑定的事件的 dom列表
                    type: 'input[name^=paperItemId]'
                }
            }, (obj) => {
                const ele = get_element(obj.type);
                obj.question = ele.question;
                obj.answer = ele.answerKey ? ele.answerKey : ele.answer;
                obj.type = ele.type;
                return obj
            }, (type, answer, $option) => {
                if (type === 0 || type === 3 || type === 1) {
                    $option.get(0).click();
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option.attr('name')).setContent(answer);
                }
            }).fillAnswer();
        }, GLOBAL.delay);
    }
 
    async function collectYkt() {
        const class_room_id = location.pathname.split('/').pop();
        const instance = axios.create({
            timeout: 10 * 1000,
            headers: {
                'xtbz': 'ykt',
                'classroom-id': class_room_id
            }
        });
        const res1 = await instance.get('https://www.yuketang.cn/v2/api/web/logs/learn/' + class_room_id + '?actype=-1&page=0&offset=20&sort=-1');
        const courseware_id = res1.data.data.activities[0].courseware_id;
 
        const res2 = await instance.get(`https://www.yuketang.cn/c27/online_courseware/xty/kls/pub_news/${courseware_id}/`);
        const content_info = res2.data.data.content_info;
        for (const content of content_info) {
            for (let leaf of content.leaf_list) {
                if (leaf.leaf_type === 6) {
                    const res3 = await instance.get(`https://www.yuketang.cn/mooc-api/v1/lms/learn/leaf_info/${class_room_id}/${leaf.id}/`);
                    const res4 = await instance.get('https://www.yuketang.cn/mooc-api/v1/lms/exercise/get_exercise_list/' + res3.data.data.content_info.leaf_type_id + '/');
                    // console.log(res4.data)
                    console.log(JSON.stringify(collectYktWork(res4.data.data.problems)));
                }
            }
        }
 
        function collectYktWork(collect) {
            return collect.map(item => {
                const type = TYPE[item.content.TypeText];
                const options = item.content.Options.map(i => {
                    return (type === 3 ? i.key : i.value)
                });
                try {
                    if (item.user.is_show_answer && item.user.answer) {
                        console.log(item.user);
                        return {
                            question: (item.content.Body),
                            options,
                            answer: (typeof item.user.answer === 'string' ? item.user.answer.split('') : item.user.answer).map(as => {
                                if (as.match(/[A-G]/)) {
                                    return options[as.charCodeAt() - 65]
                                } else {
                                    return as
                                }
                            }),
                            type
                        }
                    }
                } catch (e) {
                    console.log(e);
                }
 
            }).filter(item1 => item1 !== undefined)
        }
 
    }
 
    function yktOldExam() {
        showPanel();
        setTimeout(() => {
            new WorkerJS({
                root: '.problem_item',
                elements: {
                    question: '.notBullet:eq(0)',
                    options: '.notBullet:gt(0)',//文字的选项列表
                    $options: '.problembullet',//绑定的事件的 dom列表
                }
            }, async (obj) => {
                const $item = obj.type;
 
                var tmp = $item.find('.ptype').clone();
                tmp.children().remove();
                obj.type = TYPE[tmp.text().replaceAll(/\s+/g, '')];
                obj.question = await yuketangOcr(obj.question.attr('data-background'));
 
                if (obj.$options.length === 2) {
                    obj.options = ['正确', '错误'];
                } else {
                    const opt = [];
                    for (const tmpElement of $item.find('.notBullet:gt(0)')) {
                        opt.push(await yuketangOcr(jQuery(tmpElement).attr('data-background')));
                    }
                    obj.options = opt;
                }
 
                return obj
 
            }, (type, answer, $option) => {
                console.log($option);
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    if (!$option.hasClass('is-checked')) {
                        $option.click();
                    }
                    // $('.el-button:contains(下一题)').click()
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }).fillAnswer();
        }, GLOBAL.delay * 1.5);
    }
 
 
    function yktExam() {
 
        hookJSON();
        showPanel();
        setTimeout(() => {
            console.log(GLOBAL.json);
            // sleep(3000)
            // $('.')
            new WorkerJS({
                root: '.exam-main--body .subject-item',
                elements: {
                    question: '.item-body .problem-body ,p',
                    options: '.item-body ul li',//文字的选项列表
                    $options: '.item-body ul label, .blank-item-dynamic',//绑定的事件的 dom列表
                    type: '.item-type'
                }
            }, async (obj) => {
                console.log(obj);
                const ele = GLOBAL.json[GLOBAL.index-1];
                // obj.$options = document.querySelector('.subject-item')
                obj.type = ele.type;
                obj.options = ele.options;
                obj.question = ele.question;
                if (obj.type === 1){
                    for (let val of obj.$options) {
                        jQuery(val).hasClass('is-checked') && jQuery(val).click();
                        await sleep(500);
                    }
                }
                return obj
 
            }, (type, answer, $option) => {
                console.log($option);
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    if (!$option.hasClass('is-checked')) {
                        $option.click();
                    }
                    // $('.el-button:contains(下一题)').click()
                } else if (type === 4 || type === 2) {
                    UE.getEditor($option).setContent(answer);
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }).fillAnswer();
        }, GLOBAL.delay * 1.5);
    }
 
 
    function yktText() {
 
        hookJSON();
        showPanel();
        setTimeout(() => {
            console.log(GLOBAL.json);
            // sleep(3000)
            // $('.')
            new WorkerJS({
                root: '.container-problem .subject-item',
                elements: {
                    // question: '.item-body .problem-body ,p',
                    // options: '.item-body ul li',//文字的选项列表
                    $options: '.item-body ul label',//绑定的事件的 dom列表
                    type: '.item-type'
                }
            }, async (obj) => {
                console.log(obj);
                //测验题号
                const index = obj.type.trim().match(/^(\d+)/)[1];
                obj.index = index - 1;
                const ele = GLOBAL.json[obj.index];
                obj.type = ele.type;
                obj.options = ele.options;
                obj.question = ele.question;
                if (obj.type === 1) {
                    for (let val of obj.$options) {
                        jQuery(val).hasClass('is-checked') && jQuery(val).click();
                        await sleep(500);
                    }
                }
                console.log(obj);
                return obj
 
            }, (type, answer, $option) => {
                console.log($option);
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    if (!$option.hasClass('is-checked')) {
                        $option.click();
                    }
                    // $('.el-button:contains(下一题)').click()
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }, (need_jump) => {
                if ($('.el-button--text:contains(下一题)').hasClass('is-disabled')) return false
                // if (ne)
                need_jump && setTimeout(() => {
                    $('.el-button--text:contains(下一题)').click();
                }, GLOBAL.time / 3);
                return need_jump
            }).fillAnswer();
        }, GLOBAL.delay * 1.5);
    }
 
    function zgdzText() {
        console.log("我走到这;zgdzText");
        showPanel();
        setTimeout(() => {
            // sleep(3000)
            new WorkerJS({
                root: '.stViewItem',
                elements: {
                    question: '.stViewHead  div',
                    options: '.stViewCont  .stViewOption a',//文字的选项列表
                    $options: '.stViewCont  .stViewOption a,input',//绑定的事件的 dom列表
                }
            }, (obj) => {
                obj.type = TYPE[obj.type.parents().find('.E_E_L_I_C_R_C_T_SubType').eq(0).text().replace(/\(共\d+分\)/,'')];
                obj.options = obj.options.map(i=>{
                    return i.replace(/\([A-Za-z]\)/,'').trim()
                });
                return obj
            }, (type, answer, $option) => {
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    $option.click();
                    // $('.el-button:contains(下一题)').click()
                }else if (type === 4 || type === 2) {
                    $option.val(answer);
                }
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }).fillAnswer();
        }, GLOBAL.delay*1.5);
    }
 
    function xetText() {
        showPanel();
        setTimeout(() => {
            // sleep(3000)
            new WorkerJS({
                root: '.question-container',
                elements: {
                    question: '.question-title #_flag4unlimit  p',
                    options: 'label  .image-text-box p',//文字的选项列表
                    $options: 'label',//绑定的事件的 dom列表
                    type:'.quetion-type'
                }
            }, (obj) => {
                obj.type = TYPE[obj.type.replace("(","").replace(")","")];
                if (obj.type === 3) {
                    obj.options = ['正确', '错误'];
                }
                obj.options = obj.options.map(i=>{
                    return i.replace(/\([A-Za-z]\)/,'').trim()
                });
                return obj
            }, (type, answer, $option) => {
                // fill answer
                if (type === 0 || type === 3 || type === 1) {
                    $option.click();
                    // $('.el-button:contains(下一题)').click()
                }
 
 
 
                // if (type === 0 || type === 1 || type === 3) {
                //     if ($option.find('.check_answer,.check_answer_dx').length === 0) {
                //         $option.click()
                //     }
                // } else if (type === 4 || type === 2) {
                //     UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
                // }
            }).fillAnswer();
        }, GLOBAL.delay*1.5);
    }
 
    var _self = unsafeWindow;
    exports.top = _self;
    // _self.$ = jQuery
 
    try {
        while (exports.top !== _self.top) {
            exports.top = exports.top.parent.document ? exports.top.parent : _self.top;
            if (exports.top.location.pathname === '/mycourse/studentstudy') break;
        }
    } catch (err) {
        exports.top = _self;
    }
    // console.log('顶部窗口链接',top.location.href)
    var parent = _self === exports.top ? self : _self.parent,
        Ext = _self.Ext || parent.Ext || {},
        UE = _self.UE;
 
 
    /**
     * 顶层窗口监听 iframeNode 的参数
     */
    exports.top.addEventListener("message", (event => {
        console.log('监听器的', GLOBAL);
        if (event.data.type === 'jump') ; else if (event.data.type === 'stop') {
            if (event.data.val) {
                let intv = setInterval(() => {
                    if (GLOBAL.loop) {
                        clearInterval(GLOBAL.loop);
                        delete GLOBAL.loop;
                        clearInterval(intv);
                    }
 
                }, 20);
 
            } else {
                GLOBAL.loop = setInterval(GLOBAL.setInterval, GLOBAL.time);
            }
        } else if (event.data.type === 'start_pay') {
            GM_setValue('start_pay', event.data.flag);
            iframeMsg('tip', {tip: '已' + (event.data.flag ? '开启' : '关闭') + '请求收费题库,已实时生效'});
        } else if (event.data.type === 'auto_jump') {
            GM_setValue('auto_jump', event.data.flag);
            iframeMsg('tip', {tip: '已' + (event.data.flag ? '开启' : '关闭') + '自动切换,页面刷新后生效'});
        } else if (event.data.type === 'confim') {
            GM_setValue('token', event.data.token);
        } else if (event.data.type === 'jump') {
            GLOBAL.index++;
            iframeMsg('tip', {tip: '准备答第' + (GLOBAL.index + 1) + '题'});
        }
        // GM_getValue
    }), false);
 
    /**
     * 类似于老板键,上箭头隐藏,下箭头显示
     */
    $(document).keydown(function (event) {
        if (event.keyCode === 38) {
            $('#model-id').hide();
        } else if (event.keyCode === 40) {
            $('#model-id').show();
        }
    });
    // yuketangOcr('https://qn-s0.yuketang.cn/Fmx0luZ4H0Kntw9_9Uctwj4I-iRi').then(res=>console.log(res))
 
    setTimeout(() => {
        start();
    }, GLOBAL.time);
    if (location.pathname === '/exam/examflow_index.action') {
        ZjyExam();
    } else if (location.pathname === '/study/homework/do.html') {
        zjyold();
    }else if ((location.pathname === '/exam/test/reVersionTestStartNew' || location.pathname === '/exam-ans/exam/test/reVersionTestStartNew') && location.href.includes('newMooc=true')) {
        chaoxingNewExam(1);
    } else if ((location.pathname === '/exam/test/reVersionTestStartNew' || location.pathname === '/exam-ans/exam/test/reVersionTestStartNew') && !location.href.includes('newMooc=true')) {
        chaoxingOldExam();
    } else if (location.pathname === '/work/doHomeWorkNew') {
        chaoxingQuiz();
    } else if (location.pathname === '/mooc2/exam/preview' || location.pathname === '/exam-ans/mooc2/exam/preview') {
        chaoxingNewExam(0);
    } else if (location.pathname === '/mooc2/work/dowork') {
        chaoxingNewWork();
    } else if (location.pathname === '/study/workExam/testWork/preview.html' || location.pathname === '/study/workExam/homeWork/preview.html' || location.pathname === '/study/workExam/onlineExam/preview.html') {
        mooc_icve_com_cn();
    } else if (location.pathname === '/stuExamWeb.html' && location.href.includes('/webExamList/dohomework/')) {
        zhsExam();
    } else if (location.pathname === '/stuExamWeb.html' && location.href.includes('/webExamList/doexamination/')) {
        zhsExam();
    } else if (location.href.includes('/atHomeworkExam/stu/homeworkQ/exerciseList')) {
        zhsIntegral();
    } else if (location.pathname === '/web/index.php') {
        ybkExam();
    } else if (location.pathname === '/study/works/works.html' || location.pathname === '/study/exam/exam.html') {
        icve_works();
    } else if (location.pathname.includes('/v2/web/cloud/student/exercise/')) {
        yktText();
    } else if (location.host === 'examination.xuetangx.com' && location.pathname.includes('/exam/')) {
        yktExam();
    } else if (location.pathname.includes('/v/quiz/quiz_result')) {
        const intv = setInterval(() => {
            if ($('#cover').attr('style').includes('display: none;')) {
                clearInterval(intv);
                yktOldExam();
            }
        }, 2000);
 
    } else if (location.pathname.includes('/v2/web/studentLog')) {
        collectYkt();
    } else if (location.pathname.includes('/Exam/OnlineExamV2/')) {
        zgdzText();
    } else if (location.pathname.includes('/evaluation_wechat/examination/detail/')) {
        xetText();
    }
 
    exports.Ext = Ext;
    exports.UE = UE;
    exports._self = _self;
    exports.parent = parent;
 
    Object.defineProperty(exports, '__esModule', { value: true });
 
 
 
    return exports;
 
	}
 
})({});