// ==UserScript== // @name 💯【超星学习通满分助手】支持LLM智能答题 // @namespace askAuto // @version 3.2.11 // @author shushoujiu, HaoduoYv // @description 💯超星学习通满分助手,挂机解放时间,无需任何操作自动完成所有任务点。汇集全网免费、付费题库接口支持一键对接,支持LLM智能答题(OpenAI/DeepSeek/kimi/智谱/千问/小米Mimo等),题库无答案时自动调用AI解答。 // @icon https://vitejs.dev/logo.svg // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @match *://*.nbdlib.cn/* // @match *://*.hnsyu.net/* // @match *://*.gdhkmooc.com/* // @require https://cdn.staticfile.org/vue/3.3.4/vue.global.prod.js // @require https://cdn.staticfile.org/vue-demi/0.14.0/index.iife.min.js // @require https://cdn.staticfile.org/element-plus-icons-vue/2.1.0/global.iife.min.js // @require data:application/javascript,window.Vue%3DVue%3B // @require https://cdn.staticfile.org/pinia/2.1.6/pinia.iife.prod.js // @require https://cdn.staticfile.org/element-plus/2.3.12/index.full.min.js // @require https://cdn.staticfile.org/blueimp-md5/2.19.0/js/md5.min.js // @require https://cdn.staticfile.org/jquery/3.7.1/jquery.min.js // @resource element-plus https://cdn.staticfile.org/element-plus/2.3.12/index.css // @resource ttf https://www.forestpolice.org/ttf/2.0/table.json // @tag free // @connect api.openai.com // @connect api.deepseek.com // @connect api.anthropic.com // @connect open.bigmodel.cn // @connect dashscope.aliyuncs.com // @connect api.xiaomimimo.com // @connect token-plan-cn.xiaomimimo.com // @connect easylearn.baidu.com // @connect www.baidu.com // @connect www.bing.com // @connect duckduckgo.com // @connect * // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_getValue // @grant GM_info // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-end // @antifeature ads 脚本可能包含第三方接口广告 // @antifeature payment 脚本存在第三方付费功能 // ==/UserScript== (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const i=document.createElement("style");i.textContent=t,document.head.append(i)})("/* ===== 超星学习通满分助手 ===== */:root{--cx-primary:#6366f1;--cx-primary-light:#818cf8;--cx-primary-dark:#4f46e5;--cx-success:#22c55e;--cx-warning:#f59e0b;--cx-danger:#ef4444;--cx-info:#06b6d4;--cx-bg:#f0f2f5;--cx-card-bg:#fff;--cx-text:#1e293b;--cx-text-secondary:#64748b;--cx-border:#e2e8f0;--cx-radius:12px;--cx-radius-sm:8px;--cx-shadow:0 4px 24px rgba(0,0,0,.08),0 1px 4px rgba(0,0,0,.04);--cx-shadow-hover:0 8px 32px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.06);--cx-transition:all .25s cubic-bezier(.4,0,.2,1)}.dialog-footer button[data-v-6ed29f7f]:first-child{margin-right:10px}#csbutton[data-v-6ed29f7f]{position:fixed;bottom:24px;right:24px;z-index:99999;width:52px;height:52px;border-radius:16px!important;font-size:24px;box-shadow:0 4px 16px rgba(99,102,241,.4);transition:var(--cx-transition);border:none!important}#csbutton[data-v-6ed29f7f]:hover{transform:scale(1.08);box-shadow:0 6px 24px rgba(99,102,241,.5)}#zeokdjg[data-v-c3c6b09f]{position:fixed;left:12px;bottom:50vh;z-index:9999;border-radius:14px!important;backdrop-filter:blur(8px);background:linear-gradient(135deg,var(--cx-primary),var(--cx-primary-light))!important;border:none!important;color:#fff!important;padding:12px 18px!important;font-size:13px;font-weight:500;box-shadow:var(--cx-shadow);transition:var(--cx-transition);letter-spacing:.3px}#zeokdjg[data-v-c3c6b09f]:hover{transform:translateY(-2px);box-shadow:var(--cx-shadow-hover)}.el-dialog{border-radius:20px!important;box-shadow:0 25px 50px -12px rgba(0,0,0,.25)!important}.el-overlay-dialog{overflow:visible!important}.el-dialog__header{padding:20px 24px 0!important;font-size:18px;font-weight:700;color:var(--cx-text)}.el-dialog__body{padding:20px 24px!important;overflow:visible!important}.el-dialog__footer{padding:0 24px 20px!important;border-top:1px solid var(--cx-border);padding-top:16px!important;margin-top:4px}.el-tabs__item{font-size:13px;font-weight:500;padding:0 14px!important;transition:var(--cx-transition)}.el-tabs__item.is-active{color:var(--cx-primary)!important}.el-tabs__active-bar{background:var(--cx-primary)!important;height:3px;border-radius:3px}.el-form-item{margin-bottom:18px!important}.el-form-item__label{font-weight:500;color:var(--cx-text);padding-bottom:4px!important}.el-switch.is-checked .el-switch__core{background:var(--cx-primary)!important;border-color:var(--cx-primary)!important}.el-button--primary{--el-button-primary-bg-color:var(--cx-primary);--el-button-primary-border-color:var(--cx-primary)}.el-button--danger{--el-button-danger-bg-color:var(--cx-danger);--el-button-danger-border-color:var(--cx-danger)}.el-button{border-radius:var(--cx-radius-sm)!important;font-weight:500!important;transition:var(--cx-transition);cursor:pointer}.el-select{width:100%}.el-input__wrapper{border-radius:var(--cx-radius-sm)!important}.el-checkbox__input.is-checked .el-checkbox__inner{background:var(--cx-primary)!important;border-color:var(--cx-primary)!important}.el-checkbox__label{font-size:13px!important}.el-tag{border-radius:6px!important;font-weight:500!important;border:none!important}.el-overlay{overflow:visible!important}.el-select-dropdown{z-index:999999!important}.el-tooltip__popper{z-index:999999!important}.el-message-box__wrapper{z-index:99999!important}.el-picker__popper{z-index:999999!important}.el-popper{z-index:999999!important}.el-select__popper{z-index:999999!important}.question_btn[data-v-c3c6b09f]{width:40px;height:40px;border-radius:10px!important;margin:4px;font-weight:600!important;transition:var(--cx-transition)}.question_btn[data-v-c3c6b09f]:hover{transform:scale(1.1);z-index:2}.question_div[data-v-c3c6b09f]{height:220px;padding:4px 0}.question_ti[data-v-c3c6b09f]{margin:12px 0 16px;line-height:1.5}.cx_log[data-v-c3c6b09f]{margin:3px 0;padding:4px 8px;border-radius:6px;background:rgba(0,0,0,.02);transition:var(--cx-transition)}.cx_log[data-v-c3c6b09f]:hover{background:rgba(99,102,241,.05)}.status_log[data-v-c3c6b09f]{margin-top:12px}.dialog-footer button[data-v-c3c6b09f]:first-child{margin-right:10px}#csbutton[data-v-c3c6b09f]{position:fixed;bottom:20px;right:20px;z-index:99999}.el-card{border-radius:var(--cx-radius)!important;border:1px solid var(--cx-border)!important;box-shadow:none!important;transition:var(--cx-transition)}.el-card:hover{box-shadow:var(--cx-shadow)!important}.el-alert{border-radius:var(--cx-radius-sm)!important;border:none!important}.el-empty__description p{color:var(--cx-text-secondary)!important}.el-scrollbar__view{padding:2px 0}.el-skeleton__item{--el-skeleton-circle-size:8px}.el-divider__text{font-size:12px;color:var(--cx-text-secondary)}.el-dialog__headerbtn{top:18px!important;right:20px!important;font-size:18px!important}.el-dialog__headerbtn:hover{transform:rotate(90deg);transition:transform .3s}.cx-log-success{color:var(--cx-success)}.cx-log-error{color:var(--cx-danger)}.cx-log-info{color:var(--cx-info)}.vjs-big-play-button{display:none!important}"); (async function (vue, pinia$1, ElementPlus, md5, $$1) { 'use strict'; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; ((e) => { const t = GM_getResourceText(e); GM_addStyle(t); })("element-plus"); var _GM_getResourceText = (() => "undefined" != typeof GM_getResourceText ? GM_getResourceText : void 0)(), _GM_getValue = (() => "undefined" != typeof GM_getValue ? GM_getValue : void 0)(), _GM_info = (() => "undefined" != typeof GM_info ? GM_info : void 0)(), _GM_setValue = (() => "undefined" != typeof GM_setValue ? GM_setValue : void 0)(), _GM_xmlhttpRequest = (() => "undefined" != typeof GM_xmlhttpRequest ? GM_xmlhttpRequest : void 0)(), _unsafeWindow = (() => "undefined" != typeof unsafeWindow ? unsafeWindow : void 0)(); const encryptApiKey = (k) => k ? btoa(k.split("").reverse().join("")) : ""; const decryptApiKey = (e) => { if(!e)return"";try{return atob(e).split("").reverse().join("")}catch{return e} }; const llmProviderPresets = [ {label:"自定义",value:"custom",baseUrl:"",suffix:"/chat/completions",models:[],apiKeyUrl:""}, {label:"OpenAI",value:"openai",baseUrl:"https://api.openai.com/v1",suffix:"/chat/completions",models:["gpt-3.5-turbo","gpt-4","gpt-4-turbo","gpt-4o","gpt-4o-mini"],apiKeyUrl:"https://platform.openai.com/api-keys"}, {label:"DeepSeek",value:"deepseek",baseUrl:"https://api.deepseek.com/v1",suffix:"/chat/completions",models:["deepseek-chat","deepseek-coder","deepseek-reasoner"],apiKeyUrl:"https://platform.deepseek.com/api_keys"}, {label:"Anthropic(Claude)",value:"anthropic",baseUrl:"https://api.anthropic.com/v1",suffix:"/chat/completions",models:["claude-opus-4-5","claude-sonnet-4-5","claude-3-5-sonnet-20241022","claude-3-opus-20240229"],apiKeyUrl:"https://console.anthropic.com/settings/keys"}, {label:"智谱GLM",value:"zhipu",baseUrl:"https://open.bigmodel.cn/api/paas/v4",suffix:"/chat/completions",models:["glm-4","glm-4-flash","glm-4-plus"],apiKeyUrl:"https://open.bigmodel.cn/usercenter/apikeys"}, {label:"通义千问",value:"qwen",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode/v1",suffix:"/chat/completions",models:["qwen-turbo","qwen-plus","qwen-max"],apiKeyUrl:"https://bailian.console.aliyun.com/?apiKey=1"}, {label:"Kimi(Moonshot)",value:"kimi",baseUrl:"https://api.moonshot.cn/v1",suffix:"/chat/completions",models:["moonshot-v1-8k","moonshot-v1-32k","moonshot-v1-128k","kimi-k2.5"],apiKeyUrl:"https://platform.moonshot.cn/console/api-keys"}, {label:"小米Mimo",value:"mimo",baseUrl:"https://api.xiaomimimo.com/v1",suffix:"/chat/completions",models:[],apiKeyUrl:"https://platform.xiaomimimo.com/console/api-keys"} ]; const getConfig = () => { try { const gmConfig = _GM_getValue("config", null); if (gmConfig) { const parsed = typeof gmConfig === "string" ? JSON.parse(gmConfig) : gmConfig; if(parsed.llmApiKey)parsed.llmApiKey=decryptApiKey(parsed.llmApiKey); delete parsed.thtoken;delete parsed.yztoken;delete parsed.enncytoken; return { ...defaultConfig$1, ...parsed }; } } catch (e) {} const storage = (typeof _unsafeWindow !== 'undefined' && _unsafeWindow.top) ? _unsafeWindow.top.localStorage : localStorage; const config = storage.getItem("config"); if (config) { const parsed = JSON.parse(config); if(parsed.llmApiKey)parsed.llmApiKey=decryptApiKey(parsed.llmApiKey); delete parsed.thtoken;delete parsed.yztoken;delete parsed.enncytoken; return { ...defaultConfig$1, ...parsed }; } return {...defaultConfig$1}; }, defaultConfig$1 = { debugger: false, autoAnswer: true, autoVideo: true, autoJump: true, autoSubmit: true, llmApiKey: "", llmBaseUrl: "https://api.openai.com", llmModel: "gpt-3.5-turbo", llmEnabled: false, llmTimeout: "30", llmMaxTokens: "1000", llmType: ["0", "1", "2", "3", "4", "5", "6", "7"], llmSuffix: "/chat/completions", llmProvider: "openai", llmWebSearch: false, llmSearchEngine: "baidu", llmSearchMode: "smart", interval: 3, answerInterval: 3, minAccuracy: 0.8, autoExam: true, hideExam: false, notice: "本脚本仅供学习交流使用,严禁用于商业用途,否则后果自负!" }, userConfig = [{ name: "quick", label: "快速配置", config: [{ name: "autoAnswer", label: "自动答题", type: "switch", value: defaultConfig$1.autoAnswer, desc: "开启后会自动答题" }, { name: "autoVideo", label: "自动视频", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后会自动观看视频" }, { name: "autoJump", label: "自动切换章节", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后会自动切换章节" }, { name: "autoSubmit", label: "自动提交答案", type: "switch", value: defaultConfig$1.autoSubmit, desc: "开启后自动提交答案" }, { name: "autoExam", label: "考试自动切换", type: "switch", value: defaultConfig$1.autoExam, desc: "开启后考试会自动切换" }, { name: "llmEnabled", label: "启用 LLM 智能答题", type: "switch", value: defaultConfig$1.llmEnabled, desc: "题库无答案时使用 AI 答题" }] }, { name: "base", label: "基础配置", config: [{ name: "interval", label: "通用间隔(秒)", type: "number", value: defaultConfig$1.interval, desc: "通用间隔,用于脚本运行切换" }, { name: "answerInterval", label: "答题间隔(秒)", type: "number", value: defaultConfig$1.answerInterval, desc: "控制答题速度" }, ] }, { name: "chapter", label: "章节配置", config: [{ name: "autoAnswer", label: "自动答题", type: "switch", value: defaultConfig$1.autoAnswer, desc: "开启后,会自动答题" }, { name: "autoVideo", label: "自动视频", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后,会自动观看视频" }, { name: "autoJump", label: "自动切换", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后,会自动切换章节" }, { name: "autoSubmit", label: "自动提交", type: "switch", value: defaultConfig$1.autoSubmit, desc: "开启后,会自动提交答案" }, { name: "minAccuracy", label: "最低正确率", type: "input", value: defaultConfig$1.minAccuracy, desc: "不满足最低正确率则不会自动提交答案" }] }, { name: "exam", label: "作业/考试配置", config: [{ name: "autoExam", label: "考试自动切换", type: "switch", value: defaultConfig$1.autoExam, desc: "开启后,会考试会自动切换" }] }, { name: "llm", label: "LLM配置", config: [{ name: "llmProvider", label: "供应商预设", type: "select", value: defaultConfig$1.llmProvider, desc: "选择供应商", options: llmProviderPresets.map(p=>({label:p.label,value:p.value})) }, { name: "llmBaseUrl", label: "API Base URL", type: "input", value: defaultConfig$1.llmBaseUrl, desc: "API 基础地址,如 https://api.openai.com/v1" }, { name: "llmSuffix", label: "请求路径后缀", type: "input", value: defaultConfig$1.llmSuffix, desc: "拼接在 Base URL 后的路径,如 /chat/completions" }, { name: "llmApiKey", label: "API Key", type: "password", showPassword: true, value: defaultConfig$1.llmApiKey, desc: "LLM API 密钥" }, { name: "llmModel", label: "模型名称", type: "input", value: defaultConfig$1.llmModel, desc: "模型名称,如 gpt-3.5-turbo, claude-3-5-sonnet 等" }, { name: "llmTimeout", label: "LLM 超时时间", type: "select", value: defaultConfig$1.llmTimeout, desc: "推理过长时选不设置,超时或报错自动跳过", options: [{ label: "30秒", value: "30" }, { label: "不设置", value: "0" }] }, { name: "llmMaxTokens", label: "最大输出 Token", type: "select", value: defaultConfig$1.llmMaxTokens, desc: "推理模型需要更大输出空间", options: [{ label: "1000", value: "1000" }, { label: "2000", value: "2000" }, { label: "4000", value: "4000" }, { label: "8000", value: "8000" }] }, { name: "llmEnabled", label: "启用 LLM 答题", type: "switch", value: defaultConfig$1.llmEnabled, desc: "开启后题库无答案时使用 LLM 进行答题" }, { name: "llmWebSearch", label: "启用联网搜索", type: "switch", value: defaultConfig$1.llmWebSearch, desc: "LLM 回答前先联网搜索相关资料" }, { name: "llmSearchEngine", label: "搜索引擎", type: "select", value: defaultConfig$1.llmSearchEngine, desc: "选择联网搜索引擎", options: [{ label: "百度", value: "baidu" }, { label: "Bing", value: "bing" }, { label: "DuckDuckGo", value: "duckduckgo" }] }, { name: "llmSearchMode", label: "搜索模式", type: "select", value: defaultConfig$1.llmSearchMode, desc: "始终搜索:每次都搜索;智能搜索:LLM 不确定时才搜索", options: [{ label: "始终搜索", value: "always" }, { label: "智能搜索", value: "smart" }] }, { name: "llmType", label: "允许使用 LLM 的题型", type: "checkbox", value: defaultConfig$1.llmType, desc: "选中后,将使用 LLM 回答对应题型", options: [{ label: "单选题", value: "0" }, { label: "多选题", value: "1" }, { label: "填空题", value: "2" }, { label: "判断题", value: "3" }, { label: "简答题", value: "4" }, { label: "名词解释", value: "5" }, { label: "论述题", value: "6" }, { label: "计算题", value: "7" }] }] }], useformStore = pinia$1.defineStore({ id: "formstore", state: () => ({ forminput: getConfig(), dialogV: false, activeName: "base" }), actions: { saveConfig(forminput) { var config; config = {...forminput};if(config.llmApiKey)config.llmApiKey=encryptApiKey(config.llmApiKey);_GM_setValue("config", JSON.stringify(config)), (typeof _unsafeWindow !== 'undefined' && _unsafeWindow.top ? _unsafeWindow.top.localStorage : localStorage).setItem("config", JSON.stringify(config)); } } }); var export_helper_default = (sfc, props) => { let target = sfc.__vccOpts || sfc; for (let [key, val] of props) target[key] = val; return target; }, aim_vue_vue_type_script_lang_default = { name: "Aim" }, _hoisted_12$1 = { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" }, _hoisted_42 = [vue.createElementVNode("path", { fill: "currentColor", d: "M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z" }, null, -1), vue.createElementVNode("path", { fill: "currentColor", d: "M512 96a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V128a32 32 0 0 1 32-32zm0 576a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V704a32 32 0 0 1 32-32zM96 512a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H128a32 32 0 0 1-32-32zm576 0a32 32 0 0 1 32-32h192a32 32 0 1 1 0 64H704a32 32 0 0 1-32-32z" }, null, -1)]; var aim_default = export_helper_default(aim_vue_vue_type_script_lang_default, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("svg", _hoisted_12$1, _hoisted_42); }], ["__file", "aim.vue"]]), setting_vue_vue_type_script_lang_default = { name: "Setting" }, _hoisted_1231 = { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" }, _hoisted_3230 = [vue.createElementVNode("path", { fill: "currentColor", d: "M600.704 64a32 32 0 0 1 30.464 22.208l35.2 109.376c14.784 7.232 28.928 15.36 42.432 24.512l112.384-24.192a32 32 0 0 1 34.432 15.36L944.32 364.8a32 32 0 0 1-4.032 37.504l-77.12 85.12a357.12 357.12 0 0 1 0 49.024l77.12 85.248a32 32 0 0 1 4.032 37.504l-88.704 153.6a32 32 0 0 1-34.432 15.296L708.8 803.904c-13.44 9.088-27.648 17.28-42.368 24.512l-35.264 109.376A32 32 0 0 1 600.704 960H423.296a32 32 0 0 1-30.464-22.208L357.696 828.48a351.616 351.616 0 0 1-42.56-24.64l-112.32 24.256a32 32 0 0 1-34.432-15.36L79.68 659.2a32 32 0 0 1 4.032-37.504l77.12-85.248a357.12 357.12 0 0 1 0-48.896l-77.12-85.248A32 32 0 0 1 79.68 364.8l88.704-153.6a32 32 0 0 1 34.432-15.296l112.32 24.256c13.568-9.152 27.776-17.408 42.56-24.64l35.2-109.312A32 32 0 0 1 423.232 64H600.64zm-23.424 64H446.72l-36.352 113.088-24.512 11.968a294.113 294.113 0 0 0-34.816 20.096l-22.656 15.36-116.224-25.088-65.28 113.152 79.68 88.192-1.92 27.136a293.12 293.12 0 0 0 0 40.192l1.92 27.136-79.808 88.192 65.344 113.152 116.224-25.024 22.656 15.296a294.113 294.113 0 0 0 34.816 20.096l24.512 11.968L446.72 896h130.688l36.48-113.152 24.448-11.904a288.282 288.282 0 0 0 34.752-20.096l22.592-15.296 116.288 25.024 65.28-113.152-79.744-88.192 1.92-27.136a293.12 293.12 0 0 0 0-40.256l-1.92-27.136 79.808-88.128-65.344-113.152-116.288 24.96-22.592-15.232a287.616 287.616 0 0 0-34.752-20.096l-24.448-11.904L577.344 128zM512 320a192 192 0 1 1 0 384 192 192 0 0 1 0-384zm0 64a128 128 0 1 0 0 256 128 128 0 0 0 0-256z" }, null, -1)]; var setting_default = export_helper_default(setting_vue_vue_type_script_lang_default, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1231, _hoisted_3230); }], ["__file", "setting.vue"]]); const _sfc_main$1 = vue.defineComponent({ components: {}, setup() { const formstoreObj = useformStore(), { forminput, dialogV, activeName } = pinia$1.storeToRefs(formstoreObj); vue.watch(dialogV, v => { if (v) { const fresh = getConfig(); Object.assign(forminput.value, fresh); } }); const ruleFormRef = vue.ref(), rules = vue.reactive({ interval: [{ required: true, message: "间隔时间不能为空" }, { type: "number", message: "间隔时间必须为数字" }, { validator: (rule, value) => value >= 1 ? Promise.resolve() : Promise.reject("间隔时间必须大于等于1") }], answerInterval: [{ required: true, message: "答题间隔不能为空" }, { type: "number", message: "答题间隔必须为数字" }, { validator: (rule, value) => value >= 1 ? Promise.resolve() : Promise.reject("答题间隔必须大于等于1") }], token: [{ validator: (rule, value) => { if (value) { return /^[a-zA-Z0-9]{6,}$/.test(value) ? Promise.resolve() : Promise.reject("token格式错误"); } return Promise.resolve(); } }] }); const _bindDrag = () => { const tryBind = (attempts) => { const dlg = _unsafeWindow.top.document.querySelector('#cccxapp .el-dialog'); if (!dlg) { if (attempts > 0) setTimeout(() => tryBind(attempts - 1), 100); return; } if (dlg._dragging) return; dlg._dragging = true; const hdr = dlg.querySelector('.el-dialog__header'); if (!hdr) return; hdr.style.cursor = 'move'; let sx, sy, sl, st; const onMove = e => { dlg.style.left = (sl + e.clientX - sx) + 'px'; dlg.style.top = (st + e.clientY - sy) + 'px'; dlg.style.marginLeft = '0'; dlg.style.marginTop = '0'; }; const onUp = () => { _unsafeWindow.top.document.removeEventListener('mousemove', onMove); _unsafeWindow.top.document.removeEventListener('mouseup', onUp); }; hdr.addEventListener('mousedown', e => { if (e.target.closest('.el-dialog__headerbtn')) return; const r = dlg.getBoundingClientRect(); sx = e.clientX; sy = e.clientY; sl = r.left; st = r.top; dlg.style.position = 'fixed'; dlg.style.left = r.left + 'px'; dlg.style.top = r.top + 'px'; dlg.style.marginLeft = '0'; dlg.style.marginTop = '0'; _unsafeWindow.top.document.addEventListener('mousemove', onMove); _unsafeWindow.top.document.addEventListener('mouseup', onUp); e.preventDefault(); }); }; tryBind(10); }; vue.watch(dialogV, v => { if (v) _bindDrag(); }); const importDialogV=vue.ref(false),importText=vue.ref(''),currentProviderUrl=vue.ref((()=>{const _p=llmProviderPresets.find(x=>x.value===forminput.value.llmProvider);return _p?_p.apiKeyUrl||'':'';})()); return { importDialogV, importText, currentProviderUrl, dialogV, activeName, ruleFormRef, forminput, rules, llmProviderPresets, onProviderChange:(v)=>{const p=llmProviderPresets.find(x=>x.value===v);if(p){forminput.value.llmBaseUrl=p.baseUrl;forminput.value.llmSuffix=p.suffix||"/chat/completions";currentProviderUrl.value=p.apiKeyUrl||"";}}, isCustomProvider:vue.computed(()=>forminput.value.llmProvider==="custom"), submitForm: async (formEl) => { formEl && await formEl.validate((valid, fields) => { valid && (formstoreObj.saveConfig(forminput.value), ElementPlus.ElNotification({ title: "Success", message: "配置保存成功,请自行刷新页面", type: "success" }), dialogV.value = false); }); }, exportConfig:()=>{const _exp={...forminput.value};delete _exp.thtoken;delete _exp.yztoken;delete _exp.enncytoken;const txt=JSON.stringify(_exp,null,2);navigator.clipboard?.writeText(txt).then(()=>ElementPlus.ElNotification({title:'已导出',message:'配置已复制到剪贴板',type:'success'})).catch(()=>{const ta=document.createElement('textarea');ta.value=txt;document.body.append(ta);ta.select();document.execCommand('copy');ta.remove();ElementPlus.ElNotification({title:'已导出',message:'配置已复制到剪贴板',type:'success'})})}, importConfig:()=>{importText.value='';importDialogV.value=true;}, doImport:()=>{try{const parsed=JSON.parse(importText.value);if(parsed.llmApiKey===undefined)throw new Error('无效配置');forminput.value={...forminput.value,...parsed};ElementPlus.ElNotification({title:'已导入',message:'配置已加载,点击保存生效',type:'success'});importDialogV.value=false;}catch{ElementPlus.ElNotification({title:'导入失败',message:'JSON格式错误',type:'error'});}}, testLLM:async()=>{const{llmApiKey,llmBaseUrl,llmModel,llmApiType}=forminput.value;if(!llmApiKey||!llmBaseUrl||!llmModel){ElementPlus.ElNotification({title:'测试失败',message:'请先填写完整的 LLM 配置',type:'error'});return}const suffix=forminput.value.llmSuffix||'/chat/completions';const url=llmBaseUrl+suffix;const headers={'Content-Type':'application/json','Authorization':`Bearer ${llmApiKey}`};const body={model:llmModel,messages:[{role:'system',content:'只回复OK'},{role:'user',content:'测试'}],max_tokens:10};ElementPlus.ElNotification({title:'测试中',message:'正在连接 LLM 服务...',type:'info'});_GM_xmlhttpRequest({method:'POST',url,data:JSON.stringify(body),headers,timeout:1e4,onload:(res)=>{try{res.status===200?ElementPlus.ElNotification({title:'连接成功',message:`${llmModel} 响应正常`,type:'success'}):ElementPlus.ElNotification({title:'连接失败',message:`HTTP ${res.status}: ${JSON.parse(res.responseText)?.error?.message||res.responseText?.slice(0,100)}`,type:'error'})}catch{ElementPlus.ElNotification({title:'连接失败',message:`HTTP ${res.status}`,type:'error'})}},onerror:()=>{ElementPlus.ElNotification({title:'连接失败',message:'无法连接到 LLM 服务',type:'error'})},ontimeout:()=>{ElementPlus.ElNotification({title:'连接超时',message:'LLM 服务未响应',type:'error'})}})}, userConfig, Setting: setting_default }; } }), _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) target[key] = val; return target; }, _hoisted_1$1 = { class: "dialog-footer" }; const App = _export_sfc(_sfc_main$1, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"), _component_el_switch = vue.resolveComponent("el-switch"), _component_el_input = vue.resolveComponent("el-input"), _component_el_input_number = vue.resolveComponent("el-input-number"), _component_el_option = vue.resolveComponent("el-option"), _component_el_select = vue.resolveComponent("el-select"), _component_el_checkbox = vue.resolveComponent("el-checkbox"), _component_el_checkbox_group = vue.resolveComponent("el-checkbox-group"), _component_el_tooltip = vue.resolveComponent("el-tooltip"), _component_el_form_item = vue.resolveComponent("el-form-item"), _component_el_tab_pane = vue.resolveComponent("el-tab-pane"), _component_el_tabs = vue.resolveComponent("el-tabs"), _component_el_form = vue.resolveComponent("el-form"), _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [vue.createVNode(_component_el_button, { type: "danger", id: "csbutton", icon: _ctx.Setting, circle: "", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.dialogV = !_ctx.dialogV) }, null, 8, ["icon"]), vue.createVNode(_component_el_dialog, { modelValue: _ctx.dialogV, "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => _ctx.dialogV = $event), title: "⚡ 超星学习通满分助手 ", width: "45%", modal: false, center: "", "z-index": 100000 }, { footer: vue.withCtx(() => [vue.createElementVNode("span", _hoisted_1$1, [vue.createVNode(_component_el_button, { onClick: _cache[2] || (_cache[2] = ($event) => _ctx.dialogV = false) }, { default: vue.withCtx(() => [vue.createTextVNode("取消")]), _: 1 }), vue.createVNode(_component_el_button, { type: "primary", onClick: _cache[3] || (_cache[3] = ($event) => _ctx.submitForm(_ctx.ruleFormRef)) }, { default: vue.withCtx(() => [vue.createTextVNode("保存")]), _: 1 }), _ctx.activeName === "llm" ? vue.createVNode(_component_el_button, { size: "small", onClick: _ctx.exportConfig }, { default: vue.withCtx(() => [vue.createTextVNode("📋 导出")]), _: 1 }) : vue.createCommentVNode("", true), _ctx.activeName === "llm" ? vue.createVNode(_component_el_button, { size: "small", onClick: _ctx.importConfig }, { default: vue.withCtx(() => [vue.createTextVNode("📂 导入")]), _: 1 }) : vue.createCommentVNode("", true), _ctx.activeName === "llm" ? vue.createVNode(_component_el_button, { size: "small", type: "success", plain: "", onClick: _ctx.testLLM }, { default: vue.withCtx(() => [vue.createTextVNode("🔗 测试LLM")]), _: 1 }) : vue.createCommentVNode("", true)])]), default: vue.withCtx(() => [vue.createVNode(_component_el_form, { ref: "ruleFormRef", rules: _ctx.rules, model: _ctx.forminput, class: "demo-ruleForm" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tabs, { class: "demo-tabs", modelValue: _ctx.activeName, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.activeName = $event) }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.userConfig, (item) => (vue.openBlock(), vue.createBlock(_component_el_tab_pane, { key: item.name, label: item.label, name: item.name }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item.config, (item1) => (vue.openBlock(), vue.createBlock(_component_el_form_item, { label: item1.label, prop: item1.name }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tooltip, { class: "box-item", effect: "dark", content: item1.desc || "", placement: "top", teleported: false }, { default: vue.withCtx(() => ["switch" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_switch, { key: 0, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "password" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_input, { key: 1, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event, type: "password", showPassword: true }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "input" === item1.type && item1.name === "llmBaseUrl" ? (vue.openBlock(), vue.createBlock(_component_el_input, { key: 1, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event, disabled: !_ctx.isCustomProvider }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled"])) : "input" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_input, { key: 1, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "number" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_input, { key: 2, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event * 1, type: "number", min: "1", style: {width:"120px"} }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "select" === item1.type && item1.name === "llmProvider" ? (vue.openBlock(), vue.createElementBlock("div", { key: 3, style: { display: "flex", alignItems: "center", gap: "8px" } }, [vue.createVNode(_component_el_select, { modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => { _ctx.forminput[item1.name] = $event; _ctx.onProviderChange($event); }, placeholder: "请选择", teleported: false }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item1.options, (item2) => (vue.openBlock(), vue.createBlock(_component_el_option, { key: item2.value, label: item2.label, value: item2.value }, null, 8, ["label", "value"]))), 128))]), _: 2 }, 1032, ["modelValue", "onUpdate:modelValue"]), _ctx.currentProviderUrl ? (vue.openBlock(), vue.createElementBlock("a", { key: 0, href: _ctx.currentProviderUrl, target: "_blank", style: { fontSize: "12px", color: "#409eff", whiteSpace: "nowrap", textDecoration: "none" } }, "获取 API Key")) : vue.createCommentVNode("", true)])) : "select" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_select, { key: 3, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event, placeholder: "请选择", teleported: false }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item1.options, (item2) => (vue.openBlock(), vue.createBlock(_component_el_option, { key: item2.value, label: item2.label, value: item2.value }, null, 8, ["label", "value"]))), 128))]), _: 2 }, 1032, ["modelValue", "onUpdate:modelValue"])) : "checkbox" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_checkbox_group, { key: 4, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item1.options, (item2) => (vue.openBlock(), vue.createBlock(_component_el_checkbox, { key: item2.value, label: item2.value, name: item2.value }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(item2.label), 1)]), _: 2 }, 1032, ["label", "name"]))), 128))]), _: 2 }, 1032, ["modelValue", "onUpdate:modelValue"])) : vue.createCommentVNode("", true)]), _: 2 }, 1032, ["content"])]), _: 2 }, 1032, ["label", "prop"]))), 256))]), _: 2 }, 1032, ["label", "name"]))), 128))]), _: 1 }, 8, ["modelValue"])]), _: 1 }, 8, ["rules", "model"])]), _: 1 }, 8, ["modelValue"]), vue.createVNode(_component_el_dialog, { modelValue: _ctx.importDialogV, "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => _ctx.importDialogV = $event), title: "📂 导入配置", width: "400px", modal: false, center: "", "z-index": 100001 }, { footer: vue.withCtx(() => [vue.createElementVNode("span", null, [vue.createVNode(_component_el_button, { onClick: _cache[7] || (_cache[7] = ($event) => _ctx.importDialogV = false) }, { default: vue.withCtx(() => [vue.createTextVNode("取消")]), _: 1 }), vue.createVNode(_component_el_button, { type: "primary", onClick: _ctx.doImport }, { default: vue.withCtx(() => [vue.createTextVNode("确定")]), _: 1 })])]), default: vue.withCtx(() => [vue.createElementVNode("p", { style: { "margin-bottom": "8px", color: "#64748b", "font-size": "13px" } }, "请粘贴配置JSON"), vue.createVNode(_component_el_input, { modelValue: _ctx.importText, "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => _ctx.importText = $event), type: "textarea", rows: 6, placeholder: '{ "interval": 3, ... }' }, null, 8, ["modelValue"])]), _: 1 }, 8, ["modelValue"])], 64); }], ["__scopeId", "data-v-6ed29f7f"]]); let defaultConfig = getConfig(); class ServerApi { constructor(window2 = _unsafeWindow) { __publicField(this, "windowz", _unsafeWindow); __publicField(this, "apiIcodef", "http://cx.icodef.com/wyn-nb?v=4"); __publicField(this, "apiMuketool", "https://api.muketool.com/cx/v2/query"); __publicField(this, "apiBgk", "https://easylearn.baidu.com/edu-web-go/bgk/searchlist"); this.windowz = window2; } async defaultRequest(url, method, data = {}, headers = {}, type = false) { var _a; return type && (headers = { "Content-Type": "POST" == method ? "application/json" : "text/plain", Referer: this.windowz.location.href, v: _GM_info.script.version, uid: _unsafeWindow.uid || ((_a = _unsafeWindow == null ? void 0 : _unsafeWindow.getCookie) == null ? void 0 : _a.call(_unsafeWindow, "_uid")) || "", ...headers }), new Promise((resolve, reject) => { _GM_xmlhttpRequest({ method, url, data: JSON.stringify(data), headers, timeout: 1e4, onload: (res) => { resolve(res); }, ontimeout: () => { reject("timeout"); }, onerror: (err) => { reject(err); } }); }); } async getAnswerIcodef(questionData) { let ip = Array.from({ length: 4 }, () => Math.floor(255 * Math.random())).join("."); return new Promise((resolve) => { const ques = { question: questionData.question }; this.defaultRequest(this.apiIcodef, "POST", ques, { "Content-Type": "application/json", "X-Forwarded-For": ip, "X-Real-IP": ip }).then((response) => { const res = JSON.parse(response.responseText); let answer = ""; if (1 === res.code) { let data = res.data.replace(/javascript:void\(0\);/g, "").trim().replace(/\n/g, ""); data.includes("叛逆") || data.includes("公众号") || data.includes("李恒雅") || data.includes("一之") || (answer = data.split("#")); } resolve({ form: "icodef题库", answer }); }).catch(() => { resolve({ form: "icodef题库", answer: "" }); }); }); } async getAnswerMuketool(questionData) { return new Promise((resolve) => { const ques = { question: questionData.question, type: parseInt(questionData.type) }; this.defaultRequest(this.apiMuketool, "POST", ques, { "Content-Type": "application/json" }).then((response) => { const res = JSON.parse(response.responseText); resolve({ form: "muketool题库", answer: 1 === res.code ? res.data.split("#") : "" }); }).catch(() => { resolve({ form: "muketool题库", answer: "" }); }); }); } decodeBdjson(t, r) { const n = "34cab29ef956d78afd"; const e = n + r; const u = decodeURIComponent(escape(atob(t))); let o = 0, i = [], c = 0; for (; c < u.length; c++) { o = o === e.length ? 0 : o; const a = u[c].charCodeAt(), f = e[o].charCodeAt(), s = a ^ f; i.push(s); o++; } let l = "", p = 0; for (; p < i.length - 1; p++) { const d = String.fromCharCode(i[p++] ^ i[p]); l += d; } return JSON.parse(decodeURIComponent(l).replace(/\+/g, " ")); } async getAnswerBgk(questionData) { return new Promise((resolve) => { const url = this.apiBgk + "?query=" + encodeURIComponent(questionData.question) + "&rn=5&pn=0"; this.defaultRequest(url, "GET", {}, { Referer: "https://easylearn.baidu.com/" }).then((response) => { const res = JSON.parse(response.responseText); if (res.errno !== 0 || !res.data || !res.data.list || res.data.list.length === 0) { resolve({ form: "不挂科题库", answer: "" }); return; } const item = res.data.list[0]; let decoded; try { decoded = this.decodeBdjson(item.bdjson, item.actk); } catch (e) { resolve({ form: "不挂科题库", answer: "" }); return; } const extractText = (nodes) => { if (!nodes) return []; return nodes.flatMap(node => { if (typeof node.c === "string") return [node.c]; if (Array.isArray(node.c)) return extractText(node.c); return []; }); }; const answer = extractText(decoded.que_answer); resolve({ form: "不挂科题库", answer: answer.length > 0 ? answer : "" }); }).catch(() => { resolve({ form: "不挂科题库", answer: "" }); }); }); } getSearchCountByType(questionType) { const countMap = { "0": 2, "1": 3, "2": 3, "3": 2, "4": 5, "5": 5, "6": 5, "7": 5 }; return countMap[questionType] || 3; } async searchBaidu(query, count) { return new Promise((resolve) => { const url = "https://www.baidu.com/s?wd=" + encodeURIComponent(query) + "&rn=" + count; _GM_xmlhttpRequest({ method: "GET", url, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, timeout: 10000, onload: (res) => { try { const html = res.responseText; const results = []; const itemRegex = /
]*>([\s\S]*?)<\/p>/gi; let match; while ((match = itemRegex.exec(html)) !== null && results.length < count) { const title = match[1].replace(/<[^>]+>/g, "").trim(); const snippet = match[2].replace(/<[^>]+>/g, "").trim(); if (title) results.push({ title, snippet }); } log(`[WebSearch] Bing 搜索完成,获取 ${results.length} 条结果`, "info"); resolve(results); } catch (e) { log("[WebSearch] Bing 搜索解析失败", "error"); resolve([]); } }, ontimeout: () => { log("[WebSearch] Bing 搜索超时", "error"); resolve([]); }, onerror: () => { log("[WebSearch] Bing 搜索失败", "error"); resolve([]); } }); }); } async searchDuckDuckGo(query, count) { return new Promise((resolve) => { const url = "https://duckduckgo.com/html/?q=" + encodeURIComponent(query); _GM_xmlhttpRequest({ method: "GET", url, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, timeout: 10000, onload: (res) => { try { const html = res.responseText; const results = []; const itemRegex = /
禁止用于各种非法用途,否则后果自负
本脚本题库接口均来源于网络以及用户反馈添加,不对题库准确率以及可用性负责,请自行判断、评估是否使用。
"); const _bindDragAsk = () => { const tryBind = (attempts) => { const all = Array.from(_unsafeWindow.top.document.querySelectorAll('.el-dialog')); const dlg = all.find(d => !d._dragging && !d.closest('#cccxapp')); if (!dlg) { if (attempts > 0) setTimeout(() => tryBind(attempts - 1), 100); return; } dlg._dragging = true; const hdr = dlg.querySelector('.el-dialog__header'); if (!hdr) return; hdr.style.cursor = 'move'; let sx, sy, sl, st; const onMove = e => { dlg.style.left = (sl + e.clientX - sx) + 'px'; dlg.style.top = (st + e.clientY - sy) + 'px'; dlg.style.marginLeft = '0'; dlg.style.marginTop = '0'; }; const onUp = () => { _unsafeWindow.top.document.removeEventListener('mousemove', onMove); _unsafeWindow.top.document.removeEventListener('mouseup', onUp); }; hdr.addEventListener('mousedown', e => { if (e.target.closest('.el-dialog__headerbtn')) return; const r = dlg.getBoundingClientRect(); sx = e.clientX; sy = e.clientY; sl = r.left; st = r.top; dlg.style.position = 'fixed'; dlg.style.left = r.left + 'px'; dlg.style.top = r.top + 'px'; dlg.style.marginLeft = '0'; dlg.style.marginTop = '0'; _unsafeWindow.top.document.addEventListener('mousemove', onMove); _unsafeWindow.top.document.addEventListener('mouseup', onUp); e.preventDefault(); }); }; tryBind(10); }; vue.watch(dialogVisible, v => { if (v) _bindDragAsk(); }); return { count, dialogVisible, questionList, askActiveName, askActiveNames, task, msg, Aim: aim_default, handleClick: (e) => { askstore.select(e); } }; } }), _hoisted_1 = { class: "dialog-footer" }, _hoisted_2 = { key: 0 }, _hoisted_3 = { class: "question_div" }, _hoisted_4 = { class: "question_ti" }, _hoisted_5 = { key: 0 }, _hoisted_6 = { key: 1 }, _hoisted_7 = { key: 2 }, _hoisted_8 = ["innerHTML"], _hoisted_9 = { key: 0, style: { "margin-top": "20px" } }, _hoisted_10 = { key: 1 }, _hoisted_11 = { key: 2 }, _hoisted_12 = { height: "100px" }, _hoisted_13 = ["innerHTML"]; const Ask = _export_sfc(_sfc_main, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"), _component_el_text = vue.resolveComponent("el-text"), _component_el_skeleton = vue.resolveComponent("el-skeleton"), _component_el_card = vue.resolveComponent("el-card"), _component_el_divider = vue.resolveComponent("el-divider"), _component_el_col = vue.resolveComponent("el-col"), _component_el_row = vue.resolveComponent("el-row"), _component_el_scrollbar = vue.resolveComponent("el-scrollbar"), _component_el_tag = vue.resolveComponent("el-tag"), _component_el_alert = vue.resolveComponent("el-alert"), _component_el_empty = vue.resolveComponent("el-empty"), _component_el_tab_pane = vue.resolveComponent("el-tab-pane"), _component_el_tabs = vue.resolveComponent("el-tabs"), _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [(vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [vue.createVNode(_component_el_button, { id: "zeokdjg", type: "success", plain: "", round: "", icon: _ctx.Aim, onClick: _cache[0] || (_cache[0] = ($event) => _ctx.dialogVisible = !_ctx.dialogVisible) }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString("暂未加载" == _ctx.task.name ? "◉ 等待任务加载" : "◉ 正在完成:" + _ctx.task.name), 1)]), _: 1 }, 8, ["icon"]), vue.createVNode(_component_el_dialog, { modelValue: _ctx.dialogVisible, "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => _ctx.dialogVisible = $event), width: "400px", title: "⚡ 超星学习通满分助手 ", modal: false, "append-to-body": false, "lock-scroll": false, center: "" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tabs, { modelValue: _ctx.askActiveName, "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.askActiveName = $event), class: "demo-tabs" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tab_pane, { label: "运行框", name: "first" }, { default: vue.withCtx(() => [_ctx.task.work.questionList.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", { key: 0 }, [vue.createElementVNode("div", { class: "question_div" }, [vue.createVNode(_component_el_card, { shadow: "hover" }, { default: vue.withCtx(() => [vue.createElementVNode("h1", { class: "question_ti" }, [vue.createVNode(_component_el_text, { size: "large", truncated: "" }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(_ctx.task.work.inx + 1 + "." + _ctx.task.work.questionList[_ctx.task.work.inx].question), 1)]), _: 1 })]), _ctx.task.work.questionList[_ctx.task.work.inx].answer ? (vue.openBlock(), vue.createElementBlock("p", { key: 1 }, [vue.createElementVNode("p", null, [vue.createElementVNode("pre", null, vue.toDisplayString(_ctx.task.work.questionList[_ctx.task.work.inx].answer), 1)])])) : (vue.openBlock(), vue.createElementBlock("p", { key: 0 }, [vue.createVNode(_component_el_skeleton, { rows: 3, animated: "" })]))]), _: 1 })]), "考试" != _ctx.task.name ? (vue.openBlock(), vue.createBlock(_component_el_divider, { key: 0 }, { default: vue.withCtx(() => [vue.createTextVNode(" 题号 ")]), _: 1 })) : vue.createCommentVNode("", true), "考试" != _ctx.task.name ? (vue.openBlock(), vue.createBlock(_component_el_scrollbar, { key: 1, height: "100px" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.work.questionList, (item, index) => (vue.openBlock(), vue.createBlock(_component_el_col, { span: 4, key: index }, { default: vue.withCtx(() => [vue.createVNode(_component_el_button, { type: item.status || "info", plain: "", class: "question_btn", onClick: ($event) => _ctx.handleClick(index) }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(index + 1), 1)]), _: 2 }, 1032, ["type", "onClick"])]), _: 2 }, 1024))), 128))]), _: 1 })]), _: 1 })) : vue.createCommentVNode("", true), _ctx.task.work.questionList[_ctx.task.work.inx].allAnswer ? (vue.openBlock(), vue.createElementBlock("div", { key: 2 }, [vue.createVNode(_component_el_divider, null, { default: vue.withCtx(() => [vue.createTextVNode(" 接口返回 ")]), _: 1 }), vue.createVNode(_component_el_tabs, { "tab-position": "left", style: { height: "200px" }, class: "demo-tabs" }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.work.questionList[_ctx.task.work.inx].allAnswer, (item, index) => (vue.openBlock(), vue.createBlock(_component_el_tab_pane, { label: item.form }, { default: vue.withCtx(() => [vue.createElementVNode("div", null, [vue.createElementVNode("div", { innerHTML: (item.answer || "暂无答案") }, null, 8, ["innerHTML"]), null != item.num ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, style: { "margin-top": "20px" } }, [vue.createElementVNode("div", null, [vue.createVNode(_component_el_tag, { class: "ml-2", type: "info" }, { default: vue.withCtx(() => [vue.createTextVNode("已用次数:" + vue.toDisplayString(item.usenum), 1)]), _: 2 }, 1024)]), vue.createElementVNode("div", null, [vue.createVNode(_component_el_tag, { class: "ml-2", type: "success" }, { default: vue.withCtx(() => [vue.createTextVNode("剩余次数:" + vue.toDisplayString(item.num), 1)]), _: 2 }, 1024)])])) : vue.createCommentVNode("", true)])]), _: 2 }, 1032, ["label"]))), 256))]), _: 1 })])) : vue.createCommentVNode("", true)])) : _ctx.task.video.status ? (vue.openBlock(), vue.createElementBlock("div", { key: 1 }, [vue.createVNode(_component_el_alert, { title: "倍速有风险,挂科两行泪", type: "error", center: "", "show-icon": "" }), vue.createVNode(_component_el_text, { class: "mx-1", size: "large", type: "danger" }, { default: vue.withCtx(() => [vue.createTextVNode(" 正在完成视频任务 ")]), _: 1 })])) : (vue.openBlock(), vue.createElementBlock("div", { key: 2 }, [vue.createElementVNode("div", { height: "100px" }, [vue.createVNode(_component_el_empty, { description: _ctx.task.name }, null, 8, ["description"])])]))]), _: 1 }), vue.createVNode(_component_el_tab_pane, { label: "运行日志", name: "second" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_scrollbar, { height: "200px" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [vue.createVNode(_component_el_col, { span: 24 }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.log, (item, index) => (vue.openBlock(), vue.createElementBlock("p", { key: index, class: "cx_log" }, [vue.createVNode(_component_el_text, { size: "small", type: "info", class: "mx-1" }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(item.time), 1)]), _: 2 }, 1024), vue.createVNode(_component_el_text, { class: "mx-1", type: "info" == item.type ? "" : item.type }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(" " + item.msg), 1)]), _: 2 }, 1032, ["type"])]))), 128))]), _: 1 })]), _: 1 })]), _: 1 })]), _: 1 }), vue.createVNode(_component_el_tab_pane, { label: "公告", name: "msg" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_card, { shadow: "hover" }, { default: vue.withCtx(() => [vue.createElementVNode("div", { innerHTML: _ctx.msg }, null, 8, ["innerHTML"])]), _: 1 })]), _: 1 })]), _: 1 }, 8, ["modelValue"]), vue.createElementVNode("p", null, [_ctx.task.status ? (vue.openBlock(), vue.createBlock(_component_el_tag, { key: 0 }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(_ctx.task.status), 1)]), _: 1 })) : vue.createCommentVNode("", true)])]), _: 1 }, 8, ["modelValue"])]))], 64); }], ["__scopeId", "data-v-c3c6b09f"]]); class Cx { constructor() { __publicField(this, "app"); __publicField(this, "askStore"); __publicField(this, "ServerApi"); __publicField(this, "defaultConfig"); this.app = vue.createApp(Ask).use(ElementPlus).use(pinia), this.askStore = useAskStore(), this.ServerApi = new ServerApi(), this.defaultConfig = getConfig(), this.app.mount((() => { const div = _unsafeWindow.top.document.createElement("div"); var old=_unsafeWindow.top.document.getElementById("xxxxzx");if(old)old.remove();_unsafeWindow.top.document.body.append(div);return div })()); } innerbook() { } async audio(iframeWindow) { this.askStore.reset(), this.askStore.task.name = "视频音频"; const audio = iframeWindow.document.getElementById("audio_html5_api"); return audio.muted = true, audio.autoplay = true, audio.volume = 0, audio.play().then(function() { console.log("播放成功"); }).catch(function(error) { "NotAllowedError" === error.name ? ElementPlus.ElMessageBox.alert("由于自动播放需要用户点击过浏览器,请确认即可", "温馨提示", { confirmButtonText: "确认", callback: () => { audio.play(); } }) : console.error("视频播放失败,原因:", error); }), new Promise((resolve) => { const intervalId = setInterval(() => { audio.ended ? (clearInterval(intervalId), log("监听到音频已完成", "success"), resolve()) : audio.paused && audio.play(); }, 1e3); audio.addEventListener("ended", function() { log("监听到音频已完成1", "success"), audio.pause(), clearInterval(intervalId), resolve(); }); }); } async video(iframeWindow) { this.askStore.reset(), this.askStore.task.name = "视频", this.askStore.task.video.status = 1, await waitElementLoaded(iframeWindow, "#video_html5_api"), console.log("视频加载完成"); const player = iframeWindow.videojs("video_html5_api"), playerButton = iframeWindow.document.querySelector(".vjs-big-play-button"); player.muted(true), player.playbackRate(16), player.play(), await new Promise((resolve) => { const intervalId = setInterval(() => { "isUnFinishJob" in iframeWindow && iframeWindow.isUnFinishJob() ? player.paused() && (playerButton == null ? void 0 : playerButton.click()) : (clearInterval(intervalId), resolve()); }, 1e3), pauseBase = player.pause; player.pause = function() { player.currentTime() >= player.duration() && (console.log("视频播放完成"), player.pause = pauseBase, resolve()); }, player.on("ended", () => { console.log("视频播放完成1"), player.pause = pauseBase, player.pause(), clearInterval(intervalId), resolve(); }); }), console.log("任务点完成"); } work(iframeWindow) { return new Promise(async (resolve) => { decode(iframeWindow); const Timu = iframeWindow.document.querySelectorAll(".TiMu"); if (!Timu) return void resolve(); let ques = [], succ = 0; for (let i = 0; i < Timu.length; i++) { let data = getQuestion("1", Timu[i]); console.log(data), ques.push(data); } this.askStore.reset(), this.askStore.count = ques.length, this.askStore.task.name = "章节测验"; for (let i = 0; i < ques.length; i++) { await sleep(this.defaultConfig.answerInterval), this.askStore.insert(ques[i]), this.askStore.task.work.inx = i; let data = await getAnswers(ques[i], iframeWindow); this.askStore.get(i).allAnswer = data; let tmp = fillAnswer(data, ques[i], Timu[i], iframeWindow); if (!tmp && this.defaultConfig.llmEnabled && this.defaultConfig.llmApiKey && this.defaultConfig.llmBaseUrl) { const questionType = ques[i].type; if (this.defaultConfig.llmType && Array.isArray(this.defaultConfig.llmType) && this.defaultConfig.llmType.includes(questionType)) { let llmResult = await this.ServerApi.getAnswerByLLM(ques[i]); data.push(llmResult); tmp = fillAnswer([llmResult], ques[i], Timu[i], iframeWindow); } } tmp ? (this.askStore.get(i).status = "primary", this.askStore.get(i).answer = tmp, succ++) : (this.askStore.get(i).status = "danger", this.askStore.get(i).answer = "暂无答案"), this.askStore.get(i).dom = Timu[i]; } this.defaultConfig.autoSubmit ? (succ / ques.length < this.defaultConfig.minAccuracy ? (this.askStore.log("章节测验正确率不足,暂存", "error"), iframeWindow.alert = function(e) { console.log("alert 方法被阻止", e); }, iframeWindow.noSubmit()) : (iframeWindow.btnBlueSubmit(), await sleep(3), iframeWindow.submitCheckTimes(), this.askStore.log("章节测验已完成", "success")), this.askStore.task.status = `章节测验已完成,等待切换,正确率:${succ}/${ques.length}`, resolve()) : (this.askStore.log("已完成答题,未开启自动提交,等待手动提交中", "success"), this.askStore.task.status = `正在等待手动提交,正确率:${succ}/${ques.length}`); }); } homework() { return new Promise(async (resolve) => { const Timu = _unsafeWindow.document.querySelectorAll(".questionLi"); if (!Timu) return void resolve(); let ques = []; for (let i = 0; i < Timu.length; i++) { let data = getQuestion("2", Timu[i]); ques.push(data); } this.askStore.reset(), this.askStore.count = ques.length, this.askStore.task.name = "作业"; for (let i = 0; i < ques.length; i++) { await sleep(this.defaultConfig.answerInterval), this.askStore.insert(ques[i]), this.askStore.task.work.inx = i; let data = await getAnswers(ques[i]); this.askStore.get(i).allAnswer = data; let tmp = fillAnswer(data, ques[i], Timu[i], _unsafeWindow); if (!tmp && this.defaultConfig.llmEnabled && this.defaultConfig.llmApiKey && this.defaultConfig.llmBaseUrl) { const questionType = ques[i].type; if (this.defaultConfig.llmType && Array.isArray(this.defaultConfig.llmType) && this.defaultConfig.llmType.includes(questionType)) { let llmResult = await this.ServerApi.getAnswerByLLM(ques[i]); data.push(llmResult); tmp = fillAnswer([llmResult], ques[i], Timu[i], _unsafeWindow); } } tmp ? (this.askStore.get(i).status = "primary", this.askStore.get(i).answer = tmp) : (this.askStore.get(i).status = "danger", this.askStore.get(i).answer = "暂无答案"), this.askStore.get(i).dom = Timu[i]; } }); } exam() { return new Promise(async (resolve) => { this.askStore.reset(), this.askStore.count = 1, this.askStore.task.name = "考试"; let data = getQuestion("3", _unsafeWindow.document.body); this.askStore.insert(data), this.askStore.task.work.inx = 0; let data1 = await getAnswers(data); this.askStore.get(0).allAnswer = data1; let tmp = fillAnswer(data1, data, document.getElementsByClassName("mark_table")[0], _unsafeWindow); if (!tmp && this.defaultConfig.llmEnabled && this.defaultConfig.llmApiKey && this.defaultConfig.llmBaseUrl) { const questionType = data.type; if (this.defaultConfig.llmType && Array.isArray(this.defaultConfig.llmType) && this.defaultConfig.llmType.includes(questionType)) { let llmResult = await this.ServerApi.getAnswerByLLM(data); data1.push(llmResult); tmp = fillAnswer([llmResult], data, document.getElementsByClassName("mark_table")[0], _unsafeWindow); } } if (tmp ? (this.askStore.get(0).status = "primary", this.askStore.get(0).answer = tmp) : (this.askStore.get(0).status = "danger", this.askStore.get(0).answer = "暂无答案"), this.defaultConfig.autoExam) { await sleep(this.defaultConfig.answerInterval); const nextButton = $('.nextDiv .jb_btn:contains("下一题")'); nextButton ? nextButton.click() : (this.askStore.log("已完成答题,请自行检查答案填写后自行提交", "success"), this.askStore.task.status = "已完成答题,请自行检查答案填写后自行提交"); } else this.askStore.task.status = "未开启自动切换,等待手动切换"; }); } pdf(iframeWindow) { return new Promise(async (resolve) => { const contentWindow = iframeWindow.document.querySelector("#panView").contentWindow; contentWindow.scrollTo(0, contentWindow.document.body.scrollHeight), resolve(); }); } async s(iframeWindow) { const questionList = $(iframeWindow.document).find(".TiMu").map(function(index, element) { try { let questionHtml, questionText, questionType$1, questionAnswer, questionOption = [], questionAnalysis = ""; switch (questionHtml = $(element).find(".Zy_TItle .clearfix"), questionText = removeHtml(questionHtml[0].innerHTML), questionType$1 = questionText.match(/^\【(.+?)\】/)[1], questionText = questionText.replace(questionText.match(/^\【(.+?)\】/)[0], ""), questionType$1) { case "单选题": case "多选题": return questionOption = $(element).find("ul>li").map(function(inx, item) { return removeHtml($(item).find("a").html()); }).get(), null; case "判断题": if (questionAnalysis = removeHtml($(element).find(".Py_addpy:eq(0)").html() || ""), element.innerHTML.includes("正确答案")) questionAnswer = removeHtml($(element).find(".Py_answer.clearfix>span").html()); else { const match = $(element).find(".Py_answer.clearfix").html().match(/^(.*?)(?=<\/i>)/s), result = match ? match[1] : ""; questionAnswer = removeHtml(result); } if (questionAnswer.includes("正确答案")) questionAnswer = questionAnswer.replace("正确答案:", "").trim(); else if ($(element).find(".fr.dui").length > 0) questionAnswer = questionAnswer.replace("我的答案:", "").trim(); else { if (!questionAnswer.replace("我的答案:", "").trim().includes("√") && !questionAnswer.replace("我的答案:", "").trim().includes("×")) return null; questionAnswer = "√" == questionAnswer.replace("我的答案:", "").trim() ? "×" : "√"; } break; case "填空题": if (questionAnswer = $("span.font14", $(element)).map(function(inx, item) { return removeHtml($(item).html()).replace(/^第.空:/, "").trim(); }).get(), 0 == questionAnswer.length) { if (questionAnswer = $(element).find(".Py_answer.clearfix>div>div[class='font14']"), !(questionAnswer.length = $(element).find(".Py_answer.clearfix>div>div[class='font14']>>.fr.dui").length)) return null; questionAnswer = questionAnswer.map(function(inx, item) { return removeHtml($(item).html()).replace(/^第.空:/, "").trim(); }).get(); } break; default: return null; } return { question: questionText, options: questionOption, type: questionType[questionType$1], answer: questionAnswer }; } catch { return null; } }).get(); await this.ServerApi.s(questionList, iframeWindow.location.href); } } const pinia = pinia$1.createPinia(), app = vue.createApp(App).use(ElementPlus).use(pinia), _self = _unsafeWindow, top = _self.top, formStore = useformStore(); var iframeCom = null; switch (app.mount((() => { try { const div = top.document.createElement("div");div.id="cccxapp"; var old=top.document.getElementById("cccxapp");if(old)old.remove();top.document.body.append(div);return div } catch (e) { log(e, "error"); } })()), (() => { document.body.oncopy = null, document.body.oncut = null, document.body.onpaste = null, document.body.onselectstart = null, document.body.ondragstart = null; const style = document.createElement("style"); style.innerHTML = "\n * {\n -webkit-user-select: auto !important;\n -moz-user-select: auto !important;\n -o-user-select: auto !important;\n user-select: auto !important;\n }\n ", document.head.appendChild(style); })(), _self.location.pathname) { case "/work/doHomeWorkNew": case "/mooc-ans/work/doHomeWorkNew": case "/mooc2-ans/work/doHomeWorkNew": location.href.includes("mooc2=1") && (location.href = location.href.replace(/&mooc2=1/g, "")); break; case "/mycourse/studentstudy": case "/mooc-ans/mycourse/studentstudy": case "/mooc2-ans/mycourse/studentstudy": if (!_self.location.href.match(/mooc2=1/)) { ElementPlus.ElNotification({ title: "Auto Ask", message: "暂不支持旧版章节,尝试切换至新版", type: "error" }), _self.location.href = _self.location.href + "&mooc2=1"; break; } const cxModel = new Cx(); const llmConfig = getConfig(); console.log("[LLM] 初始化配置检查:", JSON.stringify({llmEnabled: llmConfig.llmEnabled, llmApiKey: llmConfig.llmApiKey ? "***" + llmConfig.llmApiKey.slice(-4) : "未设置", llmBaseUrl: llmConfig.llmBaseUrl, llmModel: llmConfig.llmModel, llmType: llmConfig.llmType}, null, 2)); cxModel.askStore.log("脚本初始化成功!", "success"); if (llmConfig.llmEnabled) { cxModel.askStore.log("[LLM] 已启用,模型: " + llmConfig.llmModel, "success"); } else { cxModel.askStore.log("[LLM] 未启用,请在配置中开启", "info"); } const startWork = async () => { var _a, _b, _c, _d, _e; await waitElementLoaded(_self, "#iframe"); const cardsIframe = _self.document.querySelector("#iframe"); await waitIframeLoaded(cardsIframe); const _self1 = cardsIframe.contentWindow; top.scroll2Job(); let jobList = _self1.document.querySelectorAll(".ans-job-icon") || []; for (let i = 0; i < jobList.length; i++) { const item = jobList[i]; if ((_a = item.parentElement) == null ? void 0 : _a.classList.contains("ans-job-finished")) { const iframe = (_b = item.parentElement) == null ? void 0 : _b.querySelector("iframe"); if (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/work\/index.html/)) { await waitIframeLoaded(iframe), JSON.parse(iframe.getAttribute("data")); const workIframe = (_c = iframe.contentWindow) == null ? void 0 : _c.document.querySelector("iframe"); workIframe && (await waitIframeLoaded(workIframe), cxModel.s(workIframe.contentWindow)); } console.log(iframe.src, "已完成"), cxModel.askStore.log("已完成的任务点,跳过"); } else { const iframe = (_d = item.parentElement) == null ? void 0 : _d.querySelector("iframe"); await waitIframeLoaded(iframe); const otherInfo = JSON.parse(iframe.getAttribute("data")); if (cxModel.askStore.log(`正在完成任务:${otherInfo.name || otherInfo.title}`), iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/video\/index\.html/)) { if (!formStore.forminput.autoVideo) { cxModel.askStore.log("视频任务已跳过", "success"); continue; } await cxModel.video(iframe.contentWindow), cxModel.askStore.log("视频任务已完成", "success"); } else if (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/work\/index.html/)) { cxModel.askStore.log("即将开始做作业", "info"); const workIframe = (_e = iframe.contentWindow) == null ? void 0 : _e.document.querySelector("iframe"); workIframe && (await waitIframeLoaded(workIframe), await cxModel.work(workIframe.contentWindow), cxModel.askStore.log("作业任务已完成", "success")); } else if (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/audio\/index.html/)) { if (log("音频", "error"), !formStore.forminput.autoVideo) { cxModel.askStore.log("音频任务已跳过", "success"); continue; } iframe && (await waitIframeLoaded(iframe), await cxModel.audio(iframe.contentWindow), cxModel.askStore.log("音频任务已完成", "success")); } else (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/pdf\/index.html/)) ? (log("文档", "error"), iframe && (await waitIframeLoaded(iframe), await cxModel.pdf(iframe.contentWindow), cxModel.askStore.log("pdf任务已完成", "success"))) : (console.log(iframe == null ? void 0 : iframe.src, "未知"), cxModel.askStore.log("未知任务跳过", "success")); } } await sleep(formStore.forminput.interval); if (!formStore.forminput.autoJump) { cxModel.askStore.msg("由于未开启自动切换,请手动切换"); } else { const _detectSubTab = () => { try { const sels = ["#prev_tab > li", ".prev_ul > li", "#prevTabBox > li"]; for (const sel of sels) { const nodes = Array.from((top == null ? void 0 : top.document.querySelectorAll(sel)) || []); if (!nodes.length) continue; const ai = nodes.findIndex(n => n.classList && n.classList.contains("active")); if (ai === -1) continue; return { activeIndex: ai, total: nodes.length, hasNext: ai < nodes.length - 1, tabs: nodes }; } } catch(e){} return null; }; const _sub = _detectSubTab(); if (_sub && _sub.hasNext) { cxModel.askStore.log(`当前课时存在未完成页面(${_sub.activeIndex+1}/${_sub.total}),切换到下一页`, "info"); const _nextPageBtn = (top == null ? void 0 : top.document.querySelector("#mainid > .prev_next.next")); _nextPageBtn ? _nextPageBtn.click() : (top == null ? void 0 : top.document.querySelector(".nextChapter").click()); } else { (top == null ? void 0 : top.document.querySelector(".nextChapter").click()); } } }; setInterval(async () => { await waitElementLoaded(_self, "#iframe"); const cardsIframe = _self.document.querySelector("#iframe"); await waitIframeLoaded(cardsIframe); const _self1 = cardsIframe.contentWindow; iframeCom != _self1.location.href && (iframeCom = _self1.location.href, cxModel.askStore.reset(), startWork()); }, 2e3); break; case "/mooc2-ans/mycourse/stu": case "/mooc-ans/mycourse/stu": case "/mycourse/stu": ElementPlus.ElNotification({ title: "Auto Ask", message: "此页面无任务,请自行进入章节页面", type: "error" }); break; case "/work/selectWorkQuestionYiPiYue": case "/knowledge/cards": break; case "/mooc2/work/dowork": case "/mooc-ans/mooc2/work/dowork": case "/mooc2-ans/mooc2/work/dowork": const cxModel1 = new Cx(); const llmConfig1 = getConfig(); console.log("[LLM] 作业页配置:", JSON.stringify({ enabled: llmConfig1.llmEnabled, model: llmConfig1.llmModel }, null, 2)); cxModel1.askStore.log("脚本初始化成功!", "success"); if (llmConfig1.llmEnabled) cxModel1.askStore.log("[LLM] 已启用", "success"); await( cxModel1.homework()); break; case "/exam-ans/exam/test/reVersionTestStartNew": const cxModel2 = new Cx(); const llmConfig2 = getConfig(); console.log("[LLM] 考试页配置:", JSON.stringify({ enabled: llmConfig2.llmEnabled, model: llmConfig2.llmModel }, null, 2)); cxModel2.askStore.log("脚本初始化成功!", "success"); if (llmConfig2.llmEnabled) cxModel2.askStore.log("[LLM] 已启用", "success"); await( cxModel2.exam()); } })(Vue, Pinia, ElementPlus, md5, $);