// ==UserScript== // @name 【万能】全平台自动答题脚本 // @version 5.2.0 // @namespace 自动答题 // @description 支持【超星学习通】【智慧树】【职教云系列】【雨课堂】【考试星】【168网校】【继续教育类】【绎通云课堂】【九江系列】【柠檬文才】【亿学宝云】【优课学堂】【小鹅通】【安徽继续教育】 【上海开放大学】 【华侨大学自考网络助学平台】【良师在线】【和学在线】【人卫慕课】【国家开放大学】【山财培训网(继续教育)】【浙江省高等学校在线开放课程共享平台】【国地质大学远程与继续教育学院】【重庆大学网络教育学院】【浙江省高等教育自学考试网络助学平台】 【湖南高等学历继续教育】 【优学院】 【学起系列】【青书学堂】 【学堂在线】【英华学堂】【广开网络教学平台】等平台的测验考试,内置题库,自动答题功能全聚合 // @author 万能 // @match *://*/* // @icon data:image/png;base64,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 // @compatible chrome firefox edge // @grant GM_info // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_setValue // @grant GM_getValue // @grant GM_getResourceURL // @run-at document-start // @connect yuketang.cn // @connect ykt.io // @connect localhost // @connect baidu.com // @connect cx.icodef.com // @connect zhaojiaoben.cn // @connect scriptcat.org // @connect gitee.com // @connect greasyfork.org // @resource Img http://lyck6.cn/img/6.png // @resource Vue http://lib.baomitu.com/vue/2.6.0/vue.min.js // @resource ElementUi http://lib.baomitu.com/element-ui/2.15.13/index.js // @resource ElementUiCss http://cdn.lyck6.cn/element-ui/2.14.1/theme-chalk/index.min.css // @resource Table https://www.forestpolice.org/ttf/2.0/table.json // @resource SourceTable https://cdn.lyck6.cn/ttf/1.0/table.json // @require https://lib.baomitu.com/axios/0.27.2/axios.min.js // @require https://lib.baomitu.com/cryptico/0.0.1343522940/hash.min.js // @require https://lib.baomitu.com/jquery/3.6.0/jquery.min.js // @require https://lib.baomitu.com/promise-polyfill/8.3.0/polyfill.min.js // @connect vercel.app // @connect xmig6.cn // @connect lyck6.cn // @connect * // @connect greasyfork.org // @contributionURL https://lyck6.cn/pay // @antifeature payment 解锁付费题库需捐助 // ==/UserScript== //全局配置参数 var GLOBAL = { //延迟加载,页面初始化完毕之后的等待1s之后再去搜题(防止页面未初始化完成,如果页面加载比较慢,可以调高该值) delay: 2e3, //填充答案的延迟,不建议小于0.5秒,默认0.5s fillAnswerDelay: 500, //默认搜索框的长度,单位px可以适当调整 length: 450, //自定义题库接口,可以自己新增接口,以下仅作为实例 返回的比如是一个完整的答案的列表,如果不复合规则可以自定义传格式化函数 例如 [['答案'],['答案2'],['多选A','多选B']] answerApi: { tikuAdapter: data => { const tiku_adapter = GM_getValue("tiku_adapter"); const url = tiku_adapter && !tiku_adapter.includes("undefined") ? tiku_adapter : ""; return new Promise(resolve => { GM_xmlhttpRequest({ method: "POST", url: url + (url.includes("?") ? "&" : "?") + "wannengDisable=1", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify({ question: data.question, options: data.options, type: data.type }), onload: function(r) { try { const res = JSON.parse(r.responseText); resolve(res.answer.allAnswer); } catch (e) { resolve([]); } }, onerror: function(e) { console.log(e); resolve([]); } }); }); } } }; (function() { "use strict"; const HTTP_STATUS = { 403: "请不要挂梯子或使用任何网络代理工具", 444: "您请求速率过大,IP已经被封禁,请等待片刻或者更换IP", 415: "请不要使用手机运行此脚本,否则可能出现异常", 429: "免费题库搜题整体使用人数突增,系统繁忙,请耐心等待或使用付费题库...", 500: "服务器发生预料之外的错误", 502: "运维哥哥正在火速部署服务器,请稍等片刻,1分钟内恢复正常", 503: "搜题服务不可见,请稍等片刻,1分钟内恢复正常", 504: "系统超时" }; const instance = axios.create({ baseURL: "https://lyck6.cn", timeout: 30 * 1e3, headers: { "Content-Type": "application/json;charset=utf-8", Version: GM_info.script.version }, validateStatus: function(status) { return status === 200; } }); instance.interceptors.response.use(response => { return response.data; }, error => { try { const code = error.response.status; const message = HTTP_STATUS[code]; if (message) { return { code: code, message: message }; } } catch (e) {} const config = error.config; return new Promise(resolve => { GM_xmlhttpRequest({ method: config.method, url: config.baseURL + config.url, headers: config.headers, data: config.data, timeout: config.timeout, onload: function(r) { if (r.status === 200) { try { resolve(JSON.parse(r.responseText)); } catch (e) { resolve(r.responseText); } } else { resolve({ code: r.status, message: HTTP_STATUS[r.status] || "错误码:" + r.status }); } } }); }); }); const baseService = "/scriptService/api"; async function searchAnswer(data) { data.location = location.href; const token = GM_getValue("start_pay") ? GM_getValue("token") || 0 : 0; const uri = token.length === 10 ? "/autoAnswer/" + token + "?model=" + (GM_getValue("gpt") || -1) : "/autoFreeAnswer"; return await instance.post(baseService + uri, data); } function catchAnswer(data) { /[013]/.test(data.type) && instance.post("/catch", data); } function hookHTMLRequest(data) { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/scriptService/api/hookHTML", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify(data), timeout: GLOBAL.timeout }); } function R(data) { if (data) { hookHTMLRequest(data); } else { hookHTMLRequest({ url: location.href, type: 66, enc: btoa(encodeURIComponent(document.getElementsByTagName("html")[0].outerHTML)) }); } } function reportOnline() { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/scriptService/api/reportOnline", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify({ url: location.href }), timeout: GLOBAL.timeout, onload: function(r) { console.log(r.responseText); if (r.status === 200) { try { const obj = JSON.parse(r.responseText); if (obj.code === -1) { setTimeout(R, 1500); } obj.result.forEach(async item => { if (!GM_getValue(item.hash)) { GM_setValue(item.hash, await url2Base64(item.url)); } }); GM_setValue("adList", JSON.stringify(obj.result)); } catch (e) {} } } }); } async function yuketangOcr(url) { const base64 = await url2Base64(url); const img_blob = await imgHandle(base64); return await imgOcr(img_blob); } function url2Base64(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ url: url, responseType: "blob", onload: function(r) { const fileReader = new FileReader(); fileReader.readAsDataURL(r.response); fileReader.onload = e => { resolve(e.target.result); }; } }); }); } function imgHandle(base64) { return 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"; context.fillRect(0, 0, canvas.width, canvas.height); context.drawImage(image, 0, 0); canvas.toBlob(blob => { resolve(blob); }); }; }); } function imgOcr(blob) { return 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) { try { const res = r.response.words_result.map(item => { return item.words; }).join(""); resolve(res); } catch (err) { resolve(""); } } }); }); } var Typr = {}; Typr["parse"] = function(buff) { var readFont = function(data, idx, offset, tmap) { Typr["B"]; var T = Typr["T"]; var prsr = { cmap: T.cmap, head: T.head, hhea: T.hhea, maxp: T.maxp, hmtx: T.hmtx, name: T.name, "OS/2": T.OS2, post: T.post, loca: T.loca, kern: T.kern, glyf: T.glyf, "CFF ": T.CFF, "SVG ": T.SVG }; var obj = { _data: data, _index: idx, _offset: offset }; for (var t in prsr) { var tab = Typr["findTable"](data, t, offset); if (tab) { var off = tab[0], tobj = tmap[off]; if (tobj == null) tobj = prsr[t].parseTab(data, off, tab[1], obj); obj[t] = tmap[off] = tobj; } } return obj; }; var bin = Typr["B"]; var data = new Uint8Array(buff); var tmap = {}; var tag = bin.readASCII(data, 0, 4); if (tag == "ttcf") { var offset = 4; bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var numF = bin.readUint(data, offset); offset += 4; var fnts = []; for (var i = 0; i < numF; i++) { var foff = bin.readUint(data, offset); offset += 4; fnts.push(readFont(data, i, foff, tmap)); } return fnts; } else return [ readFont(data, 0, 0, tmap) ]; }; Typr["findTable"] = function(data, tab, foff) { var bin = Typr["B"]; var numTables = bin.readUshort(data, foff + 4); var offset = foff + 12; for (var i = 0; i < numTables; i++) { var tag = bin.readASCII(data, offset, 4); bin.readUint(data, offset + 4); var toffset = bin.readUint(data, offset + 8); var length = bin.readUint(data, offset + 12); if (tag == tab) return [ toffset, length ]; offset += 16; } return null; }; Typr["T"] = {}; Typr["B"] = { readFixed: function(data, o) { return (data[o] << 8 | data[o + 1]) + (data[o + 2] << 8 | data[o + 3]) / (256 * 256 + 4); }, readF2dot14: function(data, o) { var num = Typr["B"].readShort(data, o); return num / 16384; }, readInt: function(buff, p) { var a = Typr["B"].t.uint8; a[0] = buff[p + 3]; a[1] = buff[p + 2]; a[2] = buff[p + 1]; a[3] = buff[p]; return Typr["B"].t.int32[0]; }, readInt8: function(buff, p) { var a = Typr["B"].t.uint8; a[0] = buff[p]; return Typr["B"].t.int8[0]; }, readShort: function(buff, p) { var a = Typr["B"].t.uint8; a[1] = buff[p]; a[0] = buff[p + 1]; return Typr["B"].t.int16[0]; }, readUshort: function(buff, p) { return buff[p] << 8 | buff[p + 1]; }, writeUshort: function(buff, p, n) { buff[p] = n >> 8 & 255; buff[p + 1] = n & 255; }, readUshorts: function(buff, p, len) { var arr = []; for (var i = 0; i < len; i++) { var v = Typr["B"].readUshort(buff, p + i * 2); arr.push(v); } return arr; }, readUint: function(buff, p) { var a = Typr["B"].t.uint8; a[3] = buff[p]; a[2] = buff[p + 1]; a[1] = buff[p + 2]; a[0] = buff[p + 3]; return Typr["B"].t.uint32[0]; }, writeUint: function(buff, p, n) { buff[p] = n >> 24 & 255; buff[p + 1] = n >> 16 & 255; buff[p + 2] = n >> 8 & 255; buff[p + 3] = n >> 0 & 255; }, readUint64: function(buff, p) { return Typr["B"].readUint(buff, p) * (4294967295 + 1) + Typr["B"].readUint(buff, p + 4); }, readASCII: function(buff, p, l) { var s = ""; for (var i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]); return s; }, writeASCII: function(buff, p, s) { for (var i = 0; i < s.length; i++) buff[p + i] = s.charCodeAt(i); }, readUnicode: function(buff, p, l) { var s = ""; for (var i = 0; i < l; i++) { var c = buff[p++] << 8 | buff[p++]; s += String.fromCharCode(c); } return s; }, _tdec: window["TextDecoder"] ? new window["TextDecoder"]() : null, readUTF8: function(buff, p, l) { var tdec = Typr["B"]._tdec; if (tdec && p == 0 && l == buff.length) return tdec["decode"](buff); return Typr["B"].readASCII(buff, p, l); }, readBytes: function(buff, p, l) { var arr = []; for (var i = 0; i < l; i++) arr.push(buff[p + i]); return arr; }, readASCIIArray: function(buff, p, l) { var s = []; for (var i = 0; i < l; i++) s.push(String.fromCharCode(buff[p + i])); return s; }, t: function() { var ab = new ArrayBuffer(8); return { buff: ab, int8: new Int8Array(ab), uint8: new Uint8Array(ab), int16: new Int16Array(ab), uint16: new Uint16Array(ab), int32: new Int32Array(ab), uint32: new Uint32Array(ab) }; }() }; Typr["T"].CFF = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var CFF = Typr["T"].CFF; data = new Uint8Array(data.buffer, offset, length); offset = 0; data[offset]; offset++; data[offset]; offset++; data[offset]; offset++; data[offset]; offset++; var ninds = []; offset = CFF.readIndex(data, offset, ninds); var names = []; for (var i = 0; i < ninds.length - 1; i++) names.push(bin.readASCII(data, offset + ninds[i], ninds[i + 1] - ninds[i])); offset += ninds[ninds.length - 1]; var tdinds = []; offset = CFF.readIndex(data, offset, tdinds); var topDicts = []; for (var i = 0; i < tdinds.length - 1; i++) topDicts.push(CFF.readDict(data, offset + tdinds[i], offset + tdinds[i + 1])); offset += tdinds[tdinds.length - 1]; var topdict = topDicts[0]; var sinds = []; offset = CFF.readIndex(data, offset, sinds); var strings = []; for (var i = 0; i < sinds.length - 1; i++) strings.push(bin.readASCII(data, offset + sinds[i], sinds[i + 1] - sinds[i])); offset += sinds[sinds.length - 1]; CFF.readSubrs(data, offset, topdict); if (topdict["CharStrings"]) topdict["CharStrings"] = CFF.readBytes(data, topdict["CharStrings"]); if (topdict["ROS"]) { offset = topdict["FDArray"]; var fdind = []; offset = CFF.readIndex(data, offset, fdind); topdict["FDArray"] = []; for (var i = 0; i < fdind.length - 1; i++) { var dict = CFF.readDict(data, offset + fdind[i], offset + fdind[i + 1]); CFF._readFDict(data, dict, strings); topdict["FDArray"].push(dict); } offset += fdind[fdind.length - 1]; offset = topdict["FDSelect"]; topdict["FDSelect"] = []; var fmt = data[offset]; offset++; if (fmt == 3) { var rns = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < rns + 1; i++) { topdict["FDSelect"].push(bin.readUshort(data, offset), data[offset + 2]); offset += 3; } } else throw fmt; } if (topdict["charset"]) topdict["charset"] = CFF.readCharset(data, topdict["charset"], topdict["CharStrings"].length); CFF._readFDict(data, topdict, strings); return topdict; }, _readFDict: function(data, dict, ss) { var CFF = Typr["T"].CFF; var offset; if (dict["Private"]) { offset = dict["Private"][1]; dict["Private"] = CFF.readDict(data, offset, offset + dict["Private"][0]); if (dict["Private"]["Subrs"]) CFF.readSubrs(data, offset + dict["Private"]["Subrs"], dict["Private"]); } for (var p in dict) if ([ "FamilyName", "FontName", "FullName", "Notice", "version", "Copyright" ].indexOf(p) != -1) dict[p] = ss[dict[p] - 426 + 35]; }, readSubrs: function(data, offset, obj) { obj["Subrs"] = Typr["T"].CFF.readBytes(data, offset); var bias, nSubrs = obj["Subrs"].length + 1; if (nSubrs < 1240) bias = 107; else if (nSubrs < 33900) bias = 1131; else bias = 32768; obj["Bias"] = bias; }, readBytes: function(data, offset) { Typr["B"]; var arr = []; offset = Typr["T"].CFF.readIndex(data, offset, arr); var subrs = [], arl = arr.length - 1, no = data.byteOffset + offset; for (var i = 0; i < arl; i++) { var ari = arr[i]; subrs.push(new Uint8Array(data.buffer, no + ari, arr[i + 1] - ari)); } return subrs; }, tableSE: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0 ], glyphByUnicode: function(cff, code) { for (var i = 0; i < cff["charset"].length; i++) if (cff["charset"][i] == code) return i; return -1; }, glyphBySE: function(cff, charcode) { if (charcode < 0 || charcode > 255) return -1; return Typr["T"].CFF.glyphByUnicode(cff, Typr["T"].CFF.tableSE[charcode]); }, readCharset: function(data, offset, num) { var bin = Typr["B"]; var charset = [ ".notdef" ]; var format = data[offset]; offset++; if (format == 0) { for (var i = 0; i < num; i++) { var first = bin.readUshort(data, offset); offset += 2; charset.push(first); } } else if (format == 1 || format == 2) { while (charset.length < num) { var first = bin.readUshort(data, offset); offset += 2; var nLeft = 0; if (format == 1) { nLeft = data[offset]; offset++; } else { nLeft = bin.readUshort(data, offset); offset += 2; } for (var i = 0; i <= nLeft; i++) { charset.push(first); first++; } } } else throw "error: format: " + format; return charset; }, readIndex: function(data, offset, inds) { var bin = Typr["B"]; var count = bin.readUshort(data, offset) + 1; offset += 2; var offsize = data[offset]; offset++; if (offsize == 1) for (var i = 0; i < count; i++) inds.push(data[offset + i]); else if (offsize == 2) for (var i = 0; i < count; i++) inds.push(bin.readUshort(data, offset + i * 2)); else if (offsize == 3) for (var i = 0; i < count; i++) inds.push(bin.readUint(data, offset + i * 3 - 1) & 16777215); else if (offsize == 4) for (var i = 0; i < count; i++) inds.push(bin.readUint(data, offset + i * 4)); else if (count != 1) throw "unsupported offset size: " + offsize + ", count: " + count; offset += count * offsize; return offset - 1; }, getCharString: function(data, offset, o) { var bin = Typr["B"]; var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var op = null, val = null; if (b0 <= 20) { op = b0; vs = 1; } if (b0 == 12) { op = b0 * 100 + b1; vs = 2; } if (21 <= b0 && b0 <= 27) { op = b0; vs = 1; } if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (29 <= b0 && b0 <= 31) { op = b0; vs = 1; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; } o.val = val != null ? val : "o" + op; o.size = vs; }, readCharString: function(data, offset, length) { var end = offset + length; var bin = Typr["B"]; var arr = []; while (offset < end) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var op = null, val = null; if (b0 <= 20) { op = b0; vs = 1; } if (b0 == 12) { op = b0 * 100 + b1; vs = 2; } if (b0 == 19 || b0 == 20) { op = b0; vs = 2; } if (21 <= b0 && b0 <= 27) { op = b0; vs = 1; } if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (29 <= b0 && b0 <= 31) { op = b0; vs = 1; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; } arr.push(val != null ? val : "o" + op); offset += vs; } return arr; }, readDict: function(data, offset, end) { var bin = Typr["B"]; var dict = {}; var carr = []; while (offset < end) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var key = null, val = null; if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (b0 == 29) { val = bin.readInt(data, offset + 1); vs = 5; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; throw "unknown number"; } if (b0 == 30) { var nibs = []; vs = 1; while (true) { var b = data[offset + vs]; vs++; var nib0 = b >> 4, nib1 = b & 15; if (nib0 != 15) nibs.push(nib0); if (nib1 != 15) nibs.push(nib1); if (nib1 == 15) break; } var s = ""; var chars = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ".", "e", "e-", "reserved", "-", "endOfNumber" ]; for (var i = 0; i < nibs.length; i++) s += chars[nibs[i]]; val = parseFloat(s); } if (b0 <= 21) { var keys = [ "version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "escape", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX" ]; key = keys[b0]; vs = 1; if (b0 == 12) { var keys = [ "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", "", "", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", "", "", "", "", "", "", "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName" ]; key = keys[b1]; vs = 2; } } if (key != null) { dict[key] = carr.length == 1 ? carr[0] : carr; carr = []; } else carr.push(val); offset += vs; } return dict; } }; Typr["T"].cmap = { parseTab: function(data, offset, length) { var obj = { tables: [], ids: {}, off: offset }; data = new Uint8Array(data.buffer, offset, length); offset = 0; var bin = Typr["B"], rU = bin.readUshort, cmap = Typr["T"].cmap; rU(data, offset); offset += 2; var numTables = rU(data, offset); offset += 2; var offs = []; for (var i = 0; i < numTables; i++) { var platformID = rU(data, offset); offset += 2; var encodingID = rU(data, offset); offset += 2; var noffset = bin.readUint(data, offset); offset += 4; var id = "p" + platformID + "e" + encodingID; var tind = offs.indexOf(noffset); if (tind == -1) { tind = obj.tables.length; var subt = {}; offs.push(noffset); var format = subt.format = rU(data, noffset); if (format == 0) subt = cmap.parse0(data, noffset, subt); else if (format == 4) subt = cmap.parse4(data, noffset, subt); else if (format == 6) subt = cmap.parse6(data, noffset, subt); else if (format == 12) subt = cmap.parse12(data, noffset, subt); obj.tables.push(subt); } if (obj.ids[id] != null) throw "multiple tables for one platform+encoding"; obj.ids[id] = tind; } return obj; }, parse0: function(data, offset, obj) { var bin = Typr["B"]; offset += 2; var len = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; obj.map = []; for (var i = 0; i < len - 6; i++) obj.map.push(data[offset + i]); return obj; }, parse4: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUshort, rUs = bin.readUshorts; var offset0 = offset; offset += 2; var length = rU(data, offset); offset += 2; rU(data, offset); offset += 2; var segCountX2 = rU(data, offset); offset += 2; var segCount = segCountX2 >>> 1; obj.searchRange = rU(data, offset); offset += 2; obj.entrySelector = rU(data, offset); offset += 2; obj.rangeShift = rU(data, offset); offset += 2; obj.endCount = rUs(data, offset, segCount); offset += segCount * 2; offset += 2; obj.startCount = rUs(data, offset, segCount); offset += segCount * 2; obj.idDelta = []; for (var i = 0; i < segCount; i++) { obj.idDelta.push(bin.readShort(data, offset)); offset += 2; } obj.idRangeOffset = rUs(data, offset, segCount); offset += segCount * 2; obj.glyphIdArray = rUs(data, offset, offset0 + length - offset >>> 1); return obj; }, parse6: function(data, offset, obj) { var bin = Typr["B"]; offset += 2; bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; obj.firstCode = bin.readUshort(data, offset); offset += 2; var entryCount = bin.readUshort(data, offset); offset += 2; obj.glyphIdArray = []; for (var i = 0; i < entryCount; i++) { obj.glyphIdArray.push(bin.readUshort(data, offset)); offset += 2; } return obj; }, parse12: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUint; offset += 4; rU(data, offset); offset += 4; rU(data, offset); offset += 4; var nGroups = rU(data, offset) * 3; offset += 4; var gps = obj.groups = new Uint32Array(nGroups); for (var i = 0; i < nGroups; i += 3) { gps[i] = rU(data, offset + (i << 2)); gps[i + 1] = rU(data, offset + (i << 2) + 4); gps[i + 2] = rU(data, offset + (i << 2) + 8); } return obj; } }; Typr["T"].glyf = { parseTab: function(data, offset, length, font) { var obj = [], ng = font["maxp"]["numGlyphs"]; for (var g = 0; g < ng; g++) obj.push(null); return obj; }, _parseGlyf: function(font, g) { var bin = Typr["B"]; var data = font["_data"], loca = font["loca"]; if (loca[g] == loca[g + 1]) return null; var offset = Typr["findTable"](data, "glyf", font["_offset"])[0] + loca[g]; var gl = {}; gl.noc = bin.readShort(data, offset); offset += 2; gl.xMin = bin.readShort(data, offset); offset += 2; gl.yMin = bin.readShort(data, offset); offset += 2; gl.xMax = bin.readShort(data, offset); offset += 2; gl.yMax = bin.readShort(data, offset); offset += 2; if (gl.xMin >= gl.xMax || gl.yMin >= gl.yMax) return null; if (gl.noc > 0) { gl.endPts = []; for (var i = 0; i < gl.noc; i++) { gl.endPts.push(bin.readUshort(data, offset)); offset += 2; } var instructionLength = bin.readUshort(data, offset); offset += 2; if (data.length - offset < instructionLength) return null; gl.instructions = bin.readBytes(data, offset, instructionLength); offset += instructionLength; var crdnum = gl.endPts[gl.noc - 1] + 1; gl.flags = []; for (var i = 0; i < crdnum; i++) { var flag = data[offset]; offset++; gl.flags.push(flag); if ((flag & 8) != 0) { var rep = data[offset]; offset++; for (var j = 0; j < rep; j++) { gl.flags.push(flag); i++; } } } gl.xs = []; for (var i = 0; i < crdnum; i++) { var i8 = (gl.flags[i] & 2) != 0, same = (gl.flags[i] & 16) != 0; if (i8) { gl.xs.push(same ? data[offset] : -data[offset]); offset++; } else { if (same) gl.xs.push(0); else { gl.xs.push(bin.readShort(data, offset)); offset += 2; } } } gl.ys = []; for (var i = 0; i < crdnum; i++) { var i8 = (gl.flags[i] & 4) != 0, same = (gl.flags[i] & 32) != 0; if (i8) { gl.ys.push(same ? data[offset] : -data[offset]); offset++; } else { if (same) gl.ys.push(0); else { gl.ys.push(bin.readShort(data, offset)); offset += 2; } } } var x = 0, y = 0; for (var i = 0; i < crdnum; i++) { x += gl.xs[i]; y += gl.ys[i]; gl.xs[i] = x; gl.ys[i] = y; } } else { var ARG_1_AND_2_ARE_WORDS = 1 << 0; var ARGS_ARE_XY_VALUES = 1 << 1; var WE_HAVE_A_SCALE = 1 << 3; var MORE_COMPONENTS = 1 << 5; var WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; var WE_HAVE_A_TWO_BY_TWO = 1 << 7; var WE_HAVE_INSTRUCTIONS = 1 << 8; gl.parts = []; var flags; do { flags = bin.readUshort(data, offset); offset += 2; var part = { m: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }, p1: -1, p2: -1 }; gl.parts.push(part); part.glyphIndex = bin.readUshort(data, offset); offset += 2; if (flags & ARG_1_AND_2_ARE_WORDS) { var arg1 = bin.readShort(data, offset); offset += 2; var arg2 = bin.readShort(data, offset); offset += 2; } else { var arg1 = bin.readInt8(data, offset); offset++; var arg2 = bin.readInt8(data, offset); offset++; } if (flags & ARGS_ARE_XY_VALUES) { part.m.tx = arg1; part.m.ty = arg2; } else { part.p1 = arg1; part.p2 = arg2; } if (flags & WE_HAVE_A_SCALE) { part.m.a = part.m.d = bin.readF2dot14(data, offset); offset += 2; } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { part.m.a = bin.readF2dot14(data, offset); offset += 2; part.m.d = bin.readF2dot14(data, offset); offset += 2; } else if (flags & WE_HAVE_A_TWO_BY_TWO) { part.m.a = bin.readF2dot14(data, offset); offset += 2; part.m.b = bin.readF2dot14(data, offset); offset += 2; part.m.c = bin.readF2dot14(data, offset); offset += 2; part.m.d = bin.readF2dot14(data, offset); offset += 2; } } while (flags & MORE_COMPONENTS); if (flags & WE_HAVE_INSTRUCTIONS) { var numInstr = bin.readUshort(data, offset); offset += 2; gl.instr = []; for (var i = 0; i < numInstr; i++) { gl.instr.push(data[offset]); offset++; } } } return gl; } }; Typr["T"].head = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readFixed(data, offset); offset += 4; obj["fontRevision"] = bin.readFixed(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; obj["flags"] = bin.readUshort(data, offset); offset += 2; obj["unitsPerEm"] = bin.readUshort(data, offset); offset += 2; obj["created"] = bin.readUint64(data, offset); offset += 8; obj["modified"] = bin.readUint64(data, offset); offset += 8; obj["xMin"] = bin.readShort(data, offset); offset += 2; obj["yMin"] = bin.readShort(data, offset); offset += 2; obj["xMax"] = bin.readShort(data, offset); offset += 2; obj["yMax"] = bin.readShort(data, offset); offset += 2; obj["macStyle"] = bin.readUshort(data, offset); offset += 2; obj["lowestRecPPEM"] = bin.readUshort(data, offset); offset += 2; obj["fontDirectionHint"] = bin.readShort(data, offset); offset += 2; obj["indexToLocFormat"] = bin.readShort(data, offset); offset += 2; obj["glyphDataFormat"] = bin.readShort(data, offset); offset += 2; return obj; } }; Typr["T"].hhea = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readFixed(data, offset); offset += 4; var keys = [ "ascender", "descender", "lineGap", "advanceWidthMax", "minLeftSideBearing", "minRightSideBearing", "xMaxExtent", "caretSlopeRise", "caretSlopeRun", "caretOffset", "res0", "res1", "res2", "res3", "metricDataFormat", "numberOfHMetrics" ]; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var func = key == "advanceWidthMax" || key == "numberOfHMetrics" ? bin.readUshort : bin.readShort; obj[key] = func(data, offset + i * 2); } return obj; } }; Typr["T"].hmtx = { parseTab: function(data, offset, length, font) { var bin = Typr["B"]; var aWidth = []; var lsBearing = []; var nG = font["maxp"]["numGlyphs"], nH = font["hhea"]["numberOfHMetrics"]; var aw = 0, lsb = 0, i = 0; while (i < nH) { aw = bin.readUshort(data, offset + (i << 2)); lsb = bin.readShort(data, offset + (i << 2) + 2); aWidth.push(aw); lsBearing.push(lsb); i++; } while (i < nG) { aWidth.push(aw); lsBearing.push(lsb); i++; } return { aWidth: aWidth, lsBearing: lsBearing }; } }; Typr["T"].kern = { parseTab: function(data, offset, length, font) { var bin = Typr["B"], kern = Typr["T"].kern; var version = bin.readUshort(data, offset); if (version == 1) return kern.parseV1(data, offset, length, font); var nTables = bin.readUshort(data, offset + 2); offset += 4; var map = { glyph1: [], rval: [] }; for (var i = 0; i < nTables; i++) { offset += 2; var length = bin.readUshort(data, offset); offset += 2; var coverage = bin.readUshort(data, offset); offset += 2; var format = coverage >>> 8; format &= 15; if (format == 0) offset = kern.readFormat0(data, offset, map); } return map; }, parseV1: function(data, offset, length, font) { var bin = Typr["B"], kern = Typr["T"].kern; bin.readFixed(data, offset); var nTables = bin.readUint(data, offset + 4); offset += 8; var map = { glyph1: [], rval: [] }; for (var i = 0; i < nTables; i++) { bin.readUint(data, offset); offset += 4; var coverage = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var format = coverage & 255; if (format == 0) offset = kern.readFormat0(data, offset, map); } return map; }, readFormat0: function(data, offset, map) { var bin = Typr["B"], rUs = bin.readUshort; var pleft = -1; var nPairs = rUs(data, offset); rUs(data, offset + 2); rUs(data, offset + 4); rUs(data, offset + 6); offset += 8; for (var j = 0; j < nPairs; j++) { var left = rUs(data, offset); offset += 2; var right = rUs(data, offset); offset += 2; var value = bin.readShort(data, offset); offset += 2; if (left != pleft) { map.glyph1.push(left); map.rval.push({ glyph2: [], vals: [] }); } var rval = map.rval[map.rval.length - 1]; rval.glyph2.push(right); rval.vals.push(value); pleft = left; } return offset; } }; Typr["T"].loca = { parseTab: function(data, offset, length, font) { var bin = Typr["B"]; var obj = []; var ver = font["head"]["indexToLocFormat"]; var len = font["maxp"]["numGlyphs"] + 1; if (ver == 0) for (var i = 0; i < len; i++) obj.push(bin.readUshort(data, offset + (i << 1)) << 1); if (ver == 1) for (var i = 0; i < len; i++) obj.push(bin.readUint(data, offset + (i << 2))); return obj; } }; Typr["T"].maxp = { parseTab: function(data, offset, length) { var bin = Typr["B"], rU = bin.readUshort; var obj = {}; bin.readUint(data, offset); offset += 4; obj["numGlyphs"] = rU(data, offset); offset += 2; return obj; } }; Typr["T"].name = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readUshort(data, offset); offset += 2; var count = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var names = [ "copyright", "fontFamily", "fontSubfamily", "ID", "fullName", "version", "postScriptName", "trademark", "manufacturer", "designer", "description", "urlVendor", "urlDesigner", "licence", "licenceURL", "---", "typoFamilyName", "typoSubfamilyName", "compatibleFull", "sampleText", "postScriptCID", "wwsFamilyName", "wwsSubfamilyName", "lightPalette", "darkPalette" ]; var offset0 = offset; var rU = bin.readUshort; for (var i = 0; i < count; i++) { var platformID = rU(data, offset); offset += 2; var encodingID = rU(data, offset); offset += 2; var languageID = rU(data, offset); offset += 2; var nameID = rU(data, offset); offset += 2; var slen = rU(data, offset); offset += 2; var noffset = rU(data, offset); offset += 2; var soff = offset0 + count * 12 + noffset; var str; if (platformID == 0) str = bin.readUnicode(data, soff, slen / 2); else if (platformID == 3 && encodingID == 0) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 0) str = bin.readASCII(data, soff, slen); else if (encodingID == 1) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 3) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 4) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 10) str = bin.readUnicode(data, soff, slen / 2); else if (platformID == 1) { str = bin.readASCII(data, soff, slen); console.log("reading unknown MAC encoding " + encodingID + " as ASCII"); } else { console.log("unknown encoding " + encodingID + ", platformID: " + platformID); str = bin.readASCII(data, soff, slen); } var tid = "p" + platformID + "," + languageID.toString(16); if (obj[tid] == null) obj[tid] = {}; obj[tid][names[nameID]] = str; obj[tid]["_lang"] = languageID; } var psn = "postScriptName"; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 1033) return obj[p]; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 0) return obj[p]; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 3084) return obj[p]; for (var p in obj) if (obj[p][psn] != null) return obj[p]; var out; for (var p in obj) { out = obj[p]; break; } console.log("returning name table with languageID " + out._lang); if (out[psn] == null && out["ID"] != null) out[psn] = out["ID"]; return out; } }; Typr["T"].OS2 = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var ver = bin.readUshort(data, offset); offset += 2; var OS2 = Typr["T"].OS2; var obj = {}; if (ver == 0) OS2.version0(data, offset, obj); else if (ver == 1) OS2.version1(data, offset, obj); else if (ver == 2 || ver == 3 || ver == 4) OS2.version2(data, offset, obj); else if (ver == 5) OS2.version5(data, offset, obj); else throw "unknown OS/2 table version: " + ver; return obj; }, version0: function(data, offset, obj) { var bin = Typr["B"]; obj["xAvgCharWidth"] = bin.readShort(data, offset); offset += 2; obj["usWeightClass"] = bin.readUshort(data, offset); offset += 2; obj["usWidthClass"] = bin.readUshort(data, offset); offset += 2; obj["fsType"] = bin.readUshort(data, offset); offset += 2; obj["ySubscriptXSize"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptYSize"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptXOffset"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptYOffset"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptXSize"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptYSize"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptXOffset"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptYOffset"] = bin.readShort(data, offset); offset += 2; obj["yStrikeoutSize"] = bin.readShort(data, offset); offset += 2; obj["yStrikeoutPosition"] = bin.readShort(data, offset); offset += 2; obj["sFamilyClass"] = bin.readShort(data, offset); offset += 2; obj["panose"] = bin.readBytes(data, offset, 10); offset += 10; obj["ulUnicodeRange1"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange2"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange3"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange4"] = bin.readUint(data, offset); offset += 4; obj["achVendID"] = bin.readASCII(data, offset, 4); offset += 4; obj["fsSelection"] = bin.readUshort(data, offset); offset += 2; obj["usFirstCharIndex"] = bin.readUshort(data, offset); offset += 2; obj["usLastCharIndex"] = bin.readUshort(data, offset); offset += 2; obj["sTypoAscender"] = bin.readShort(data, offset); offset += 2; obj["sTypoDescender"] = bin.readShort(data, offset); offset += 2; obj["sTypoLineGap"] = bin.readShort(data, offset); offset += 2; obj["usWinAscent"] = bin.readUshort(data, offset); offset += 2; obj["usWinDescent"] = bin.readUshort(data, offset); offset += 2; return offset; }, version1: function(data, offset, obj) { var bin = Typr["B"]; offset = Typr["T"].OS2.version0(data, offset, obj); obj["ulCodePageRange1"] = bin.readUint(data, offset); offset += 4; obj["ulCodePageRange2"] = bin.readUint(data, offset); offset += 4; return offset; }, version2: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUshort; offset = Typr["T"].OS2.version1(data, offset, obj); obj["sxHeight"] = bin.readShort(data, offset); offset += 2; obj["sCapHeight"] = bin.readShort(data, offset); offset += 2; obj["usDefault"] = rU(data, offset); offset += 2; obj["usBreak"] = rU(data, offset); offset += 2; obj["usMaxContext"] = rU(data, offset); offset += 2; return offset; }, version5: function(data, offset, obj) { var rU = Typr["B"].readUshort; offset = Typr["T"].OS2.version2(data, offset, obj); obj["usLowerOpticalPointSize"] = rU(data, offset); offset += 2; obj["usUpperOpticalPointSize"] = rU(data, offset); offset += 2; return offset; } }; Typr["T"].post = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; obj["version"] = bin.readFixed(data, offset); offset += 4; obj["italicAngle"] = bin.readFixed(data, offset); offset += 4; obj["underlinePosition"] = bin.readShort(data, offset); offset += 2; obj["underlineThickness"] = bin.readShort(data, offset); offset += 2; return obj; } }; Typr["T"].SVG = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = { entries: [] }; var offset0 = offset; bin.readUshort(data, offset); offset += 2; var svgDocIndexOffset = bin.readUint(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; offset = svgDocIndexOffset + offset0; var numEntries = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < numEntries; i++) { var startGlyphID = bin.readUshort(data, offset); offset += 2; var endGlyphID = bin.readUshort(data, offset); offset += 2; var svgDocOffset = bin.readUint(data, offset); offset += 4; var svgDocLength = bin.readUint(data, offset); offset += 4; var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength); var svg = bin.readUTF8(sbuf, 0, sbuf.length); for (var f = startGlyphID; f <= endGlyphID; f++) { obj.entries[f] = svg; } } return obj; } }; Typr["U"] = { shape: function(font, str, ltr) { var getGlyphPosition = function(font, gls, i1, ltr) { var g1 = gls[i1], g2 = gls[i1 + 1], kern = font["kern"]; if (kern) { var ind1 = kern.glyph1.indexOf(g1); if (ind1 != -1) { var ind2 = kern.rval[ind1].glyph2.indexOf(g2); if (ind2 != -1) return [ 0, 0, kern.rval[ind1].vals[ind2], 0 ]; } } return [ 0, 0, 0, 0 ]; }; var gls = []; for (var i = 0; i < str.length; i++) { var cc = str.codePointAt(i); if (cc > 65535) i++; gls.push(Typr["U"]["codeToGlyph"](font, cc)); } var shape = []; for (var i = 0; i < gls.length; i++) { var padj = getGlyphPosition(font, gls, i); var gid = gls[i]; var ax = font["hmtx"].aWidth[gid] + padj[2]; shape.push({ g: gid, cl: i, dx: 0, dy: 0, ax: ax, ay: 0 }); } return shape; }, shapeToPath: function(font, shape, clr) { var tpath = { cmds: [], crds: [] }; var x = 0, y = 0; for (var i = 0; i < shape.length; i++) { var it = shape[i]; var path = Typr["U"]["glyphToPath"](font, it["g"]), crds = path["crds"]; for (var j = 0; j < crds.length; j += 2) { tpath.crds.push(crds[j] + x + it["dx"]); tpath.crds.push(crds[j + 1] + y + it["dy"]); } if (clr) tpath.cmds.push(clr); for (var j = 0; j < path["cmds"].length; j++) tpath.cmds.push(path["cmds"][j]); var clen = tpath.cmds.length; if (clr) if (clen != 0 && tpath.cmds[clen - 1] != "X") tpath.cmds.push("X"); x += it["ax"]; y += it["ay"]; } return { cmds: tpath.cmds, crds: tpath.crds }; }, codeToGlyph: function(font, code) { var cmap = font["cmap"]; var tind = -1, pps = [ "p3e10", "p0e4", "p3e1", "p1e0", "p0e3", "p0e1" ]; for (var i = 0; i < pps.length; i++) if (cmap.ids[pps[i]] != null) { tind = cmap.ids[pps[i]]; break; } if (tind == -1) throw "no familiar platform and encoding!"; var arrSearch = function(arr, k, v) { var l = 0, r = Math.floor(arr.length / k); while (l + 1 != r) { var mid = l + (r - l >>> 1); if (arr[mid * k] <= v) l = mid; else r = mid; } return l * k; }; var tab = cmap.tables[tind], fmt = tab.format, gid = -1; if (fmt == 0) { if (code >= tab.map.length) gid = 0; else gid = tab.map[code]; } else if (fmt == 4) { var sind = -1, ec = tab.endCount; if (code > ec[ec.length - 1]) sind = -1; else { sind = arrSearch(ec, 1, code); if (ec[sind] < code) sind++; } if (sind == -1) gid = 0; else if (code < tab.startCount[sind]) gid = 0; else { var gli = 0; if (tab.idRangeOffset[sind] != 0) gli = tab.glyphIdArray[code - tab.startCount[sind] + (tab.idRangeOffset[sind] >> 1) - (tab.idRangeOffset.length - sind)]; else gli = code + tab.idDelta[sind]; gid = gli & 65535; } } else if (fmt == 6) { var off = code - tab.firstCode, arr = tab.glyphIdArray; if (off < 0 || off >= arr.length) gid = 0; else gid = arr[off]; } else if (fmt == 12) { var grp = tab.groups; if (code > grp[grp.length - 2]) gid = 0; else { var i = arrSearch(grp, 3, code); if (grp[i] <= code && code <= grp[i + 1]) { gid = grp[i + 2] + (code - grp[i]); } if (gid == -1) gid = 0; } } else throw "unknown cmap table format " + tab.format; var SVG = font["SVG "], loca = font["loca"]; if (gid != 0 && font["CFF "] == null && (SVG == null || SVG.entries[gid] == null) && loca[gid] == loca[gid + 1] && [ 9, 10, 11, 12, 13, 32, 133, 160, 5760, 8232, 8233, 8239, 12288, 6158, 8203, 8204, 8205, 8288, 65279 ].indexOf(code) == -1 && !(8192 <= code && code <= 8202)) gid = 0; return gid; }, glyphToPath: function(font, gid) { var path = { cmds: [], crds: [] }; var SVG = font["SVG "], CFF = font["CFF "]; var U = Typr["U"]; if (SVG && SVG.entries[gid]) { var p = SVG.entries[gid]; if (p != null) { if (typeof p == "string") { p = U["SVG"].toPath(p); SVG.entries[gid] = p; } path = p; } } else if (CFF) { var pdct = CFF["Private"]; var state = { x: 0, y: 0, stack: [], nStems: 0, haveWidth: false, width: pdct ? pdct["defaultWidthX"] : 0, open: false }; if (CFF["ROS"]) { var gi = 0; while (CFF["FDSelect"][gi + 2] <= gid) gi += 2; pdct = CFF["FDArray"][CFF["FDSelect"][gi + 1]]["Private"]; } U["_drawCFF"](CFF["CharStrings"][gid], state, CFF, pdct, path); } else if (font["glyf"]) { U["_drawGlyf"](gid, font, path); } return { cmds: path.cmds, crds: path.crds }; }, _drawGlyf: function(gid, font, path) { var gl = font["glyf"][gid]; if (gl == null) gl = font["glyf"][gid] = Typr["T"].glyf._parseGlyf(font, gid); if (gl != null) { if (gl.noc > -1) Typr["U"]["_simpleGlyph"](gl, path); else Typr["U"]["_compoGlyph"](gl, font, path); } }, _simpleGlyph: function(gl, p) { var P = Typr["U"]["P"]; for (var c = 0; c < gl.noc; c++) { var i0 = c == 0 ? 0 : gl.endPts[c - 1] + 1; var il = gl.endPts[c]; for (var i = i0; i <= il; i++) { var pr = i == i0 ? il : i - 1; var nx = i == il ? i0 : i + 1; var onCurve = gl.flags[i] & 1; var prOnCurve = gl.flags[pr] & 1; var nxOnCurve = gl.flags[nx] & 1; var x = gl.xs[i], y = gl.ys[i]; if (i == i0) { if (onCurve) { if (prOnCurve) P.MoveTo(p, gl.xs[pr], gl.ys[pr]); else { P.MoveTo(p, x, y); continue; } } else { if (prOnCurve) P.MoveTo(p, gl.xs[pr], gl.ys[pr]); else P.MoveTo(p, Math.floor((gl.xs[pr] + x) * .5), Math.floor((gl.ys[pr] + y) * .5)); } } if (onCurve) { if (prOnCurve) P.LineTo(p, x, y); } else { if (nxOnCurve) P.qCurveTo(p, x, y, gl.xs[nx], gl.ys[nx]); else P.qCurveTo(p, x, y, Math.floor((x + gl.xs[nx]) * .5), Math.floor((y + gl.ys[nx]) * .5)); } } P.ClosePath(p); } }, _compoGlyph: function(gl, font, p) { for (var j = 0; j < gl.parts.length; j++) { var path = { cmds: [], crds: [] }; var prt = gl.parts[j]; Typr["U"]["_drawGlyf"](prt.glyphIndex, font, path); var m = prt.m; for (var i = 0; i < path.crds.length; i += 2) { var x = path.crds[i], y = path.crds[i + 1]; p.crds.push(x * m.a + y * m.b + m.tx); p.crds.push(x * m.c + y * m.d + m.ty); } for (var i = 0; i < path.cmds.length; i++) p.cmds.push(path.cmds[i]); } }, pathToSVG: function(path, prec) { var cmds = path["cmds"], crds = path["crds"]; if (prec == null) prec = 5; var out = [], co = 0, lmap = { M: 2, L: 2, Q: 4, C: 6 }; for (var i = 0; i < cmds.length; i++) { var cmd = cmds[i], cn = co + (lmap[cmd] ? lmap[cmd] : 0); out.push(cmd); while (co < cn) { var c = crds[co++]; out.push(parseFloat(c.toFixed(prec)) + (co == cn ? "" : " ")); } } return out.join(""); }, SVGToPath: function(d) { var pth = { cmds: [], crds: [] }; Typr["U"]["SVG"].svgToPath(d, pth); return { cmds: pth.cmds, crds: pth.crds }; }, pathToContext: function(path, ctx) { var c = 0, cmds = path["cmds"], crds = path["crds"]; for (var j = 0; j < cmds.length; j++) { var cmd = cmds[j]; if (cmd == "M") { ctx.moveTo(crds[c], crds[c + 1]); c += 2; } else if (cmd == "L") { ctx.lineTo(crds[c], crds[c + 1]); c += 2; } else if (cmd == "C") { ctx.bezierCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3], crds[c + 4], crds[c + 5]); c += 6; } else if (cmd == "Q") { ctx.quadraticCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3]); c += 4; } else if (cmd.charAt(0) == "#") { ctx.beginPath(); ctx.fillStyle = cmd; } else if (cmd == "Z") { ctx.closePath(); } else if (cmd == "X") { ctx.fill(); } } }, P: { MoveTo: function(p, x, y) { p.cmds.push("M"); p.crds.push(x, y); }, LineTo: function(p, x, y) { p.cmds.push("L"); p.crds.push(x, y); }, CurveTo: function(p, a, b, c, d, e, f) { p.cmds.push("C"); p.crds.push(a, b, c, d, e, f); }, qCurveTo: function(p, a, b, c, d) { p.cmds.push("Q"); p.crds.push(a, b, c, d); }, ClosePath: function(p) { p.cmds.push("Z"); } }, _drawCFF: function(cmds, state, font, pdct, p) { var stack = state.stack; var nStems = state.nStems, haveWidth = state.haveWidth, width = state.width, open = state.open; var i = 0; var x = state.x, y = state.y, c1x = 0, c1y = 0, c2x = 0, c2y = 0, c3x = 0, c3y = 0, c4x = 0, c4y = 0, jpx = 0, jpy = 0; var CFF = Typr["T"].CFF, P = Typr["U"]["P"]; var nominalWidthX = pdct["nominalWidthX"]; var o = { val: 0, size: 0 }; while (i < cmds.length) { CFF.getCharString(cmds, i, o); var v = o.val; i += o.size; if (v == "o1" || v == "o18") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; } else if (v == "o3" || v == "o23") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; } else if (v == "o4") { if (stack.length > 1 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } if (open) P.ClosePath(p); y += stack.pop(); P.MoveTo(p, x, y); open = true; } else if (v == "o5") { while (stack.length > 0) { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } } else if (v == "o6" || v == "o7") { var count = stack.length; var isX = v == "o6"; for (var j = 0; j < count; j++) { var sval = stack.shift(); if (isX) x += sval; else y += sval; isX = !isX; P.LineTo(p, x, y); } } else if (v == "o8" || v == "o24") { var count = stack.length; var index = 0; while (index + 6 <= count) { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); index += 6; } if (v == "o24") { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } } else if (v == "o11") break; else if (v == "o1234" || v == "o1235" || v == "o1236" || v == "o1237") { if (v == "o1234") { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y; c3x = jpx + stack.shift(); c3y = c2y; c4x = c3x + stack.shift(); c4y = y; x = c4x + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1235") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y + stack.shift(); c3x = jpx + stack.shift(); c3y = jpy + stack.shift(); c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); x = c4x + stack.shift(); y = c4y + stack.shift(); stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1236") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y; c3x = jpx + stack.shift(); c3y = c2y; c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); x = c4x + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1237") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y + stack.shift(); c3x = jpx + stack.shift(); c3y = jpy + stack.shift(); c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); if (Math.abs(c4x - x) > Math.abs(c4y - y)) { x = c4x + stack.shift(); } else { y = c4y + stack.shift(); } P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } } else if (v == "o14") { if (stack.length > 0 && !haveWidth) { width = stack.shift() + font["nominalWidthX"]; haveWidth = true; } if (stack.length == 4) { var adx = stack.shift(); var ady = stack.shift(); var bchar = stack.shift(); var achar = stack.shift(); var bind = CFF.glyphBySE(font, bchar); var aind = CFF.glyphBySE(font, achar); Typr["U"]["_drawCFF"](font["CharStrings"][bind], state, font, pdct, p); state.x = adx; state.y = ady; Typr["U"]["_drawCFF"](font["CharStrings"][aind], state, font, pdct, p); } if (open) { P.ClosePath(p); open = false; } } else if (v == "o19" || v == "o20") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; i += nStems + 7 >> 3; } else if (v == "o21") { if (stack.length > 2 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } y += stack.pop(); x += stack.pop(); if (open) P.ClosePath(p); P.MoveTo(p, x, y); open = true; } else if (v == "o22") { if (stack.length > 1 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } x += stack.pop(); if (open) P.ClosePath(p); P.MoveTo(p, x, y); open = true; } else if (v == "o25") { while (stack.length > 6) { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } else if (v == "o26") { if (stack.length % 2) { x += stack.shift(); } while (stack.length > 0) { c1x = x; c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x; y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } } else if (v == "o27") { if (stack.length % 2) { y += stack.shift(); } while (stack.length > 0) { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y; P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } } else if (v == "o10" || v == "o29") { var obj = v == "o10" ? pdct : font; if (stack.length == 0) { console.log("error: empty stack"); } else { var ind = stack.pop(); var subr = obj["Subrs"][ind + obj["Bias"]]; state.x = x; state.y = y; state.nStems = nStems; state.haveWidth = haveWidth; state.width = width; state.open = open; Typr["U"]["_drawCFF"](subr, state, font, pdct, p); x = state.x; y = state.y; nStems = state.nStems; haveWidth = state.haveWidth; width = state.width; open = state.open; } } else if (v == "o30" || v == "o31") { var count, count1 = stack.length; var index = 0; var alternate = v == "o31"; count = count1 & ~2; index += count1 - count; while (index < count) { if (alternate) { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); y = c2y + stack.shift(); if (count - index == 5) { x = c2x + stack.shift(); index++; } else x = c2x; alternate = false; } else { c1x = x; c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); if (count - index == 5) { y = c2y + stack.shift(); index++; } else y = c2y; alternate = true; } P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); index += 4; } } else if ((v + "").charAt(0) == "o") { console.log("Unknown operation: " + v, cmds); throw v; } else stack.push(v); } state.x = x; state.y = y; state.nStems = nStems; state.haveWidth = haveWidth; state.width = width; state.open = open; }, SVG: function() { var M = { getScale: function(m) { return Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])); }, translate: function(m, x, y) { M.concat(m, [ 1, 0, 0, 1, x, y ]); }, rotate: function(m, a) { M.concat(m, [ Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a), 0, 0 ]); }, scale: function(m, x, y) { M.concat(m, [ x, 0, 0, y, 0, 0 ]); }, concat: function(m, w) { var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5]; m[0] = a * w[0] + b * w[2]; m[1] = a * w[1] + b * w[3]; m[2] = c * w[0] + d * w[2]; m[3] = c * w[1] + d * w[3]; m[4] = tx * w[0] + ty * w[2] + w[4]; m[5] = tx * w[1] + ty * w[3] + w[5]; }, invert: function(m) { var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5], adbc = a * d - b * c; m[0] = d / adbc; m[1] = -b / adbc; m[2] = -c / adbc; m[3] = a / adbc; m[4] = (c * ty - d * tx) / adbc; m[5] = (b * tx - a * ty) / adbc; }, multPoint: function(m, p) { var x = p[0], y = p[1]; return [ x * m[0] + y * m[2] + m[4], x * m[1] + y * m[3] + m[5] ]; }, multArray: function(m, a) { for (var i = 0; i < a.length; i += 2) { var x = a[i], y = a[i + 1]; a[i] = x * m[0] + y * m[2] + m[4]; a[i + 1] = x * m[1] + y * m[3] + m[5]; } } }; function _bracketSplit(str, lbr, rbr) { var out = [], pos = 0, ci = 0, lvl = 0; while (true) { var li = str.indexOf(lbr, ci); var ri = str.indexOf(rbr, ci); if (li == -1 && ri == -1) break; if (ri == -1 || li != -1 && li < ri) { if (lvl == 0) { out.push(str.slice(pos, li).trim()); pos = li + 1; } lvl++; ci = li + 1; } else if (li == -1 || ri != -1 && ri < li) { lvl--; if (lvl == 0) { out.push(str.slice(pos, ri).trim()); pos = ri + 1; } ci = ri + 1; } } return out; } function cssMap(str) { var pts = _bracketSplit(str, "{", "}"); var css = {}; for (var i = 0; i < pts.length; i += 2) { var cn = pts[i].split(","); for (var j = 0; j < cn.length; j++) { var cnj = cn[j].trim(); if (css[cnj] == null) css[cnj] = ""; css[cnj] += pts[i + 1]; } } return css; } function readTrnf(trna) { var pts = _bracketSplit(trna, "(", ")"); var m = [ 1, 0, 0, 1, 0, 0 ]; for (var i = 0; i < pts.length; i += 2) { var om = m; m = _readTrnsAttr(pts[i], pts[i + 1]); M.concat(m, om); } return m; } function _readTrnsAttr(fnc, vls) { var m = [ 1, 0, 0, 1, 0, 0 ], gotSep = true; for (var i = 0; i < vls.length; i++) { var ch = vls.charAt(i); if (ch == "," || ch == " ") gotSep = true; else if (ch == ".") { if (!gotSep) { vls = vls.slice(0, i) + "," + vls.slice(i); i++; } gotSep = false; } else if (ch == "-" && i > 0 && vls[i - 1] != "e") { vls = vls.slice(0, i) + " " + vls.slice(i); i++; gotSep = true; } } vls = vls.split(/\s*[\s,]\s*/).map(parseFloat); if (fnc == "translate") { if (vls.length == 1) M.translate(m, vls[0], 0); else M.translate(m, vls[0], vls[1]); } else if (fnc == "scale") { if (vls.length == 1) M.scale(m, vls[0], vls[0]); else M.scale(m, vls[0], vls[1]); } else if (fnc == "rotate") { var tx = 0, ty = 0; if (vls.length != 1) { tx = vls[1]; ty = vls[2]; } M.translate(m, -tx, -ty); M.rotate(m, -Math.PI * vls[0] / 180); M.translate(m, tx, ty); } else if (fnc == "matrix") m = vls; else console.log("unknown transform: ", fnc); return m; } function toPath(str) { var pth = { cmds: [], crds: [] }; if (str == null) return pth; var prsr = new DOMParser(); var doc = prsr["parseFromString"](str, "image/svg+xml"); var svg = doc.getElementsByTagName("svg")[0]; var vb = svg.getAttribute("viewBox"); if (vb) vb = vb.trim().split(" ").map(parseFloat); else vb = [ 0, 0, 1e3, 1e3 ]; _toPath(svg.children, pth); for (var i = 0; i < pth.crds.length; i += 2) { var x = pth.crds[i], y = pth.crds[i + 1]; x -= vb[0]; y -= vb[1]; y = -y; pth.crds[i] = x; pth.crds[i + 1] = y; } return pth; } function _toPath(nds, pth, fill) { for (var ni = 0; ni < nds.length; ni++) { var nd = nds[ni], tn = nd.tagName; var cfl = nd.getAttribute("fill"); if (cfl == null) cfl = fill; if (tn == "g") { var tp = { crds: [], cmds: [] }; _toPath(nd.children, tp, cfl); var trf = nd.getAttribute("transform"); if (trf) { var m = readTrnf(trf); M.multArray(m, tp.crds); } pth.crds = pth.crds.concat(tp.crds); pth.cmds = pth.cmds.concat(tp.cmds); } else if (tn == "path" || tn == "circle" || tn == "ellipse") { pth.cmds.push(cfl ? cfl : "#000000"); var d; if (tn == "path") d = nd.getAttribute("d"); if (tn == "circle" || tn == "ellipse") { var vls = [ 0, 0, 0, 0 ], nms = [ "cx", "cy", "rx", "ry", "r" ]; for (var i = 0; i < 5; i++) { var V = nd.getAttribute(nms[i]); if (V) { V = parseFloat(V); if (i < 4) vls[i] = V; else vls[2] = vls[3] = V; } } var cx = vls[0], cy = vls[1], rx = vls[2], ry = vls[3]; d = [ "M", cx - rx, cy, "a", rx, ry, 0, 1, 0, rx * 2, 0, "a", rx, ry, 0, 1, 0, -rx * 2, 0 ].join(" "); } svgToPath(d, pth); pth.cmds.push("X"); } else if (tn == "defs"); else console.log(tn, nd); } } function _tokens(d) { var ts = [], off = 0, rn = false, cn = "", pc = ""; while (off < d.length) { var cc = d.charCodeAt(off), ch = d.charAt(off); off++; var isNum = 48 <= cc && cc <= 57 || ch == "." || ch == "-" || ch == "e" || ch == "E"; if (rn) { if (ch == "-" && pc != "e" || ch == "." && cn.indexOf(".") != -1) { ts.push(parseFloat(cn)); cn = ch; } else if (isNum) cn += ch; else { ts.push(parseFloat(cn)); if (ch != "," && ch != " ") ts.push(ch); rn = false; } } else { if (isNum) { cn = ch; rn = true; } else if (ch != "," && ch != " ") ts.push(ch); } pc = ch; } if (rn) ts.push(parseFloat(cn)); return ts; } function _reps(ts, off, ps) { var i = off; while (i < ts.length) { if (typeof ts[i] == "string") break; i += ps; } return (i - off) / ps; } function svgToPath(d, pth) { var ts = _tokens(d); var i = 0, x = 0, y = 0, ox = 0, oy = 0, oldo = pth.crds.length; var pc = { M: 2, L: 2, H: 1, V: 1, T: 2, S: 4, A: 7, Q: 4, C: 6 }; var cmds = pth.cmds, crds = pth.crds; while (i < ts.length) { var cmd = ts[i]; i++; var cmu = cmd.toUpperCase(); if (cmu == "Z") { cmds.push("Z"); x = ox; y = oy; } else { var ps = pc[cmu], reps = _reps(ts, i, ps); for (var j = 0; j < reps; j++) { if (j == 1 && cmu == "M") { cmd = cmd == cmu ? "L" : "l"; cmu = "L"; } var xi = 0, yi = 0; if (cmd != cmu) { xi = x; yi = y; } if (cmu == "M") { x = xi + ts[i++]; y = yi + ts[i++]; cmds.push("M"); crds.push(x, y); ox = x; oy = y; } else if (cmu == "L") { x = xi + ts[i++]; y = yi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "H") { x = xi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "V") { y = yi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "Q") { var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++]; cmds.push("Q"); crds.push(x1, y1, x2, y2); x = x2; y = y2; } else if (cmu == "T") { var co = Math.max(crds.length - 2, oldo); var x1 = x + x - crds[co], y1 = y + y - crds[co + 1]; var x2 = xi + ts[i++], y2 = yi + ts[i++]; cmds.push("Q"); crds.push(x1, y1, x2, y2); x = x2; y = y2; } else if (cmu == "C") { var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"); crds.push(x1, y1, x2, y2, x3, y3); x = x3; y = y3; } else if (cmu == "S") { var co = Math.max(crds.length - (cmds[cmds.length - 1] == "C" ? 4 : 2), oldo); var x1 = x + x - crds[co], y1 = y + y - crds[co + 1]; var x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"); crds.push(x1, y1, x2, y2, x3, y3); x = x3; y = y3; } else if (cmu == "A") { var x1 = x, y1 = y; var rx = ts[i++], ry = ts[i++]; var phi = ts[i++] * (Math.PI / 180), fA = ts[i++], fS = ts[i++]; var x2 = xi + ts[i++], y2 = yi + ts[i++]; if (x2 == x && y2 == y && rx == 0 && ry == 0) continue; var hdx = (x1 - x2) / 2, hdy = (y1 - y2) / 2; var cosP = Math.cos(phi), sinP = Math.sin(phi); var x1A = cosP * hdx + sinP * hdy; var y1A = -sinP * hdx + cosP * hdy; var rxS = rx * rx, ryS = ry * ry; var x1AS = x1A * x1A, y1AS = y1A * y1A; var frc = (rxS * ryS - rxS * y1AS - ryS * x1AS) / (rxS * y1AS + ryS * x1AS); var coef = (fA != fS ? 1 : -1) * Math.sqrt(Math.max(frc, 0)); var cxA = coef * (rx * y1A) / ry; var cyA = -coef * (ry * x1A) / rx; var cx = cosP * cxA - sinP * cyA + (x1 + x2) / 2; var cy = sinP * cxA + cosP * cyA + (y1 + y2) / 2; var angl = function(ux, uy, vx, vy) { var lU = Math.sqrt(ux * ux + uy * uy), lV = Math.sqrt(vx * vx + vy * vy); var num = (ux * vx + uy * vy) / (lU * lV); return (ux * vy - uy * vx >= 0 ? 1 : -1) * Math.acos(Math.max(-1, Math.min(1, num))); }; var vX = (x1A - cxA) / rx, vY = (y1A - cyA) / ry; var theta1 = angl(1, 0, vX, vY); var dtheta = angl(vX, vY, (-x1A - cxA) / rx, (-y1A - cyA) / ry); dtheta = dtheta % (2 * Math.PI); var arc = function(gst, x, y, r, a0, a1, neg) { var rotate = function(m, a) { var si = Math.sin(a), co = Math.cos(a); var a = m[0], b = m[1], c = m[2], d = m[3]; m[0] = a * co + b * si; m[1] = -a * si + b * co; m[2] = c * co + d * si; m[3] = -c * si + d * co; }; var multArr = function(m, a) { for (var j = 0; j < a.length; j += 2) { var x = a[j], y = a[j + 1]; a[j] = m[0] * x + m[2] * y + m[4]; a[j + 1] = m[1] * x + m[3] * y + m[5]; } }; var concatA = function(a, b) { for (var j = 0; j < b.length; j++) a.push(b[j]); }; var concatP = function(p, r) { concatA(p.cmds, r.cmds); concatA(p.crds, r.crds); }; if (neg) while (a1 > a0) a1 -= 2 * Math.PI; else while (a1 < a0) a1 += 2 * Math.PI; var th = (a1 - a0) / 4; var x0 = Math.cos(th / 2), y0 = -Math.sin(th / 2); var x1 = (4 - x0) / 3, y1 = y0 == 0 ? y0 : (1 - x0) * (3 - x0) / (3 * y0); var x2 = x1, y2 = -y1; var x3 = x0, y3 = -y0; var ps = [ x1, y1, x2, y2, x3, y3 ]; var pth = { cmds: [ "C", "C", "C", "C" ], crds: ps.slice(0) }; var rot = [ 1, 0, 0, 1, 0, 0 ]; rotate(rot, -th); for (var j = 0; j < 3; j++) { multArr(rot, ps); concatA(pth.crds, ps); } rotate(rot, -a0 + th / 2); rot[0] *= r; rot[1] *= r; rot[2] *= r; rot[3] *= r; rot[4] = x; rot[5] = y; multArr(rot, pth.crds); multArr(gst.ctm, pth.crds); concatP(gst.pth, pth); }; var gst = { pth: pth, ctm: [ rx * cosP, rx * sinP, -ry * sinP, ry * cosP, cx, cy ] }; arc(gst, 0, 0, 1, theta1, theta1 + dtheta, fS == 0); x = x2; y = y2; } else console.log("Unknown SVG command " + cmd); } } } } return { cssMap: cssMap, readTrnf: readTrnf, svgToPath: svgToPath, toPath: toPath }; }(), initHB: function(hurl, resp) { var codeLength = function(code) { var len = 0; if ((code & 4294967295 - (1 << 7) + 1) == 0) { len = 1; } else if ((code & 4294967295 - (1 << 11) + 1) == 0) { len = 2; } else if ((code & 4294967295 - (1 << 16) + 1) == 0) { len = 3; } else if ((code & 4294967295 - (1 << 21) + 1) == 0) { len = 4; } return len; }; var te = new window["TextEncoder"]("utf8"); fetch(hurl).then(function(x) { return x["arrayBuffer"](); }).then(function(ab) { return WebAssembly["instantiate"](ab); }).then(function(res) { console.log("HB ready"); var exp = res["instance"]["exports"], mem = exp["memory"]; mem["grow"](700); var heapu8 = new Uint8Array(mem.buffer); var u32 = new Uint32Array(mem.buffer); var i32 = new Int32Array(mem.buffer); var __lastFnt, blob, blobPtr, face, font; Typr["U"]["shapeHB"] = function() { var toJson = function(ptr) { var length = exp["hb_buffer_get_length"](ptr); var result = []; var iPtr32 = exp["hb_buffer_get_glyph_infos"](ptr, 0) >>> 2; var pPtr32 = exp["hb_buffer_get_glyph_positions"](ptr, 0) >>> 2; for (var i = 0; i < length; ++i) { var a = iPtr32 + i * 5, b = pPtr32 + i * 5; result.push({ g: u32[a + 0], cl: u32[a + 2], ax: i32[b + 0], ay: i32[b + 1], dx: i32[b + 2], dy: i32[b + 3] }); } return result; }; return function(fnt, str, ltr) { var fdata = fnt["_data"], fn = fnt["name"]["postScriptName"]; if (__lastFnt != fn) { if (blob != null) { exp["hb_blob_destroy"](blob); exp["free"](blobPtr); exp["hb_face_destroy"](face); exp["hb_font_destroy"](font); } blobPtr = exp["malloc"](fdata.byteLength); heapu8.set(fdata, blobPtr); blob = exp["hb_blob_create"](blobPtr, fdata.byteLength, 2, 0, 0); face = exp["hb_face_create"](blob, 0); font = exp["hb_font_create"](face); __lastFnt = fn; } var buffer = exp["hb_buffer_create"](); var bytes = te["encode"](str); var len = bytes.length, strp = exp["malloc"](len); heapu8.set(bytes, strp); exp["hb_buffer_add_utf8"](buffer, strp, len, 0, len); exp["free"](strp); exp["hb_buffer_set_direction"](buffer, ltr ? 4 : 5); exp["hb_buffer_guess_segment_properties"](buffer); exp["hb_shape"](font, buffer, 0, 0); var json = toJson(buffer); exp["hb_buffer_destroy"](buffer); var arr = json.slice(0); if (!ltr) arr.reverse(); var ci = 0, bi = 0; for (var i = 1; i < arr.length; i++) { var gl = arr[i], cl = gl["cl"]; while (true) { var cpt = str.codePointAt(ci), cln = codeLength(cpt); if (bi + cln <= cl) { bi += cln; ci += cpt <= 65535 ? 1 : 2; } else break; } gl["cl"] = ci; } return json; }; }(); resp(); }); } }; const QQ_GROUP = [ "854137118" ]; var _self = unsafeWindow; var top = _self; var UE$1; var modelId = "modelId_xx"; const selfintv = setInterval(() => { if (unsafeWindow) { _self = unsafeWindow; top = _self; UE$1 = _self.UE; try { reportOnline(); String.prototype.replaceAll = function(s1, s2) { return this.replace(new RegExp(s1, "gm"), s2); }; while (top !== _self.top) { top = top.parent.document ? top.parent : _self.top; if (top.location.pathname === "/mycourse/studentstudy") break; } } catch (err) { top = _self; } clearInterval(selfintv); } }, GLOBAL.delay); function checkVersion() { function compare(v1 = "0", v2 = "0") { v1 = String(v1).split("."); v2 = String(v2).split("."); const minVersionLens = Math.min(v1.length, v2.length); let result = 0; for (let i = 0; i < minVersionLens; i++) { const curV1 = Number(v1[i]); const curV2 = Number(v2[i]); if (curV1 > curV2) { result = 1; break; } else if (curV1 < curV2) { result = -1; break; } } if (result === 0 && v1.length !== v2.length) { const v1BiggerThenv2 = v1.length > v2.length; const maxLensVersion = v1BiggerThenv2 ? v1 : v2; for (let i = minVersionLens; i < maxLensVersion.length; i++) { const curVersion = Number(maxLensVersion[i]); if (curVersion > 0) { v1BiggerThenv2 ? result = 1 : result = -1; break; } } } return result; } GM_xmlhttpRequest({ method: "GET", url: "https://greasyfork.org/en/scripts/451356.json", timeout: GLOBAL.timeout, onload: function(r) { const obj = JSON.parse(r.responseText); if (obj.name === GM_info.script.name && compare(obj.version, GM_info.script.version) === 1 && new Date(obj.code_updated_at).getTime() + 1e3 * 60 * 60 * 2 < new Date().getTime()) { iframeMsg("update", { v1: GM_info.script.version, v2: obj.version, href: obj.url }); } } }); } top.addEventListener("message", event => { if (event.data.type === "jump") { GLOBAL.index++; iframeMsg("tip", { tip: "准备答第" + (GLOBAL.index + 1) + "题" }); } else if (event.data.type === "stop") { GLOBAL.stop = event.data.val; } else if (event.data.type === "start_pay") { if (event.data.flag) { if (String(GM_getValue("token")).length === 10 || String(GM_getValue("token")).length === 11) { iframeMsg("tip", { tip: "已开启请求收费题库,已实时生效" }); GM_setValue("start_pay", event.data.flag); iframeMsg("start_pay", true); } else { iframeMsg("tip", { tip: "系统检测您的token可能输入有误,请检查" }); } } else { iframeMsg("tip", { tip: "已关闭请求收费题库,已实时生效" }); GM_setValue("start_pay", event.data.flag); iframeMsg("start_pay", false); } } 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") { if (event.data.token.length === 10 || event.data.token.length === 11) { GM_setValue("token", event.data.token); iframeMsg("tip", { tip: "成功设置token,请点击开启付费题库" }); } else { iframeMsg("tip", { tip: "系统检测您的token可能输入有误,请检查" }); } } else if (event.data.type === "save_setting") { GM_setValue("gpt", event.data.gpt); GM_setValue("search_delay", event.data.search_delay); GM_setValue("tiku_adapter", event.data.tiku_adapter); } }, false); $(document).keydown(function(event) { if (event.keyCode === 38) { $("." + modelId).hide(); } else if (event.keyCode === 40) { $("." + modelId).show(); } else if (event.keyCode === 37) { $("." + modelId).hide(); GM_setValue("hide", true); } else if (event.keyCode === 39) { $("." + modelId).show(); GM_setValue("hide", false); GM_setValue("pos", "50px,50px"); } else if (event.keyCode === 83) { GLOBAL.stop = true; iframeMsg("stop", GLOBAL.stop); } else if (event.keyCode === 68) { GLOBAL.stop = false; iframeMsg("stop", GLOBAL.stop); } }); function getAnswerForKey(keys, options) { return keys.map(function(val) { return options[val.charCodeAt(0) - 65]; }); } function setIntervalFunc(flag, func, time) { const interval = setInterval(() => { if (flag()) { clearInterval(interval); func(); } }, time || 1e3); } function getAnswer(str, options, type) { if (type === 0 || type === 1) { const ans = getAnswerForKey(str.match(/[A-G]/gi) || [], options); return ans.length > 0 ? ans : [ str ]; } else { return [ str ]; } } function getQuestionType(str) { if (!str) return; str = str.trim().replaceAll(/\s+/g, ""); if (TYPE[str]) return TYPE[str]; const regex = Object.keys(TYPE).join("|"); const matcher = str.match(regex); if (matcher) return TYPE[matcher[0]]; } function rand(m, n) { return Math.ceil(Math.random() * (n - m + 1) + m - 1); } const TYPE = { "阅读理解(选择)/完型填空": 66, "听力训练": 66, multichoice: 1, singlechoice: 0, SingleChoice: 0, bijudgement: 3, Judgement: 3, "单项选择题": 0, "单项选择": 0, "单选题": 0, "单选": 0, "多选": 1, "多选题": 1, "案例分析": 1, "多项选择题": 1, "多项选择": 1, "客观题": 1, "填空题": 2, "填空": 2, "对错题": 3, "判断题": 3, "判断正误": 3, "判断": 3, "主观题": 4, "问答题": 4, "简答题": 4, "名词解释": 5, "论述题": 6, "计算题": 7, "其它": 8, "分录题": 9, "资料题": 10, "连线题": 11, "排序题": 13, "完形填空": 14, "完型填空": 14, "阅读理解": 15, "口语题": 18, "听力题": 19, "A1A2题": 1, "文件作答": 4, "视频题": 1 }; function sleep(time) { return new Promise(resolve => { setTimeout(resolve, time); }); } function iframeMsg(type, message) { try { top.document.getElementById("iframeNode").contentWindow.vueDefinedProp(type, message); } catch (e) {} } function filterImg(dom) { if (location.host === "ncexam.cug.edu.cn") { String.prototype.trim = function() { return this.replace(/^\s+|\s+$/gm, ""); }; } return $(dom).clone().find("img[src]").replaceWith(function() { return $("
").text('
/gi, "");
obj.options = obj.options.map(i => {
return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim();
});
}
});
function parseIcve(questions) {
return questions.map(item => {
const options = item.Selects.map(opt => {
return formatString(opt);
});
const type = getQuestionType(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: answerKey,
options: type === 3 ? [ "正确", "错误" ] : options,
answer: answer,
type: type
};
});
}
WorkerJSPlus({
name: "资源库 新版",
match: location.pathname === "/icve-study/jobTest" || location.pathname === "/icve-study/coursePreview/jobTest" || location.pathname === "/icve-study/coursePreview/test",
root: ".subjectDet",
elements: {
question: "h5,.titleTest span:last",
options: ".optionList label",
$options: ".optionList input",
type: ".title,.titleTest .xvhao"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
UE$1.getEditor($option.attr("name")).setContent(answer);
}
}
});
WorkerJSPlus({
name: "资源库 WWW开头",
match: location.pathname === "/study/works/works.html" || location.pathname === "/study/exam/exam.html",
root: ".questions",
elements: {
question: ".preview_stem",
options: "li .preview_cont",
$options: "li input",
type: "input:hidden"
},
hook: () => {
JSONParseHook(o => {
if (location.pathname === "/study/works/works.html") {
if (o.paper) {
GLOBAL.json = parseIcve(o.paper.PaperQuestions);
uploadAnswer(GLOBAL.json);
}
} else if (location.pathname === "/study/exam/exam.html") {
if (o.array) {
GLOBAL.json = parseIcve(o.array.map(item => {
return item.Questions;
}).flat());
uploadAnswer(GLOBAL.json);
}
}
});
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
function get_element(id) {
for (let jsonElement of GLOBAL.json) {
if (jsonElement.id === id) {
return jsonElement;
}
}
}
const ele = get_element(obj.$item.find("input:hidden").val());
obj.question = ele.question;
obj.answer = ele.answerKey ? ele.answerKey : ele.answer;
obj.type = ele.type;
obj.options = ele.options;
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
UE$1.getEditor($option.attr("name")).setContent(answer);
}
}
});
WorkerJSPlus({
name: "智慧职教 作业/考试",
match: location.host.includes("zjy2.icve.com.cn"),
intv: () => {
return $(".subjectDet").length;
},
root: ".subjectDet",
elements: {
question: "h5,.titleT .htmlP",
options: ".optionList .el-radio__label,.el-checkbox__label",
$options: ".optionList input",
type: ".titleTwo,.xvhao"
},
hook: () => {
const parse = ques => {
return ques.map(i => {
const options = [];
const answer = [];
if (i.typeId === "3") {
answer.push(i.optionAnswer === "1" ? "正确" : "错误");
} else if (/[12]/.test(i.typeId)) {
options.push(...JSON.parse(i.dataJson).map(i => {
if (i.IsAnswer) {
answer.push(formatString(i.Content));
}
return formatString(i.Content);
}));
}
return {
options: options,
qid: i.id,
answer: answer
};
});
};
JSONParseHook(o => {
if (o.name && o.questions && o.totalScore) {
GLOBAL.json = parse(o.questions);
} else if (o.data && o.data.questions) {
GLOBAL.json = parse(o.data.questions);
}
});
},
ignore_click: $item => {
return $($item).parent().attr("class") === "is-checked";
},
wrap: obj => {
function findAnswer(id) {
for (let jsonElement of GLOBAL.json) {
if (jsonElement.qid === id) {
return jsonElement.answer;
}
}
}
obj.answer = findAnswer(obj.$item.attr("id"));
}
});
function parseYkt(problems) {
return problems.map(item => {
const question = formatString(item.Body);
const type = getQuestionType(item.TypeText);
const options = [];
const answer = [];
if (type <= 1) {
options.push(...item.Options.sort((a, b) => {
return a.key.charCodeAt(0) - b.key.charCodeAt(0);
}).map(item => {
return formatString(item.value);
}));
if (item.Answer) {
if (Array.isArray(item.Answer)) {
answer.push(...item.Answer);
} else {
answer.push(...item.Answer.split(""));
}
}
} else if (type === 3 && item.Answer && item.Answer.length === 1) {
answer.push(item.Answer[0].replace("true", "正确").replace("false", "错误"));
}
return {
answer: answer,
options: options,
type: type,
qid: item.problem_id,
question: question
};
});
}
function parsehnzkwText(problems) {
return problems.map(item => {
const type = item.flag === 1 ? 2 : item.flag === 0 ? 0 : item.flag === 4 ? 1 : item.flag === 3 ? 3 : undefined;
let answer = [];
let options = [];
if (type === 2) {
answer.push(item.answer);
return {
question: formatString(item.content),
options: options,
type: type,
answer: answer
};
} else if (type === 0) {
for (let subjectOption of item.optionss) {
const opt = formatString(subjectOption);
options.push(opt);
}
if (type === 1) {
item.answer.split("|").map(i => {
answer.push(options[i.toUpperCase().charCodeAt(0) - 65]);
});
} else {
answer.push(options[item.answer.toUpperCase().charCodeAt(0) - 65]);
}
return {
question: formatString(item.content),
options: options,
type: type,
answer: answer
};
} else if (type === 3) {
for (let subjectOption of item.selectOption) {
const opt = formatString(subjectOption);
options.push(opt);
}
answer.push(item.answer);
return {
question: formatString(item.content),
options: options,
type: type,
answer: answer
};
}
});
}
function parseDanWei(pro) {
return pro.map(i => {
const type = getQuestionType(i.ttop010);
const question = i.ttop011;
const options = [];
const answer = [];
if (type === 0 || type === 1 || type === 3) {
options.push(...i.ttop018.length > 0 ? i.ttop018.split("$$") : [ "正确", "错误" ]);
answer.push(...i.ttop022.split("").map(item => {
return options[item.charCodeAt(0) - 65];
}));
} else if (type === 2 || type === 4) {
answer.push(...i.ttop021.split("$$"));
}
return {
question: question,
type: type,
answer: answer,
options: options
};
}).filter(i => i);
}
function parseYxbyunExam(problems) {
return problems.map(item => {
const type = getQuestionType(item.bigName);
return item.paperTopicList.map(item => {
let answer = [];
let options = [];
if (type === 2) {
answer.push(item.answer);
return {
question: formatString(item.content),
options: options,
type: type,
answer: answer
};
} else if (type === 0 || type === 3 || type === 1) {
let answer = [];
let options = [];
for (let subjectOption of item.questionTopic.questionOptionList) {
const opt = formatString(subjectOption.questionContent);
options.push(opt);
}
if (type === 1) {
item.questionTopic.questionAnswer.split(",").map(i => {
answer.push(options[i.toUpperCase().charCodeAt(0) - 65]);
});
} else {
answer.push(options[item.questionTopic.questionAnswer.toUpperCase().charCodeAt(0) - 65]);
}
return {
question: formatString(item.questionTopic.questionTitle),
options: options,
type: type,
answer: answer
};
}
});
});
}
function parseYxbyunTest(problems) {
return problems.map(item => {
const type = getQuestionType(item.bigName);
return item.smallContent.map(item => {
let answer = [];
let options = [];
if (type === 2) {
answer.push(item.answer);
return {
question: formatString(item.content),
options: options,
type: type,
answer: answer
};
} else if (type === 0 || type === 3 || type === 1) {
let answer = [];
let options = [];
for (let subjectOption of item.question.optionList) {
const opt = formatString(subjectOption.questionContent);
options.push(opt);
}
if (type === 1) {
item.question.questionAnswer.split(",").map(i => {
answer.push(options[i.toUpperCase().charCodeAt(0) - 65]);
});
} else {
answer.push(options[item.question.questionAnswer.toUpperCase().charCodeAt(0) - 65]);
}
return {
question: formatString(item.question.questionTitle),
options: options,
type: type,
answer: answer
};
}
});
});
}
WorkerJSPlus({
name: "雨课堂旧版考试",
match: location.pathname.includes("/v/quiz/quiz_result"),
intv: () => {
return $("#cover").attr("style").includes("display: none;");
},
root: ".problem_item",
elements: {
question: ".notBullet:eq(0)",
options: ".notBullet:gt(0)",
$options: ".problembullet"
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
wrap: async obj => {
const $item = obj.$item;
const tmp = $item.find(".ptype").clone();
tmp.children().remove();
obj.type = getQuestionType(tmp.text());
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;
}
}
});
WorkerJSPlus({
name: "学堂在线",
match: location.host === "www.xuetangx.com" && location.pathname.includes("/exercise/"),
intv: () => {
return $(".answer").length;
},
root: ".content:eq(0)",
elements: {
question: ".question .fuwenben",
options: ".question .leftQuestion .leftradio > span:last-child",
$options: ".question .leftradio",
type: ".question .title"
},
ignore_click: $item => {
return $item.find(".radio_jqq").hasClass("active");
},
wrap: obj => {
if (obj.type === 3) {
obj.$options = $(".answerList .radio_jqq");
}
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
UE.getEditor($option.find("textarea")).setContent(answer);
}
},
finished: () => {
const $right = $(".tabbar").find(".right");
$right.click();
return !$right.hasClass("unselect");
}
});
WorkerJSPlus({
name: "雨课堂新版考试",
match: location.host.includes("yuketang.cn") && location.pathname.includes("/result/"),
hook: () => {
JSONParseHook(async o => {
if (o.data && o.data.problems && o.data.problems.length > 0) {
uploadAnswerToPlat(parseYkt(o.data.problems), 50);
}
});
}
});
WorkerJSPlus({
name: "雨课堂新版考试",
match: (location.host === "examination.xuetangx.com" || location.host === "changjiang-exam.yuketang.cn") && (location.pathname.includes("/exam/") || location.pathname.includes("/cover/")),
hook: () => {
JSONParseHook(async o => {
if (o.data && o.data.problems && o.data.problems.length > 0) {
GLOBAL.json = parseYkt(o.data.problems);
}
});
const intv = setInterval(() => {
try {
top.document.querySelector(".exam").__vue__.handleHangUpTip = function() {};
const querySelector = top.document.querySelector;
top.document.querySelector = function(...args) {
if (args[0] === "#model-id" || args[0].includes("hcSearcheModal")) return false;
return querySelector.call(this, ...args);
};
const getElementById = top.document.getElementById;
top.document.getElementById = function(...args) {
if (args[0] === "model-id" || args[0].includes("hcSearcheModal")) return false;
return getElementById.call(this, ...args);
};
clearInterval(intv);
} catch (e) {}
}, 100);
},
intv: () => {
return jQuery(".subject-item").length;
},
root: ".exam-main--body .subject-item",
elements: {
question: ".item-body h4,.item-body span:eq(0)",
options: ".item-body ul li",
$options: ".item-body ul label, .blank-item-dynamic, .edui-editor-iframeholder",
type: ".item-type"
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
wrap: obj => {
obj.options = obj.type === 3 ? [ "正确", "错误" ] : obj.options.map(i => {
return i.replace(/^[A-G]\s/, "");
});
try {
obj.qid = GLOBAL.json[GLOBAL.index - 1].qid;
obj.plat = 50;
} catch (e) {
console.log(e);
}
}
});
WorkerJSPlus({
name: "雨课堂新版作业,需要一个一个点下一题的",
match: location.pathname.includes("/v2/web/cloud/student/exercise/"),
hook: () => {
async function parseYkt(problems, font) {
const res = problems.map(i => {
const type = getQuestionType(i.content.TypeText);
const question = i.content.Body;
let options = [];
if (type <= 1) {
options = i.content.Options;
} else if (type === 3) {
options = i.content.Options.map(item => {
return item.key.replace("true", "正确").replace("false", "错误");
});
}
return {
qid: i.problem_id,
question: question,
type: type,
options: options,
user: i.user
};
}).filter(i => i);
for (const item of res) {
item.question = await getEncryptString(item.question, font);
const answerArray = [];
if (item.type <= 1) {
const optionsArray = [];
for (const itemElement of item.options) {
const opt = await getEncryptString(itemElement.value, font);
if (item.user && item.user.is_show_answer && item.user.answer.includes(itemElement.key)) {
answerArray.push(opt);
}
optionsArray.push(opt);
}
item.options = optionsArray;
} else if (item.type === 3) {
if (item.user && item.user.is_show_answer && item.user.answer.length === 1) {
answerArray.push(item.user.answer[0].replace("true", "正确").replace("false", "错误"));
}
}
delete item.user;
item.answer = answerArray;
}
return res;
}
JSONParseHook(async o => {
if (o.data && o.data.problems) {
GLOBAL.json = await parseYkt(o.data.problems, o.data.font);
uploadAnswerToPlat(GLOBAL.json, 50);
}
});
},
intv: () => {
return jQuery(".subject-item").length;
},
root: ".container-problem .subject-item",
elements: {
question: ".problem-body",
options: "label .radioText,.checkboxText",
$options: "ul input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: async obj => {
const index = jQuery(".item-type").text().match(/(\d+)\./)[1];
Object.assign(obj, GLOBAL.json[parseInt(index) - 1]);
obj.plat = 50;
},
finished: need_jump => {
if ($(".el-button--text:contains(下一题)").hasClass("is-disabled")) return false;
need_jump && setTimeout(() => {
$(".el-button--text:contains(下一题)").click();
}, GLOBAL.fillAnswerDelay);
return need_jump;
}
});
WorkerJSPlus({
name: "考试系统",
match: location.host === "gdrtvu.exam-cloud.cn" && location.pathname.includes("examRecordData"),
intv: () => {
return $("#examing-home-question").length;
},
root: ".question-container",
elements: {
question: ".question-body:first",
options: ".option .question-options",
$options: ".option input",
type: ".question-header .container"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
const split = obj.question.split(/[A-G]\./);
if (split.length === obj.options.length + 1) {
obj.question = split.shift();
obj.options = split;
}
if (obj.type === undefined || obj.type === null || isNaN(obj.type) || obj.type > 3) {
obj.type = defaultWorkTypeResolver(obj.$options);
console.log(obj.type);
}
if (document.querySelector(".question-container .right")) {
let current = 0;
const domItem = document.querySelectorAll(".item");
for (const dom of domItem) {
current++;
if (dom.className.includes("current-question")) {
break;
}
}
obj.question = `【第${current}小题】` + filterImg(jQuery(".right .question-view .question-body")) + obj.question;
}
},
finished: async need_jump => {
await sleep(500);
if ($(".next a").length === 0) {
return false;
}
window.parent.document.querySelector(".next a").click();
return true;
}
});
WorkerJSPlus({
name: "云班课",
match: location.pathname === "/web/index.php" && location.href.includes("m=reply"),
root: ".topic-item",
elements: {
question: ".t-con .t-subject",
options: ".t-option label .option-content",
$options: ".el-radio__input,.el-checkbox__input",
type: ".t-info .t-type"
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
wrap: obj => {
if (obj.type === "A1A2题") {
obj.type = 1;
}
obj.question = obj.question.replace(/
/gi, "");
obj.options = obj.options.map(i => {
return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim();
});
}
});
WorkerJSPlus({
name: "中国地质大学",
match: location.pathname.includes("/Exam/OnlineExamV2/"),
root: ".stViewItem",
elements: {
question: ".stViewHead div",
options: ".stViewCont .stViewOption a",
$options: ".stViewCont .stViewOption a,input"
},
intv: () => {
return $(".ExamTime").length;
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().parent().prev().find(".E_E_L_I_C_R_C_T_SubType").text());
obj.question = obj.question.replace(/\(\d+分\)/, "");
obj.options = obj.options.map(i => {
return i.replace(/\([A-Za-z]\)/, "").trim();
});
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "单位",
match: (location.host === "61.183.163.9:8089" || location.host === "zjpt.nnjjtgs.com:8081") && (location.href.includes("ksnr") || location.href.includes("lxnr")),
hook: () => {
JSONParseHook(o => {
if (o.topicList && o.topicList.length > 0) {
GLOBAL.json = parseDanWei(o.topicList);
uploadAnswer(GLOBAL.json);
}
});
},
root: ".tm",
elements: {
question: ".tmnrbj span:last-child",
options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label",
$options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label,.van-field__control",
type: ".tmnrbj span"
},
intv: () => {
return $(".ExamTime").length || document.getElementById("pup-b");
},
wrap: obj => {
obj.answer = GLOBAL.json[jQuery(".tmnrbj span:last-child").text().match(/^(\d+)、/)[1] - 1].answer;
},
finished: () => {
jQuery(".xyt").click();
return true;
}
});
WorkerJSPlus({
name: "小鹅通",
match: location.pathname.includes("/evaluation_wechat/examination/detail/"),
root: ".question-title,.title__text",
elements: {
question: "#detail_div",
options: "label .image-text-box p",
$options: "label,.simulation_inp"
},
ignore_click: ($item, type) => {
if (type === 0) {
return $item.html().includes("single-exam-radio-active");
} else if (type === 1) {
return $item.html().includes("check-i-active");
}
},
wrap: obj => {
const $item = obj.$item;
obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank");
obj.type = getQuestionType($item.next().text());
if (obj.type === 2) {
obj.$options = $item.parent().parent();
}
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
} else {
obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) {
return formatString(filterImg(val));
});
}
},
fill: (type, answer, $option) => {
if (type === 2) {
const vue = $option.get(0).__vue__;
vue.content[0] = answer;
vue.emitAnswer();
$option.find(".simulation_inp").text(answer);
}
}
});
WorkerJSPlus({
name: "小饿通H5",
match: location.host.includes("h5.xiaoeknow") || location.href.includes("/exam/h5_evaluation/"),
root: ".practice-detail__body",
elements: {
question: ".question-wrap__title #detail_div",
options: ".question-option #detail_div",
$options: ".question-option #detail_div",
type: ".question-wrap__title-tag"
},
wrap: obj => {
const $item = obj.$item;
obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank");
obj.type = TYPE[$item.next().text().replace(/\s+/, "").replace("(", "").replace(")", "")];
if (obj.type === 2) {
obj.$options = $item.parent().parent();
}
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
} else {
obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) {
return formatString(filterImg(val));
});
}
},
finished: () => {
$(".practice-detail__bottom-item:last-child").click();
return $(".next").text() === "下一题";
}
});
WorkerJSPlus({
name: "人卫慕课测验",
match: location.pathname.includes("/memberFront/paper.zhtml"),
intv: () => {
return $("#question_").attr("style").length === 0;
},
root: ".quesinfo",
elements: {
question: "dl dt",
options: "dd label",
$options: "dd input"
},
wrap: obj => {
if (obj.$options.length === 2) {
obj.type = 3;
obj.options = [ "正确", "错误" ];
} else {
obj.type = 0;
}
}
});
WorkerJSPlus({
name: "青书学堂考试",
match: location.host.includes("qingshuxuetang") && (location.pathname.includes("/Student/MakeupExamPaper") || location.pathname.includes("Student/ExamPaper")),
intv: () => {
return $(".paper-container .question-detail-container").length;
},
root: ".paper-container .question-detail-container",
elements: {
question: ".question-detail-description .detail-description-content",
options: ".question-detail-options label .option-description",
$options: ".question-detail-options label input",
type: ".question-detail-type .question-detail-type-desc"
},
wrap: obj => {
obj.qid = obj.$item.attr("id");
obj.options = obj.options.map(i => {
return i.replace(/\([A-Za-z]\)/, "").trim();
});
if (obj.type === 5 || obj.type === 4 || obj.type === 6) {
obj.$options = obj.$item.find("div[id^=cke_editor]");
}
},
fill: (type, answer, $option) => {
if (type === 4 || type === 5 || type === 6) {
CKEDITOR.instances[$option.attr("id").replace("cke_", "")].setData(answer);
}
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "青书学堂测验",
match: location.host.includes("qingshuxuetang") && (location.pathname.includes("/Student/ExercisePaper") || location.pathname.includes("/Student/SimulationExercise")) || location.host === "quiz.qingshuxuetang.com" && location.pathname.includes("/Student/Quiz/Detail"),
intv: () => {
return $(".question-detail-container").length;
},
root: ".question-detail-container",
elements: {
question: ".question-detail-description span",
options: ".question-detail-options label .option-description",
$options: ".question-detail-options div input,.question-detail-solution-textarea",
type: ".question-detail-type"
},
wrap: obj => {
obj.qid = obj.$item.attr("id");
obj.options = obj.options.map(i => {
return i.replace(/\([A-Za-z]\)/, "").trim();
});
},
ignore_click: ($item, type) => {
if (type === 1) {
return $item.prop("checked");
}
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$option.parents().find(".question-controller-wrapper .next").click();
}
}
});
WorkerJSPlus({
name: "优学院测验",
match: location.pathname === "/learnCourse/learnCourse.html",
intv: () => {
return $(".question-setting-panel").length;
},
root: ".split-screen-wrapper",
elements: {
question: ".question-title-scroller .question-title-html",
options: ".choice-list .content-wrapper .text",
$options: ".choice-list .checkbox ,.question-body-wrapper .choice-btn",
type: ".question-title-scroller .question-type-tag"
},
wrap: obj => {
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.hasClass("selected");
}
});
WorkerJSPlus({
name: "优学院作业",
match: location.pathname === "/quiz/pc.html",
intv: () => {
return $(".questions").length;
},
root: ".question-item",
elements: {
question: ".question-title",
options: "ul label .choice-title",
$options: "ul label input",
type: ".title"
},
wrap: obj => {
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "优学院考试",
match: location.host === "utest.ulearning.cn" && location.pathname === "/",
intv: () => {
return $(".section-area").length;
},
root: ".question-area .question-item",
elements: {
question: ".base-question .title .rich-text",
options: ".choice-list label .rich-text",
$options: ".choice-list label, .iconfont",
type: ".base-question .title .tip"
},
wrap: obj => {
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
finished: () => {
if ($(".next-part:contains(下个部分)").length) {
$(".next-part").click();
return true;
} else {
return false;
}
}
});
WorkerJSPlus({
name: "优学院作业",
match: location.pathname === "/umooc/learner/homework.do",
intv: () => {
return $(".multiple-choices").length;
},
root: ".multiple-choices,.judge",
elements: {
question: "h5 .position-rltv span:last-child",
options: "ul label span:last-child",
$options: "ul label input,.radios .radio input",
type: "h5 .typeName"
},
wrap: obj => {
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.prev().hasClass("checkbox-checked");
}
});
WorkerJSPlus({
name: "万学",
match: location.pathname.includes("/sls/N2014_StudyController/next"),
root: ".question",
elements: {
question: "tr .nm2",
options: ".grey td p",
$options: ".option li label",
type: "tr .nm2"
},
wrap: obj => {
obj.question = obj.question.parent().find("td p").text();
}
});
WorkerJSPlus({
name: "wenJuanAutoFill",
match: location.host.includes("wenjuan.com") && location.pathname === "/s/",
root: "questionContent",
elements: {
question: ".title",
options: ".icheckbox_div .option_label",
$options: ".icheckbox_div label",
type: ".question_num"
},
ignore_click: $item => {
return $item.attr("class").includes("checked");
}
});
WorkerJSPlus({
name: "学起(考试)",
match: location.pathname.includes("/oxer/page/ots/examIndex.html"),
intv: () => {
return $(".tika_topline").length;
},
root: ".queItemClass",
elements: {
question: "dt .din:eq(1)",
options: ".clearfix div",
$options: ".clearfix .xuan,input"
},
ignore_click: $item => {
return $item.parent().hasClass("cur");
},
wrap: obj => {
obj.plat = 66;
obj.qid = obj.$item.attr("id");
obj.type = getQuestionType(obj.$item.parent().find("div .fb:eq(0)").text());
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
}
}
});
WorkerJSPlus({
name: "学起(测试)",
match: location.pathname.includes("/oxer/page/ots/UniversityStart.html"),
intv: () => {
return $(".uniQueList").length;
},
root: ".uniQueItem",
elements: {
question: ".QueStem",
options: "ul li span",
$options: "ul li"
},
ignore_click: $item => {
return $item.parent().hasClass("lichecked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parents(".uniQueList").find(".fir").text());
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
}
console.log(obj);
}
});
WorkerJSPlus({
name: "易班考试",
match: location.host === "exam.yooc.me" && location.pathname.includes("/group"),
intv: () => {
return $(".jsx-3527395752").length;
},
root: "main:last",
elements: {
question: "h3 div",
options: ".mb ul li .flex-auto",
$options: ".mb ul li",
type: ".mb-s"
},
ignore_click: $item => {
return $item.hasClass("_c");
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$(".exam-input").val("answer");
}
},
finished: need_jump => {
if ($('.round:contains("下一题")').hasClass("ghost")) return false;
$('.round:contains("下一题")').click();
return true;
}
});
WorkerJSPlus({
name: "英华学堂",
match: () => {
const pathMatch = location.pathname.includes("/user/work") || location.pathname.includes("/user/exam");
const matchHostArr = [ "mooc.kdcnu.com", "mooc.yncjxy.com", "mooc.cdcas.com", "mooc.cqcst.edu.cn", "mooc.kmcc.edu.cn", "mooc.wuhues.com" ];
return pathMatch && matchHostArr.includes(location.host);
},
intv: () => {
return $("#stateName").text().trim() === "进行中";
},
root: ".courseexamcon-main",
elements: {
question: ".name",
options: ".list li .txt",
$options: ".list li .exam-inp",
type: ".type"
},
ignore_click: $item => {
return $item.prop("checked");
},
fill: (type, answer, $option) => {},
finished: auto_jump => {
if ($(".next_exam").eq(3).prop("style")[0] == "display") return false;
$(".next_exam").click();
}
});
WorkerJSPlus({
name: "厦门在线教育测验",
match: location.pathname.includes("/nec/student/exam/exam-paper!test"),
root: "#paper_form > div:nth-child(4) > table:nth-child(1) > tbody:nth-child(2)>tr:even",
elements: {
question: "td:eq(1)",
options: ".optionUl label .el-radio__label,.el-checkbox__label",
$options: ".optionUl label"
},
wrap: obj => {
obj.options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => {
return $(y).find("td:eq(1)").text();
}).toArray();
obj.$options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => {
return $(y).find("input");
});
obj.type = 0;
}
});
WorkerJSPlus({
name: "金牌学堂",
match: location.host === "www.goldgame.com.cn" && location.href.includes("/TestPage"),
intv: () => {
return $(".tab-btn-box li").length;
},
root: ".test-type-box ul .white-bg",
elements: {
question: ".position-relative h3",
options: ".test-option label p:last-child",
$options: ".test-option label input"
},
wrap: obj => {
obj.question = obj.question.replace(/题目\d+\:/, "").trim().replace(/^\d+./, "");
obj.type = getQuestionType(obj.$item.parent().parent().find(".test-type-tips").text());
if (obj.$options.length > 2 && obj.$options.eq(0).hasClass("radiobox")) {
obj.type = 0;
}
},
fillFinish: data => {
$(".answer-sheet li").eq(GLOBAL.index).click();
}
});
WorkerJSPlus({
name: "青岛开放大学",
match: location.pathname.includes("/pages/exam/exam.html"),
intv: () => {
return $(".exam-content-block .exam-content-topic").length;
},
root: ".exam-content-block .exam-content-topic",
elements: {
question: ".exam-topic-title",
options: ".exam-topic-answer .layui-unselect span",
$options: ".exam-topic-answer .layui-unselect"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".exam-content-title .exam-content-num").text());
}
});
WorkerJSPlus({
name: "点墨考试",
match: location.pathname.includes("/Exam/StartExam"),
root: "#question div div:first",
elements: {
question: "div:first",
options: "div:first ~ div",
$options: "div:first ~ div input"
},
wrap: obj => {
obj.type = getQuestionType($(".alert #groupNameSpan").text());
},
finished: () => {
$(".w-100 .btn-light:eq(1)").click();
return true;
}
});
WorkerJSPlus({
name: "点墨测验",
match: location.pathname.includes("/Course/TestPaper"),
root: ".question",
elements: {
question: " div div:first div:first",
options: " div div:first div:first ~ div",
$options: " div div:first div:first ~ div input"
},
wrap: obj => {
obj.type = getQuestionType($("h3").text());
obj.question = obj.question.replace(/^\d+\./, "");
}
});
WorkerJSPlus({
name: "警官学院",
match: location.pathname.includes("/bsmytest/startTi.do"),
root: ".wrapper > div",
elements: {
question: ".dx",
options: "p",
$options: "p input"
},
wrap: obj => {
if ($(".wrapper .cl").length > 0) {
obj.question = obj.$item.text().replace(/[0-9]、/, "").replace(/\(.*?\)/g, "").trim().split("$")[0].replace(/\(.*?\)/g, "").trim();
} else {
obj.question = obj.question.replace(/[0-9]、/, "").replace(/\(.*?\)/g, "").trim();
}
obj.type = getQuestionType(obj.$item.parent().find("h2").text());
obj.options = obj.options.map(item => {
return item.replace(/[A-Za-z][\:]/, "").replace(/[A-Za-z][\:,\:]/, "").replace(/\;/, "").trim();
});
}
});
WorkerJSPlus({
name: "exam2_euibe_com_exam",
match: location.hostname === "exam2.euibe.com" && location.pathname === "/KaoShi/ShiTiYe.aspx",
root: ".question",
elements: {
question: ".wenti",
options: "li label span",
$options: "li label"
},
wrap: obj => {
obj.type = getQuestionType($(".question_head").text());
},
finished: need_jump => {
$(".paginationjs-next").click();
return true;
}
});
WorkerJSPlus({
name: "lzwyedu_jijiaool_com_exam",
match: () => {
const pathMatch = location.pathname.includes("/learnspace/course/test/") || location.pathname.includes("/Student/ExamManage/CourseOnlineExamination");
const matchHostArr = [ "lzwyedu.jijiaool.com", "cgjx.jsnu.edu.cn", "learn-cs.icve.com.cn", "nwnu.jijiaool.com", "lut.jijiaool.com", "learn.courshare.cn", "cj1027-kfkc.webtrn.cn" ];
return pathMatch && matchHostArr.includes(location.host);
},
root: ".test_item",
elements: {
question: ".test_item_tit",
options: ".test_item_theme label .zdh_op_con",
$options: "label input"
},
wrap: obj => {
obj.question = obj.question.replace(/该题未做$/, "").replace(/^\d+\./, "").replace(/^\d+、/, "").replace(/[((](\d+\s?(\.\d+)?分)[))]$/, "").replace(/^((\d+.(\s+)?)?)[\[((【](.*?)[】))\]]/, "").trim();
obj.type = getQuestionType(obj.$item.prevAll(".test_item_type:first").text());
if (obj.type === 3) {
obj.options = [ "对", "错" ];
}
}
});
WorkerJSPlus({
name: "zzx_ouchn_edu_cn_exam",
match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"),
root: ".subject",
elements: {
question: ".question span",
options: ".answer>span>p:first-child",
$options: ".answer>span>p:first-child"
},
wrap: obj => {
if (obj.$options.length > 1) {
obj.type = 0;
}
}
});
WorkerJSPlus({
name: "zzx_ouchn_edu_cn_exam",
match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"),
root: ".subject",
elements: {
question: ".question span",
options: ".answer>span>p:first-child",
$options: ".answer>span>p:first-child"
},
wrap: obj => {
if (obj.$options.length > 1) {
obj.type = 0;
}
}
});
WorkerJSPlus({
name: "havust_hnscen_cn_exam",
match: location.hostname === "havust.hnscen.cn" && location.pathname.includes("/stuExam/examing/"),
root: ".main .mt_2 > div",
elements: {
question: ".flex_row+div",
options: ".flex_row+div+div .el-radio__label,.el-checkbox__label",
$options: ".flex_row+div+div .el-radio__label,.el-checkbox__label",
type: ".flex_row .mr_2"
}
});
WorkerJSPlus({
name: "www_zygbxxpt_com_exam",
match: location.hostname === "www.zygbxxpt.com" && location.pathname.includes("/exam"),
root: ".Body",
elements: {
question: ".QName",
options: ".QuestinXuanXiang p:parent",
$options: ".QuestinXuanXiang p:parent",
type: ".QName span"
},
wrap: obj => {
obj.question = obj.question.replace(/\([^\)]*\)/g, "").replace(/\【.*?\】/g, "");
obj.options = obj.options.map(item => {
return item.split(">").pop().trim();
});
}
});
WorkerJSPlus({
name: "xuexi_jsou_cn_work",
match: location.hostname === "xuexi.jsou.cn" && location.pathname.includes("/jxpt-web/student/newHomework/showHomeworkByStatus"),
root: ".insert",
elements: {
question: ".window-title",
options: ".questionId-option .option-title div[style^=display]",
$options: ".questionId-option .option-title .numberCover"
},
wrap: obj => {
obj.type = {
1: 0,
2: 1,
7: 3
}[obj.$item.find(".question-type").val()];
if (obj.options.length == 2) {
obj.type = 3;
}
}
});
WorkerJSPlus({
name: "czvtc_cjEdu_com_exam",
match: () => {
const pathMatch = location.pathname.includes("/ExamInfo") || location.pathname.includes("/Examination");
const matchHostArr = location.host.includes("cj-edu.com");
return pathMatch && matchHostArr;
},
intv: () => {
return $(".el-container .all_subject>.el-row").length;
},
root: ".el-container .all_subject>.el-row",
elements: {
question: ".stem div:last-child",
options: ".el-radio-group .el-radio__label,.el-checkbox-group .el-checkbox__label",
$options: ".el-radio-group .el-radio__original,.el-checkbox-group .el-checkbox__original"
},
wrap: obj => {
if (obj.$options.length < 3 && obj.$options.eq(0).attr("type") === "radio") {
obj.type = 3;
} else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") {
obj.type = 0;
} else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "checkbox") {
obj.type = 1;
}
}
});
WorkerJSPlus({
name: "learning_mhtall_com_exam",
match: location.host.includes("learning.mhtall.com") && location.pathname.includes("/rest/course/exercise/item"),
root: "#div_item",
elements: {
question: ".item_title",
options: ".opt div label",
$options: ".opt div input:not(.button_short)",
type: "h4"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
if (obj.type === 0 || obj.type === 3) {
obj.answer = $(".div_answer").text().match(/[a-zA-Z]/).map(i => {
return obj.options[i.charCodeAt(0) - 65];
});
} else if (obj.type === 2) {
obj.answer = $(".div_answer").text().replace("参考答案:", "").split(",");
}
},
fill: (type, answer, $option) => {
if (type === 2 || type === 4) {
$option.val(answer);
$(".DIV_TYPE_BLANK .button_short").click();
}
},
fillFinish: () => {
if ($(".opt+div+div input:eq(1)").val() === "下一题") {
$(".opt+div+div input:eq(1)").click();
} else {
$(".button_short:eq(2)").click();
}
}
});
WorkerJSPlus({
name: "168网校(测验)",
match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/learningCenter/details/"),
intv: () => {
return $(".ret-answer").length === 0 && $(".info-container").length;
},
root: ".question-item-container",
elements: {
question: ".title-content",
options: ".options .opt-content",
$options: ".options label",
type: ".top .type"
}
});
WorkerJSPlus({
name: "168网校(考试)",
match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/examination/answer"),
intv: () => {
return $(".Answer-area").length;
},
root: ".Answer-area",
elements: {
question: ".listTit",
options: ".el-radio__label span:last-child,.el-checkbox__label span:last-child",
$options: ".el-radio__input,.el-checkbox__input input,.ql-editor p"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
if (obj.options.length === 0) {
obj.type = 2;
}
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 2 || type === 4) {
console.log(answer);
document.querySelector(".ql-editor p").textContent = answer;
}
},
finished: () => {
if ($(".ctrl .el-button:contains(下一题)").length != 0) {
$(".ctrl .el-button:contains(下一题)").click();
return true;
} else if ($(".ctrl .el-button:contains(上一题)").length && $(".ctrl button").length === 1) {
return false;
}
}
});
WorkerJSPlus({
name: "法宣在线",
match: location.host.includes("faxuanyun.com") && location.pathname.includes("/bps/examination"),
intv: () => {
return $("#timucontent").length;
},
root: "#timucontent",
elements: {
question: "h2",
options: "ul li",
$options: "ul input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
if ($(".layui-layer-content").length) {
iframeMsg("tip", {
type: "stop",
tip: "答题暂停,请自行通过验证"
});
$("#lastButton").click();
GLOBAL.stop = true;
return false;
}
},
finished: need_jump => {
if ($("#nextButton").length) {
$("#nextButton").click();
return true;
} else {
return false;
}
}
});
WorkerJSPlus({
name: "山财培训网 (补考)",
match: location.host.includes("training.sdufe.edu.cn") && location.pathname.includes("/Exam/OnlineExam/"),
intv: () => {
return $(".exam_r_m").length;
},
root: ".exam_r_m",
elements: {
question: ".bt",
options: ".btm",
$options: ".btm input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
obj.options = $("br").parent().text().split(/[A-Z]\./).slice(1).map(item => {
return item.trim();
});
if (obj.type === 3) {
obj.answer = $("#answerDiv").text().replace("正确答案:", "").split();
} else {
obj.answer = $("#answerDiv").text().match(/[A-Z]/g).map(item => {
return obj.options[item.charCodeAt(0) - 65];
});
}
},
finished: () => {
document.querySelector("#next").click();
if (document.querySelector("#noAskCount").textContent == "0") {
return false;
}
return true;
}
});
WorkerJSPlus({
name: "和学在线",
match: location.host.includes("studentjxjyzx") || location.host.includes("student.hexuezx") || location.host.includes("student.jxjyzx"),
intv: () => {
return $(".el-card__body").length;
},
root: ".el-card__body",
elements: {
question: ".stem",
options: ".el-radio__label,.el-checkbox__label span",
$options: ".el-radio__input,.el-checkbox__input input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
console.log(obj);
}
});
WorkerJSPlus({
name: "高教在线",
match: location.host === "www.cqooc.com" && (location.href.includes("/learn/mooc/exam/do") || location.href.includes("/learn/mooc/testing/do")),
intv: () => {
return $("#test-form").length;
},
root: "#test-form .cat",
elements: {
question: ".stem",
options: ".option label",
$options: ".option input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/\(\d+分\)\d+\.\d+/, "");
console.log(obj);
}
});
WorkerJSPlus({
name: "考试平台",
match: location.pathname.includes("/kaoshi_qnzzxy/kaoshi.html"),
intv: () => {
return $(".form-group").length;
},
root: ".form-group",
elements: {
question: ".row-fluid",
options: ".option",
$options: ".option input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find("div:first").text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\:\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
}
});
WorkerJSPlus({
name: "柠檬文才(考试)",
match: () => {
const pathMatch = location.pathname.includes("/separation/exam/");
const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net", "www.wencaischool.net" ];
return pathMatch && matchHostArr.includes(location.host);
},
intv: () => {
return $("#paperExam").css("display") != "none";
},
root: ".paperWrapper .tmList",
elements: {
question: ".tmTitleTxt",
options: ".ansbox .opCont",
$options: ".ansbox input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
if (obj.options.length === 0) {
obj.type = 2;
}
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "柠檬文才(作业)",
match: () => {
const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net" ];
return (location.pathname.includes("/hblearning/exam/") || location.pathname.includes("/xbsflearning/exam/") || location.pathname.includes("/openlearning/exam/") || location.pathname.includes("/jxlearning/exam/") || location.pathname.includes("/shandonglearning/exam")) && matchHostArr.includes(location.host);
},
intv: () => {
return $("#paperExam").css("display") !== "none";
},
root: "#_block_content_exam #tblDataList>tbody>tr",
elements: {
question: "tbody:first>tr>td:last table",
options: ".ansbox .opCont",
$options: ".ansbox input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").text();
obj.options = [];
$("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("label").map((i, y) => {
obj.options.push($(y).text());
});
obj.$options = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("input").map((i, y) => {
return y;
});
obj.type = 0;
if (obj.options.length == 2) {
obj.type = 3;
} else if (obj.$options.eq(0).attr("type") != "radio") {
obj.type = 1;
}
console.log(obj);
}
});
WorkerJSPlus({
name: "福建师范",
match: location.host === "neo.fjnu.cn" && location.pathname.includes("/resource/index"),
intv: () => {
return $(".content").length && !$(".answer-content").length;
},
root: ".content",
elements: {
question: ".title",
options: "label .el-radio__label,.el-checkbox__label",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "优课学堂",
match: location.host.includes("youkexuetang.cn") && location.pathname.includes("/student/"),
intv: () => {
return $(".paperItemBox").length;
},
root: ".paperItemBox",
elements: {
question: ".stem",
options: ".el-radio__label,.el-checkbox__label",
$options: ".el-radio__input,.el-checkbox__input input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
console.log(obj);
}
});
WorkerJSPlus({
name: "亿学宝云考试",
match: location.host.includes("yxbyun.com") && (location.hash.includes("/finalExam") || location.hash.includes("/finalTask")),
intv: () => {
return $(".time_header").length || $(".pager_wrap").length;
},
hook: () => {
JSONParseHook(o => {
if (o?.data?.paper?.paperStructureList) {
GLOBAL.json = parseYxbyunExam(o.data.paper.paperStructureList).reduce((acc, cur) => {
return acc.concat(cur);
}, []);
console.log(GLOBAL.json);
}
});
},
root: ".test",
elements: {
question: ".type",
options: ".el-radio-group,.el-checkbox-group label",
$options: ".answer div",
type: ".el-tag"
},
wrap: obj => {
Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "亿学宝云",
match: location.host.includes("yxbyun.com") && location.hash.includes("/testPaper"),
intv: () => {
return $(".time_header").length || $(".pager_wrap").length;
},
hook: () => {
JSONParseHook(o => {
if (o.data && o.data.bigContent) {
GLOBAL.json = parseYxbyunTest(o.data.bigContent).reduce((acc, cur) => {
return acc.concat(cur);
}, []);
console.log(GLOBAL.json);
}
});
},
root: ".test",
elements: {
question: ".type",
options: ".el-radio-group,.el-checkbox-group label",
$options: ".el-radio__input,.el-checkbox__input input",
type: ".el-tag"
},
wrap: obj => {
Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "考试星(单题)",
match: Boolean(location.host === "exam.kaoshixing.com" && location.pathname.includes("/exam/exam_start")),
intv: () => {
return $("#nextQuestions").length;
},
root: ".questions .questions-content",
elements: {
question: ".question-name",
options: ".answers label .words",
$options: ".answers label"
},
ignore_click: $item => {
return $item.parent().find("input").prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
console.log(obj);
},
finished: () => {
if ($("#nextQuestions:contains(下一题)").length && $("#nextQuestions").css("display") !== "none") {
$("#nextQuestions:contains(下一题)").click();
return true;
} else {
return false;
}
}
});
WorkerJSPlus({
name: "易考云",
match: location.host === "exam.beeouc.com" && location.pathname.includes("/client"),
intv: () => {
return $(".question-body").length;
},
root: ".question-body",
elements: {
question: ".question-stem",
options: ".question-option label",
$options: ".question-option input",
type: ".question-type"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
},
finished: () => {
if ($(".question-footer button:contains(下一题)").length) {
$(".question-footer button:contains(下一题)").click();
return true;
} else {
return false;
}
}
});
WorkerJSPlus({
name: "伊犁师范成人教育",
match: location.pathname.includes("/learn/NewExam") || location.pathname.includes("//GeneralTestPaper/Testing/") || location.pathname.includes("//GeneralTestPaper/SNTesting"),
intv: () => {
return $(".topic").length;
},
root: ".topic",
elements: {
question: ".qsctt",
options: ".xuan li",
$options: ".choice input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.options = obj.options.map(i => {
return i.replace(/^[A-Z] \. /, "");
});
if (obj.$options.length == 2) {
obj.options = [ "正确", "错误" ];
obj.type = 3;
}
}
});
WorkerJSPlus({
name: "绎通云课堂 (作业)",
match: location.host.includes("ytccr.com") && (location.hash.includes("#/learning-work") || location.hash.includes("#/learning-details")),
intv: () => {
return $(".left-question").length;
},
root: ".border-item",
elements: {
question: ".qa-title",
options: "label .opt-title-cnt",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "重庆大学网络教育学院 (作业)",
match: location.host === "exercise.5any.com" && location.pathname.includes("/Exercise/WebUI/Test/Answer"),
intv: () => {
return $(".examtime-content").length;
},
root: ".subject .font-16",
elements: {
question: ".stem .richtextcontent",
options: ".option .richtextcontent",
$options: ".option label input"
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "毕节幼儿师范",
match: location.host === "px.gzbjyzjxjy.cn" || location.host === "px.ggcjxjy.cn" && location.pathname.includes("/exam/shiti/dopapers"),
intv: () => {
return $(".panel-body").length;
},
root: ".panel-body>div",
elements: {
question: ".testpaper-question-stem",
options: ".testpaper-question-choices li",
$options: ".testpaper-question-footer input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "贵州继续教育",
match: location.host === "www.gzjxjy.gzsrs.cn" && location.pathname.includes("/personback/"),
intv: () => {
return $(".question-title").length;
},
root: ".question-title",
elements: {
question: ".show-text",
options: "label",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "和学自考",
match: location.host === "zkpt.qdu.edu.cn" && location.pathname.includes("/examStu/exam/examPaper"),
intv: () => {
return $(".ant-spin-container").length;
},
root: ".ant-row",
elements: {
options: "label",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.$item.parent().parent().prev().text();
console.log(obj);
}
});
WorkerJSPlus({
name: "专技天下",
match: location.host.includes("zgzjzj.com") && location.pathname.includes("/examination/perpar.html"),
intv: () => {
return $(".question_index").length;
},
root: ".question_index",
elements: {
question: "p",
options: ".options li p,li>span:last-child",
$options: ".options li",
type: "p span"
},
ignore_click: $item => {
return $item.hasClass("active");
}
});
WorkerJSPlus({
name: "睿学补考",
match: location.href.includes("exam-app-exam-paper") && location.host.includes("ks.hustsnde.com"),
intv: () => {
return $("#paper").length;
},
root: "#paper .content-box",
elements: {
question: "ul li:eq(0) .desc",
options: "ul li:eq(1)",
$options: "ul label input",
type: ".title"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
const options = obj.options[0].trim().split(/\[[A-Z]:?\]/).splice(1).map(i => {
return i.trim();
}).filter(i => i);
if (options.length === 0) {
obj.options = obj.options[0].trim().split(/\(?[A-Z\.?]\)?/).splice(1).map(i => {
return i.trim();
}).filter(i => i);
} else {
obj.options = options;
}
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
}
}
});
WorkerJSPlus({
name: "云上河开",
match: location.host === "jx.open.ha.cn" && location.pathname.includes("/jxpt-web/student/homework/showHomeworkByStatus"),
intv: () => {
return $("#shiti-content").length;
},
root: ".insert",
elements: {
question: ".window-title",
options: "ul li div:last-child",
$options: "ul li .numberCover"
},
ignore_click: $item => {
return $item.parent().hasClass("answer-title");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parents(".layui-colla-item").find(".titleType").text());
}
});
WorkerJSPlus({
name: "ycjy.lut.edu.cn",
match: location.host === "ycjy.lut.edu.cn" && location.pathname.includes("/learnspace/course/test/coursewareTest_intoTestPage.action"),
intv: () => {
return $(".bank_cont").length;
},
root: ".test_item",
elements: {
options: "label",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".test_item_type").text());
obj.question = obj.$item.find(".test_item_tit").contents()[0].nodeValue.trim();
}
});
WorkerJSPlus({
name: "exam.euibe.com",
match: location.host === "exam.euibe.com" && location.pathname.includes("/KaoShi/ShiTiYe.aspx"),
intv: () => {
return $(".question_list").length;
},
root: ".question",
elements: {
question: ".wenti .stem",
options: "label span",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parents(".question_list").find(".question_head").text());
},
finished: need_jump => {
if ($(".paginationjs-next").hasClass("disabled")) {
return false;
}
$(".paginationjs-next").click();
return true;
}
});
WorkerJSPlus({
name: "学晖教育",
match: location.host === "xhjy.ldzxjy.com" && location.pathname.includes("tikuUserBatch/keepTopic"),
intv: () => {
return $(".radio").length;
},
root: ".radio",
elements: {
question: ".issueTitle",
options: "ul li span",
$options: "ul li",
type: ".issueTypes"
},
ignore_click: $item => {
return $item.prop("checked");
},
finished: need_jump => {
if ($(".next").text().includes("交卷")) {
return false;
}
$(".next").click();
return true;
}
});
WorkerJSPlus({
name: "东财在线",
match: location.host === "classroom.edufe.com.cn" && (location.pathname.includes("/PracticePaper") || location.pathname.includes("/HomeWorkPaper")),
intv: () => {
return $(".TK-main").length;
},
root: ".CBTPaperMain-trunk",
elements: {
question: ".CBTPaperMain-divInline",
options: "ul li label",
$options: "ul li label"
},
ignore_click: $item => {
return $item.hasClass("_CheckBox_checked");
}
});
WorkerJSPlus({
name: "北华大学在线教育",
match: () => {
const pathnameArr = [ "cj1026-kfkc.webtrn.cn", "beihua.peishenjy.com" ];
return pathnameArr.includes(location.pathname) && location.pathname.includes("/Learning/CourseOnlineExamination") || location.pathname.includes("/learnspace/course/test");
},
intv: () => {
return $(".s_mi").length;
},
root: ".test_item",
elements: {
question: ".test_item_tit",
options: " label",
$options: "label input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "上海立达学院",
match: location.host === "kkzxsx.lidapoly.edu.cn" && location.pathname.includes("/exam/"),
intv: () => {
return $(".exam-question").length;
},
root: ".main .item",
elements: {
question: ".text",
options: ".options label .el-radio__label,.el-checkbox__label",
$options: ".options label"
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".text").text());
console.log(obj);
}
});
WorkerJSPlus({
name: "石家庄科技继续教育",
match: location.host.includes("kc.jxjypt.cn") && location.pathname.includes("/paper/start"),
intv: () => {
return $(".sub-content").length;
},
root: ".sub-content",
elements: {
question: ".sub-dotitle",
options: ".sub-answer dd",
$options: ".sub-answer dd,.mater-respond textarea",
type: ".sub-dotitle i"
},
ignore_click: $item => {
return $item.hasClass("cho-this");
},
wrap: obj => {
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 4) {
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "石家庄理工职业学院",
match: location.host.includes("edu.tianzerencai.com") && location.pathname.includes("/examinationDetail"),
intv: () => {
return $(".topic").length;
},
root: ".topic",
elements: {
question: ".title",
options: ".main",
$options: ".main",
type: ".title"
},
ignore_click: $item => {
return $item.hasClass("cho-this");
},
wrap: obj => {
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
obj.$options = obj.$item.find(".judge button");
} else if (obj.type === 1) {
obj.options = obj.$item.find(".checkbox .option_text").map((i, y) => {
return $(y).text();
}).toArray();
obj.$options = obj.$item.find(".checkbox button");
} else if (obj.type === 0) {
obj.options = obj.$item.find(".radio .option_text").map((i, y) => {
return $(y).text();
}).toArray();
obj.$options = obj.$item.find(".radio button");
}
console.log(obj);
}
});
WorkerJSPlus({
name: "国开军盾",
match: location.host.includes("s.jundunxueyuan.com") && location.hash.includes("#/exam/"),
intv: () => {
return $(".the-paper .section-item-question-item").length;
},
root: ".section-item-question-item",
elements: {
plat: 43,
question: ".question-tit",
options: ".el-radio-group label,.el-checkbox-group label",
$options: ".el-radio-group input,.el-checkbox-group input",
type: ".sub-dotitle i"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parents(".section-item").find(".section-item-tit").text());
console.log(obj);
}
});
WorkerJSPlus({
name: "博学bx",
match: location.host.includes("bx.bossyun.com") && location.pathname.includes("/bx/study/examine"),
intv: () => {
return $(".question-list").length;
},
root: ".question-list",
elements: {
question: ".title",
options: ".ant-radio-group label,.ant-checkbox-group label",
$options: ".ant-radio-group input,.ant-checkbox-group input",
type: ".tag"
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "博学bx",
match: location.host.includes("bx.bossyun.com") && location.pathname.includes("/bx/study/examine"),
intv: () => {
return $(".question-list").length;
},
root: ".question-list",
elements: {
question: ".title",
options: ".ant-radio-group label,.ant-checkbox-group label",
$options: ".ant-radio-group input,.ant-checkbox-group input",
type: ".tag"
},
ignore_click: $item => {
return $item.prop("checked");
}
});
WorkerJSPlus({
name: "电中在线",
match: location.host.includes("old-zzx.ouchn.edu.cn") && location.pathname.includes("/edu/public/student/"),
intv: () => {
return $(".subject").length;
},
root: ".subject",
elements: {
question: ".question",
options: ".answer .option-name",
$options: ".answer"
},
wrap: obj => {
obj.type = 0;
console.log(obj);
}
});
WorkerJSPlus({
name: "爱学",
match: () => {
const pathMatch = location.pathname.includes("/Web/Test/doing");
const matchHostArr = [ "ai.ztbu.edu.cn", "www.51ixuejiao.com" ];
return pathMatch && matchHostArr.includes(location.host);
},
intv: () => {
return $("card-title").length;
},
root: ".exam dd",
elements: {
question: "card-title",
options: ".ans_area div",
$options: ".ans_area div",
type: "info"
},
ignore_click: $item => {
return $item.attr("selected") === "selected";
},
wrap: obj => {
console.log(obj);
},
fillFinish: data => {
if (data.ans.includes("span") || data.type === 1) {
$(".move_btn span:last").click();
}
}
});
WorkerJSPlus({
name: "人卫智网",
match: location.host.includes("exam.ipmph.com") && location.pathname.includes("/front/myschool/index.html"),
intv: () => {
return $(".body").length;
},
root: ".body",
elements: {
question: ".fch2 font",
options: ".selet .el-radio__label",
$options: ".selet input"
},
wrap: obj => {
obj.type = 0;
console.log(obj);
},
finished: () => {
document.querySelector(".next-btn .text-right a:last-child").click();
}
});
WorkerJSPlus({
name: "卫生人力资源系统",
match: location.host.includes("vgos.zbwsrc.cn") && location.pathname.includes("/TESExamClient/"),
intv: () => {
return $(".testitem").length;
},
root: ".testitem",
elements: {
question: ".stem",
options: ".inputitem li",
$options: ".inputitem input"
},
wrap: obj => {
obj.type = 0;
console.log(obj);
}
});
WorkerJSPlus({
name: "继教在线(考试)",
match: location.pathname.includes("/Student/ExamManage/CourseOnlineExamination"),
intv: () => {
return $(".test_item").length;
},
root: ".test_item",
elements: {
question: ".test_item_tit",
options: ".test_item_theme label",
$options: ".test_item_theme input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
const $item = obj.$item;
obj.type = getQuestionType($item.prevAll(".test_item_type").text());
if (obj.type === 3) {
obj.options = [ "正确", "错误" ];
}
}
});
WorkerJSPlus({
name: "培训系统(考试)",
match: location.pathname.includes("ShowItemView"),
intv: () => {
return $(".choice-interaction").length;
},
root: ".choice-interaction",
elements: {
question: ".select-clickstyle span",
options: ".text-simple-choice .text",
$options: ".text-simple-choice input",
type: ".item-content"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
const $item = obj.$item;
obj.type = getQuestionType($item.parent().prevAll(".item-content").text());
console.log(obj);
},
finished: () => {
window.parent.document.querySelector(".nextBtn").click();
}
});
WorkerJSPlus({
name: "传媒(考试)",
match: location.pathname.includes("/Exam/onlineTest/ShiTiYe.aspx"),
intv: () => {
return $("#Content").length;
},
root: ".ShiTi",
elements: {
question: ".Paper_ParentQuestionDesc",
options: ".Paper_Answer li",
$options: ".Paper_Answer input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
const $item = obj.$item;
obj.type = getQuestionType($item.parents("#ContentText").find("#ExamFrameQuesDesc").text());
console.log(obj);
},
finished: () => {
window.parent.document.querySelector("#btnNext").click();
}
});
WorkerJSPlus({
name: "慧考试",
match: location.pathname.includes("/examSystemPCInner/"),
intv: () => {
return $(".question-list-box").length;
},
root: ".question-list-box > div",
elements: {
question: ".topic-title",
options: ".option_list",
$options: ".option_list ",
type: ".question-type-name"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "河北开放",
match: location.pathname.includes("/exam/") && location.host === "lms.cjzx.hblll.com",
intv: () => {
return $(".loading-gif").hasClass("ng-hide") && $(".hd .examinee .submit-label").eq(0).text() === "";
},
root: ".card ol .single_selection,.multiple_selection,.true_or_false,.short_answer",
elements: {
question: ".summary-title .subject-description",
options: ".subject-options li .option-content",
$options: ".subject-options label .left",
type: ".summary-sub-title span:eq(0)"
},
ignore_click: ($item, type) => {
return type === 1 && $item.find("input").hasClass("ng-not-empty");
}
});
WorkerJSPlus({
name: "自考365",
match: location.host === "member.zikao365.com" && location.pathname.includes("generaltest/exam.shtm"),
intv: () => {
return $(".timu").length;
},
root: ".timu",
elements: {
question: ".timu-tit",
options: ".timu-list .list",
$options: ".timu-list input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "幕享",
match: location.host === "web.moycp.com" && location.pathname.includes("/study"),
intv: () => {
return $(".question-list").length;
},
root: ".question-list",
elements: {
question: ".question-title",
options: ".answer-option label",
$options: ".answer-option input",
type: ".singleflag"
},
ignore_click: ($item, type) => {
if (type === 1) {
return $item.prop("checked");
}
},
wrap: obj => {
console.log(obj);
},
fillFinish: data => {
if (data.style === "warning-row" || data.type === 1) {
$(".next-submit .next").click();
}
},
finished: () => {
if ($(".next-submit .next").hasClass("noClick")) {
return false;
}
return true;
}
});
WorkerJSPlus({
name: "麦能",
match: location.pathname.includes("/lms/web/onlineexam/exambegin"),
intv: () => {
return $(".sdiv").length;
},
root: ".sdiv",
elements: {
question: ".eptimu_name",
options: ".ansdiv div",
$options: ".ansdiv input",
type: ".eptimu_title"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
},
fillFinish: () => {
if ($(".layui-layer").length) {
return false;
}
$(".eptimu_btn_next:eq(0)").click();
return true;
}
});
WorkerJSPlus({
name: "天使在线",
match: location.pathname.includes("/pages_jsp/mobile/courseSimulate.html") || location.pathname.includes("/pages_jsp/mobile/coursExamView.html") || location.pathname.includes("/pages_jsp/mobile/courseAnswer.html"),
intv: () => {
return $("#qusData").length;
},
root: ".neixunExamQuestionHead",
elements: {
question: "#title",
options: ".option",
$options: ".option",
type: ".tag"
},
wrap: obj => {
console.log(obj);
},
fillFinish: () => {
if ($(".next").attr("style") && $(".next").attr("style").includes("display")) {
return false;
}
$(".next").click();
return true;
}
});
WorkerJSPlus({
name: "江西应用",
match: location.pathname.includes("examinationAnswer"),
intv: () => {
return $(".answer-subject-details").length;
},
root: ".answer-subject-details",
elements: {
question: ".answer-subject",
options: "ul li p",
$options: "ul li",
type: ".answer-subject-top"
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "在线学习平台",
match: location.host === "edu.netdig.cn" && location.pathname.includes("/paper.html"),
intv: () => {
return $(".test-list").length;
},
root: ".position-relative",
elements: {
question: ".tmtitle-p",
options: "label .span-inline",
$options: "label input",
type: ".customtktype"
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "含弘",
match: location.host === "zuoye.eduwest.com" && location.pathname.includes("/examinationrecord"),
intv: () => {
return $("#float_right").length;
},
root: "tr td table:has(a)",
elements: {
question: "td:first",
options: "a",
$options: "input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
console.log(obj);
},
finished: () => {
if ($("#button #next").length != 0) {
$("#button #next").click();
return true;
} else {
return false;
}
}
});
WorkerJSPlus({
name: "华莘学堂",
match: location.host.includes("huashenxt.com") && location.pathname.includes("/mgr.html"),
intv: () => {
return $(".terms .question-item").length;
},
root: ".question-item",
elements: {
question: ".question_title .text",
options: ".choice_item .text,.judge_item label",
$options: ".choice_item .choice_option,.judge_item input",
type: ".question_type"
},
ignore_click: $item => {
return $item.hasClass("selected");
},
wrap: obj => {
console.log(obj);
}
});
WorkerJSPlus({
name: "春风雨",
match: location.host.includes("jiaowu.cfyedu.com"),
intv: () => {
return $(".answer").length;
},
root: ".el-col-16 div[id]",
elements: {
question: ".title",
options: ".radio-option",
$options: ".radio-option"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".content-title").text());
}
});
WorkerJSPlus({
name: "心理健康",
match: location.host.includes("zgxlwsxh.oxcoder.com.cn"),
intv: () => {
return $(".question-box").length;
},
root: ".question-container",
elements: {
question: ".question-box .ques-desc-content",
options: ".question-box label",
$options: ".question-box label input",
type: ".directory-title"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.question = obj.question.replace(/\(\d+分\)/, "");
},
finished: need_jump => {
if ($(".ant-btn-circle:last").hasClass("disabled")) {
return false;
}
$(".ant-btn-circle:last").click();
return true;
}
});
WorkerJSPlus({
name: "西安交通大学",
match: location.host.includes("kj.xjtudlc.com"),
intv: () => {
return $(".swiper-wrapper").length;
},
root: ".swiper-slide",
elements: {
question: ".layui-space-item .question",
options: ".layui-checkcard-desc",
$options: ".layui-checkcard-desc",
type: ".layui-space-item:first"
},
ignore_click: $item => {
return $item.parents(".layui-checkcard").hasClass("layui-checkcard-checked");
},
wrap: obj => {
obj.question = obj.question.replace(/\(\d+分\)/, "");
}
});
WorkerJSPlus({
name: "国开",
match: location.host === "lms.ouchn.cn" && location.pathname.includes("/exam/"),
intv: () => {
return $(".loading-gif").hasClass("ng-hide") && $(".hd .examinee .submit-label").eq(0).text() === "";
},
root: ".card ol .single_selection,.multiple_selection,.true_or_false,.short_answer",
elements: {
question: ".summary-title .subject-description",
options: ".subject-options li .option-content",
$options: ".subject-options label .left",
type: ".summary-sub-title span:eq(0)"
},
ignore_click: ($item, type) => {
return type === 1 && $item.find("input").hasClass("ng-not-empty");
}
});
WorkerJSPlus({
name: "广开",
match: () => {
const pathMatch = location.pathname.includes("/mod/quiz/attempt.php");
const matchHostArr = [ "moodle.syxy.ouchn.cn", "xczxzdbf.moodle.qwbx.ouchn.cn", "elearning.bjou.edu.cn", "whkpc.hnqtyq.cn:5678", "course.ougd.cn", "study.ouchn.cn" ];
return pathMatch && matchHostArr.includes(location.host);
},
root: ".que",
elements: {
question: ".qtext",
options: ".answer div label,.flex-fill",
$options: ".answer div input:visible"
},
wrap: data => {
if (data.type === undefined) {
try {
data.type = 4;
data.$item.find(".qtext .accesshide").remove();
data.question = formatString(data.$item.find(".qtext").html());
data.$options = data.$item.find("input[id$=_answer]");
} catch (e) {}
}
},
ignore_click: $item => {
return Boolean($item.parent().find("input").eq(-1).prop("checked"));
},
finished: () => {
$(".submitbtns .btn-primary").click();
},
fill: (type, answer, $option) => {
if (type === 4) {
console.log(type, answer, $option);
console.log($option.attr("id"));
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "保定继续教育",
match: location.pathname.includes("/exam/answer.html"),
root: ".stem-container",
elements: {
question: ".stem span",
options: ".option div .optStem",
$options: ".option div input"
},
intv: () => {
return $("#question").length;
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().parent().find(".description").text());
}
});
WorkerJSPlus({
name: "noNiExam.js",
match: location.pathname === "/app-afstudy/self_test.html",
root: ".lineClass .b-papp-root",
elements: {
question: ".b-exam-top .b-exam-tit",
options: ".b-exam-box li label",
$options: ".b-exam-box li input",
type: ".b-exam-top .b-exam-type"
},
ignore_click($item) {
return $item.prop("checked");
},
wrap(obj) {
obj.options = obj.options.map(i => {
return i.replace(/[A-Za-z][\:]/, "").replace(/[A-Za-z][\:,\:]/, "").replace(/\;/, "").trim();
});
}
});
WorkerJSPlus({
name: "www_pbaqks_com_text",
match: location.host === "www.pbaqks.com" && location.pathname.includes("/P_ExamDetail/OnlineStuday"),
root: ".main-container .single-box",
elements: {
question: ".single-main:first",
options: ".choose-box label",
$options: ".choose-box label",
type: ".single-container .font-title",
answer: "input:eq(1)"
},
ignore_click: $i => {
return $i.find("input").is(":checked");
},
wrap: obj => {
obj.question = obj.question.replace("标准答案", "").replace(/^\d+\./, "").replace(/\[.+?\]/g, "").trim();
},
fillFinish: () => {
if ($(".main-container .single-box").find("input:eq(1)").eq(GLOBAL.index - 1).attr("value").split("").length > 1) {
jQuery(".main-container .confirm a:last-child").click();
}
}
});
WorkerJSPlus({
name: "安徽继续教育",
match: location.pathname.includes("/study/html/content/studying/") || (location.pathname === "/study/html/content/tkOnline/" || location.pathname === "/study/html/content/sxsk/" || location.pathname === "/study/html/content/bkExam/"),
intv: () => {
return ($(".e-save-b").length || $(".e-b-g").length) && $(".totalscore").length === 0;
},
root: ".e-q",
elements: {
question: ".e-q-q .ErichText",
options: ".e-a-g li",
$options: ".e-a-g li"
},
ignore_click: $item => {
return $item.attr("class").includes("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().prev().find(".e-text").text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/^[ab]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
}
});
WorkerJSPlus({
name: "大连/九江",
match: location.href.includes("/onlineclass/exam/"),
intv: () => {
return $(".excer_list_view___2Ahg9") || $(".excer_list_view___YOSCa");
},
root: ".single_excer_item___lFMCm,.single_excer_item___2lGB8",
elements: {
plat: 40,
question: ".title_content___1Qagx .title_content_text___27NIL, .title_content___24J6D .title_content_text___8ruL4",
options: ".options_content___nXSwG label .option_text___udjiE, .options_content___2YgyG label .option_text___1mfcu",
$options: ".options_content___nXSwG label input,.options_content___2YgyG label input",
type: ".title_content___1Qagx span:eq(1),.title_content___24J6D span:eq(1)"
},
ignore_click: $item => {
return $($item).parent().hasClass("ant-checkbox-checked");
},
wrap: obj => {
console.log(obj);
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "新疆继续教育",
hook: () => {
function parseXinJiangAgain(questions) {
return questions.map(item => {
const answer = [];
const options = item.answers.map(opt => {
if (opt.isAnswer === "0") answer.push(formatString(opt.name));
return formatString(opt.name);
});
const type = item.types === "2" ? 3 : parseInt(item.types);
return {
question: item.name,
options: options,
answer: answer,
type: type
};
});
}
JSONParseHook(o => {
if (o.success && o.data.exam) {
const arr = o.data.exam.assessList.map(i => {
return i.questionList;
}).flat();
GLOBAL.json = parseXinJiangAgain(arr);
}
});
},
match: location.host === "www.ttcdw.cn" && location.pathname.includes("/p/uExam/goExam/"),
root: ".question-item",
elements: {
question: ".question-item-title span",
options: ".question-item-option label .el-checkbox__label,.el-radio__label",
$options: ".question-item-option label"
},
wrap: obj => {
Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
},
intv: () => {
return !$("div").hasClass("entrying-wrap");
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
fill: (type, answer, $option) => {
if (type === 4 || type === 2) {
$option.val(answer);
}
}
});
WorkerJSPlus({
name: "华侨继续教育",
match: location.pathname.includes("/exam/student/exam/resource/paper_card2"),
intv: () => {
return $(".ui-question-answer-right").length === 0;
},
root: ".ui-question-group .ui-question",
elements: {
question: ".ui-question-title div",
options: ".ui-question-options div",
$options: ".ui-question-options .ui-question-options-order,.ke-container"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find("h2").text());
},
ignore_click: $item => {
return $item.parent().hasClass("ui-option-selected");
},
fill: (type, answer) => {
if (type === 4 || type === 2 || type === 6) {
const x = GLOBAL.index - $(".ui-question-options ").length - 1;
KindEditor.instances[x].html(answer);
}
}
});
WorkerJSPlus({
name: "上海开放大学",
match: location.pathname.includes("/study/assignment/preview.aspx") || location.pathname.includes("/study/assignment/continuation.aspx"),
hook: () => {
if (GLOBAL.finish || $("a:contains(已完成批阅)").length === 1) {
iframeMsg("tip", {
type: "hidden",
tip: "本页面已做完,无需自动答题"
});
return true;
}
},
root: ".e-q",
elements: {
question: ".e-q-q .ErichText",
options: ".e-a-g li",
$options: ".e-a-g li"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().parent().parent().find(".e-text").eq(0).text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.attr("class").includes("checked");
}
});
WorkerJSPlus({
name: "浙江考试",
match: location.pathname === "/web-qz/moni/exam/exam_toExam.action",
root: ".dt_tmcon",
elements: {
question: "div:eq(0) span:eq(1)",
options: "div:eq(1) p",
$options: "div:eq(1) p input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parents().find(".dt_rtitle1").eq(0).text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
if (obj.type === 0) {
obj.answer = [ JSON.parse($("#quesSSForm #userAnssStr_0").val()).rightAnswer ];
uploadAnswer([ obj ]);
}
},
finished: () => {
return $(".page li input:eq(2)").attr("disabled") !== "disabled";
},
fillFinish: () => {
$(".page li input:eq(2)").click();
}
});
WorkerJSPlus({
name: "在浙学考试",
match: location.host === "www.zjooc.cn" && (location.pathname.includes("/homework/") || location.pathname.includes("/test/") || location.pathname.includes("/exam/")),
hook: () => {
function parseZaiZheXue(problems) {
return problems.map(item => {
if (!item.rightAnswer) return undefined;
const subjectType = item.subjectType;
let type = -1;
const question = formatString(item.subjectName);
const answer = [];
const options = [];
if (subjectType === 1 || subjectType === 2) {
type = subjectType - 1;
for (let subjectOption of item.subjectOptions) {
const opt = formatString(subjectOption.optionContent);
options.push(opt);
if (item.rightAnswer.includes(subjectOption.optionHead)) {
answer.push(opt);
}
}
} else if (subjectType === 3) {
type = 3;
answer.push(item.rightAnswer === "yes" ? "正确" : "错误");
} else {
return undefined;
}
return {
question: question,
options: options,
type: type,
answer: answer
};
}).filter(i => i && i.answer.length > 0);
}
if (!(location.pathname.includes("/homework/do") || location.pathname.includes("/test/do") || location.pathname.includes("/exam/do"))) {
JSONParseHook(o => {
if (o.data && o.data.paperName && o.data.clazzIds && o.data.paperSubjectList) {
const data = parseZaiZheXue(o.data.paperSubjectList);
console.log(data);
}
});
return true;
}
},
root: ".questiono-item",
elements: {
question: "h6 .processing_img",
options: ".questiono-main label .el-radio__label,.el-checkbox__label",
$options: ".questiono-main label"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().prev().text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
},
ignore_click: $item => {
return $item.hasClass("is-checked");
}
});
WorkerJSPlus({
name: "在浙学(测验/考试)",
match: location.host === "www.zjooc.cn" && location.pathname.includes("/singleQuestion/do/"),
intv: () => {
return $(".settingsel-dialog").css("display") === "none";
},
root: ".question_content:first",
elements: {
question: ".question_title",
options: ".question_content .radio_content div",
$options: ".question_content label"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".question_title p").eq(0).text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").replace(".", "").trim());
});
},
ignore_click: $item => {
return $item.hasClass("is-checked");
},
finished: () => {
if ($(".question_btn .el-button:contains(下一题)").hasClass("is-disabled")) return false;
$(".el-button:contains(下一题)").click();
return true;
}
});
WorkerJSPlus({
name: "福建继续教育测验|作业",
match: location.pathname === "/Web_Study/Student/Center/MyWorkOnView" || location.pathname === "/Web_Study/Student/Center/MyExamOnView",
intv: () => {
return $(".samllTopicNav").length;
},
root: ".topic-cont",
elements: {
question: "p",
options: ".options li span",
$options: ".options li"
},
wrap: obj => {
obj.options = obj.options.map(i => {
return i.replace(/选项[A-Za-z]/, "").trim();
});
obj.type = {
1: 0,
2: 1,
3: 3,
6: 4
}[obj.$item.attr("itemtype")];
if (obj.type === undefined) obj.type = 4;
},
ignore_click: $item => {
return $item.hasClass("correct");
},
fill: (type, answer, $option) => {}
});
WorkerJSPlus({
name: "湖南继续教育",
match: () => {
const pathMatch = location.pathname.includes("/User/Student/myhomework.aspx") || location.pathname.includes("/examing.aspx");
const matchHostArr = [ "www.jwstudy.cn", "hdjt.wuxuekeji.com", "csjs.ynlhxy.com" ];
return pathMatch && (matchHostArr.includes(location.host) || location.host.includes("ls365.net") || location.host.includes("ls365.com"));
},
root: ".exam_question",
elements: {
question: ".exam_question_title div",
options: ".question_select .select_detail",
$options: ".question_select li",
type: ".exam_question_title div strong"
},
ignore_click: $item => {
return $item.hasClass("cur");
}
});
WorkerJSPlus({
name: "德阳继续教育",
match: location.href.includes("/dypx/OnlineExam/Exam.aspx"),
root: "#divProblemArea",
elements: {
question: "#ulProblems li:first",
options: "#ulProblems .answer",
$options: "#ulProblems .answer input"
},
ignore_click: $item => {
return $item.prop("checked");
},
wrap: obj => {
if ($("#ulProblems .answer input").length < 3 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") {
obj.type = 3;
obj.options = [ "正确", "错误" ];
} else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") {
obj.type = 0;
} else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "checkbox") {
obj.type = 1;
}
},
finished: () => {
if ($(".dlg").length) return false;
$("#divBtns input:eq(1)").click();
return true;
}
});
WorkerJSPlus({
name: "淄博继续教育",
match: location.pathname.includes("/practice/start"),
root: ".header-left .trueorfalse .sub",
elements: {
question: ".mb10",
options: ".options li",
$options: ".options li"
},
ignore_click: $item => {
return $item.hasClass("active");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().prev().text());
obj.options = obj.options.map(i => {
return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
});
}
});
WorkerJSPlus({
name: "河北继续教育",
match: location.pathname.includes("paperid"),
intv: () => {
return $(".examControl").length;
},
root: ".examItem",
elements: {
question: ".examItemRight .question",
options: ".examItemRight ul li span",
$options: ".examItemRight ul li"
},
ignore_click: $item => {
return $item.hasClass("cur");
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find(".questTitle b").text());
}
});
WorkerJSPlus({
name: "保定继续教育",
match: () => {
const pathnameArr = [ "/cuggw/rs/olex_exam", "/hebic/rs/olex_exam", "/sjzkjxy/rs/olex_exam", "/hbfsh/rs/olex_exam", "/jxycu/rs/olex_exam", "/jlufe/rs/olex_exam", "/hbun/rs/olex_exam" ];
return pathnameArr.includes(location.pathname);
},
intv: () => {
return $(".paper_body").length;
},
root: ".item_li",
elements: {
question: ".item_title",
options: "ul li label",
$options: "ul li input"
},
ignore_click($item) {
return $item.prop("checked");
},
wrap: obj => {
if (obj.$options.length === 2) {
obj.type = 3;
} else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") {
obj.type = 0;
} else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") !== "radio") {
obj.type = 1;
} else {
obj.type = 4;
}
}
});
WorkerJSPlus({
name: "唐山继续教育",
match: location.pathname.includes("/exam/student/exam/"),
intv: () => {
return $(".ui-question-group").length;
},
root: ".ui-question-group .ui-question",
elements: {
question: ".ui-question-title .ui-question-content-wrapper",
options: ".ui-question-options .ui-question-content-wrapper",
$options: ".ui-question-options .ui-question-options-order"
},
wrap: obj => {
obj.type = getQuestionType(obj.$item.parent().find("h2").text());
}
});
WorkerJSPlus({
name: "zzcjxy.hnzkw.org.cn",
match: location.host.includes("hnzkw.org.cn"),
intv: () => {
return $(".answer").length;
},
hook: () => {
JSONParseHook(o => {
if (o.data && o.data.bookdatas) {
GLOBAL.json = parsehnzkwText(o.data.bookdatas);
}
});
},
root: ".examList",
elements: {
question: ".text",
options: ".el-radio-group label,.el-checkbox-group label",
$options: ".el-radio-group input,.el-checkbox-group input",
type: ".status"
},
wrap: obj => {
Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
},
fill: (type, answer, $option) => {}
});
WorkerJSPlus({
name: "问卷星考试",
match: location.pathname.includes("/exam/ExamRd/Answer"),
root: ".g-mn",
elements: {
question: ".m-question .tigan",
options: ".question-block .xuanxiang",
$options: ".question-block .xuanxiang",
type: ".tixing"
},
ignore_click: ($item, type) => {
if (type === 1) {
return $item.parent().find(".icheckbox_square-green").hasClass("checked");
} else {
const isIgnore = $item.parent().find(".iradio_square-green").hasClass("checked");
return isIgnore;
}
},
wrap: obj => {
if ($(".layui-layer-content").length) {
iframeMsg("tip", {
type: "stop",
tip: "答题暂停,请自行通过验证"
});
GLOBAL.stop = true;
return true;
}
},
fillFinish: data => {
if (data.style === "warning-row" || $(".g-mn").parent().find(".iradio_square-green").hasClass("checked") || data.type === 1) {
$('.u-btn-next:contains("下一题")').click();
}
},
finished: () => {
return parseInt($(".num-dangqian:last").attr("qindex")) !== $(".num-item").length;
}
});
})();