// ==UserScript== // @name 【超星学习通助手】视频+测试+考试(新增更稳定的电脑端,手机端使用方法,支持多开), // @namespace unrival // @version 1.51 // @description 上次更新:2024/4/17 新增了更稳定的电脑端(支持多开),手机端的使用方法 // @author unrival // @run-at document-end // @storageName unrivalxxt // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @match *://*.nbdlib.cn/* // @match *://*.hnsyu.net/* // @match *://*.ac.cn/* // @icon http://pan-yz.chaoxing.com/favicon.ico // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_info // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_setValue // @grant GM_getResourceURL // @connect mooc1-1.chaoxing.com // @connect mooc1.chaoxing.com // @connect mooc1-2.chaoxing.com // @connect passport2-api.chaoxing.com // @connect 14.29.190.187 // @connect cx.icodef.com // @license GPL-3.0-or-later // @original-script https://scriptcat.org/script-show-page/1692 // @original-author unrival // @original-license GPL-3.0-or-later // @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 //如果脚本提示添加安全网址,请将脚本提示内容填写到下方区域,一行一个,如果不会,请加群询问 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 + "?gpt=" + (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(''); }).end().find("iframe[src]").replaceWith(function() { return $("

").text('
任务列表
运行日志
[00:00:00]如果此提示不消失,说明页面出现了错误,请联系作者
`; var logs = { "logArry": [], "addLog": function (str, color = "black") { if (this.logArry.length >= 50) { this.logArry.splice(0, 1); } var nowTime = new Date(); var nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2); var nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2); var nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2); this.logArry.push("[" + nowHour + ":" + nowMin + ":" + nowSec + "] " + str + ""); let logStr = ""; for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) { logStr += this.logArry[logI] + "
"; } _d.getElementById('log').innerHTML = logStr; var logElement = _d.getElementById('log'); logElement.scrollTop = logElement.scrollHeight; } }, htmlHook = setInterval(function () { if (_d.getElementById('unrivalRate') && _d.getElementById('updateRateButton') && _d .getElementById('reviewModeButton') && _d.getElementById('autoDoWorkButton') && _d .getElementById('autoSubmitButton') && _d.getElementById('autoSaveButton')) { if (!backGround) { _d.getElementById('fuckMeModeButton').style.display = "none"; } allowBackground = Math.round(new Date() / 1000) - parseInt(GM_getValue( 'unrivalBackgroundVideoEnable', '6')) < 15; if (allowBackground) { _d.getElementById('fuckMeModeButton').setAttribute('href', 'unrivalxxtbackground/'); } clearInterval(htmlHook); if (cVersion < 86) { logs.addLog( '\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e', 'red'); stop = true; return; } if (isMobile) { logs.addLog('手机浏览器不保证能正常运行此脚本', 'orange'); } _d.addEventListener('visibilitychange', function () { let isH = _d.hidden; if (!isH) { logs.addLog('挂机功能不稳定,不建议长时间最小化窗口', 'orange'); } }); _d.getElementById('unrivalRate').value = rate; _d.getElementById('updateToken').onclick = function () { var token = _d.getElementById('token').value; logs.addLog('题库token已更新为' +token, 'green'); GM_setValue('tikutoken', token); } _d.getElementById('updateRateButton').onclick = function () { let urate = _d.getElementById('unrivalRate').value; if (parseFloat(urate) == parseInt(urate)) { urate = parseInt(urate); } else { urate = parseFloat(urate); } GM_setValue('unrivalrate', urate); rate = urate; if (urate > 0) { logs.addLog('视频倍速已更新为' + urate + '倍,将在3秒内生效', 'green'); } else { logs.addLog('倍速小于等于0时,将会自动跳过视频任务', 'orange'); } } _d.getElementById('backGround').onclick = function () { logs.addLog('挂机激活成功,您现在可以最小化页面了', 'green'); _w.top.backNow = 1; } _d.getElementById('reviewModeButton').onclick = function () { let reviewButton = _d.getElementById('reviewModeButton'); if (reviewButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-success'); logs.addLog('复习模式已开启,遇到已完成的视频任务不会跳过', 'green'); GM_setValue('unrivalreview', '1'); _w.top.unrivalReviewMode = '1'; } else { _d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-default'); logs.addLog('复习模式已关闭,遇到已完成的视频任务会自动跳过', 'green'); GM_setValue('unrivalreview', '0'); _w.top.unrivalReviewMode = '0'; } } _d.getElementById('autoDoWorkButton').onclick = function () { let autoDoWorkButton = _d.getElementById('autoDoWorkButton'); if (autoDoWorkButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-success'); logs.addLog('自动做章节测试已开启,将会自动做章节测试', 'green'); GM_setValue('unrivaldowork', '1'); _w.top.unrivalDoWork = '1'; } else { _d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-default'); logs.addLog('自动做章节测试已关闭,将不会自动做章节测试', 'green'); GM_setValue('unrivaldowork', '0'); _w.top.unrivalDoWork = '0'; } } _d.getElementById('autoSubmitButton').onclick = function () { let autoSubmitButton = _d.getElementById('autoSubmitButton'); if (autoSubmitButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-success'); logs.addLog('符合提交标准的章节测试将会自动提交', 'green'); GM_setValue('unrivalautosubmit', '1'); _w.top.unrivalAutoSubmit = '1'; } else { _d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-default'); logs.addLog('章节测试将不会自动提交', 'green'); GM_setValue('unrivalautosubmit', '0'); _w.top.unrivalAutoSubmit = '0'; } } _d.getElementById('autoSaveButton').onclick = function () { let autoSaveButton = _d.getElementById('autoSaveButton'); if (autoSaveButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-success'); logs.addLog('不符合提交标准的章节测试将会自动保存', 'green'); GM_setValue('unrivalautosave', '1'); _w.top.unrivalAutoSave = '1'; } else { _d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-default'); logs.addLog('不符合提交标准的章节测试将不会自动保存,等待用户自己操作', 'green'); GM_setValue('unrivalautosave', '0'); _w.top.unrivalAutoSave = '0'; } } _d.getElementById('videoTimeButton').onclick = function () { _d.getElementById('videoTime').style.display = 'block'; _d.getElementById('videoTimeContent').src = _p + '//stat2-ans.chaoxing.com/task/s/index?courseid=' + courseId + '&clazzid=' + classId; } } }, 100), loopjob = () => { if (_w.top.unrivalScriptList.length > 1) { logs.addLog('您同时开启了多个刷课脚本,会挂科', 'red'); } if (cVersion < 8.6 * 10) { logs.addLog( '\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e', 'red'); stop = true; return; } if (stop) { return; } let missionli = missionList; if (missionli == []) { setTimeout(loopjob, 500); return; } for (let itemName in missionli) { if (missionli[itemName]['running']) { setTimeout(loopjob, 500); return; } } for (let itemName in missionli) { if (!missionli[itemName]['done']) { switch (missionli[itemName]['type']) { case 'video': doVideo(missionli[itemName]); break; case 'document': doDocument(missionli[itemName]); break; case 'work': doWork(missionli[itemName]); break; } setTimeout(loopjob, 500); return; } } if (busyThread <= 0) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('所有任务处理完毕,5秒后自动下一章', 'green'); } else { logs.addLog('所有任务处理完毕,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green'); } clearInterval(loopjob); } else { setTimeout(loopjob, 500); } }, readyCheck = () => { setTimeout(function () { try { if (!isCat) { logs.addLog( '推荐使用脚本猫运行此脚本,使用其他脚本管理器不保证能正常运行', 'orange'); } if (_w.top.unrivalReviewMode == '1') { logs.addLog('复习模式已开启,遇到已完成的视频任务不会跳过', 'green'); _d.getElementById('reviewModeButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalReviewMode]); } if (_w.top.unrivalDoWork == '1') { logs.addLog('自动做章节测试已开启,将会自动做章节测试', 'green'); _d.getElementById('autoDoWorkButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalDoWork]); } _d.getElementById('autoSubmitButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalAutoSubmit]); _d.getElementById('autoSaveButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalAutoSave]); } catch (e) { console.log(e); readyCheck(); return; } }, 500); } readyCheck(); try { var pageData = JSON.parse(param); } catch (e) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('此页无任务,5秒后自动下一章', 'green'); } else { logs.addLog('此页无任务,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green'); } return; } var data = pageData['defaults'], jobList = [], classId = data['clazzId'], chapterId = data['knowledgeid'], reportUrl = data['reportUrl'], ktoken = data['ktoken']; UID = UID || data['userid']; FID = FID || data['fid']; for (let i = 0, l = pageData['attachments'].length; i < l; i++) { let item = pageData['attachments'][i]; if (item['job'] != true || item['isPassed'] == true) { if (_w.top.unrivalReviewMode == '1' && item['type'] == 'video') { jobList.push(item); } continue; } else { jobList.push(item); } } var video_getReady = (item) => { let statusUrl = _p + '//' + _h + '/ananas/status/' + item['property']['objectid'] + '?k=' + FID + '&flag=normal&_dc=' + String(Math.round(new Date())), doubleSpeed = item['property']['doublespeed']; busyThread += 1; GM_xmlhttpRequest({ method: "get", headers: { 'Host': _h, 'Referer': vrefer, 'Sec-Fetch-Site': 'same-origin' }, url: statusUrl, onload: function (res) { try { busyThread -= 1; let videoInfo = JSON.parse(res.responseText), duration = videoInfo['duration'], dtoken = videoInfo['dtoken']; if (duration == undefined) { _d.getElementById('joblist').innerHTML += `
` + '[无效视频]' + item['property']['name'] + `
` return; } missionList['m' + item['jobid']] = { 'module': item['property']['module'], 'type': 'video', 'dtoken': dtoken, 'duration': duration, 'objectId': item['property']['objectid'], 'rt': item['property']['rt'] || '0.9', 'otherInfo': item['otherInfo'], 'doublespeed': doubleSpeed, 'jobid': item['jobid'], 'name': item['property']['name'], 'done': false, 'running': false }; _d.getElementById('joblist').innerHTML += `
` + '[视频]' + item['property']['name'] + `
` } catch (e) { } }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog('请添加安全网址,将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:', 'red'); logs.addLog( '' ); stop = true; } else { logs.addLog('获取任务详情失败', 'red'); logs.addLog('错误原因:' + err.error, 'red'); } } }); }, doVideo = (item) => { if (rate <= 0) { missionList['m' + item['jobid']]['running'] = true; logs.addLog('倍速设置为0时,视频将自动跳过', 'orange'); setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } if (allowBackground && backGround) { if (_w.top.document.getElementsByClassName('catalog_points_sa').length > 0 || _w.top.document .getElementsByClassName('lock').length > 0) { logs.addLog('您已安装超星挂机小助手,但此课程可能为闯关模式,不支持后台挂机,将为您在线完成', 'blue'); } else { item['userid'] = UID; item['classId'] = classId; item['review'] = [false, true][_w.top.unrivalReviewMode]; item['reportUrl'] = reportUrl; item['rt'] = missionList['m' + item['jobid']]['rt']; GM_setValue('unrivalBackgroundVideo', item); _d.cookie = "videojs_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; logs.addLog( '您已安装超星挂机小助手,已添加至后台任务,点我查看后台', 'green'); missionList['m' + item['jobid']]['running'] = true; setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } } let videojs_id = String(parseInt(Math.random() * 9999999)); _d.cookie = 'videojs_id=' + videojs_id + ';path=/' logs.addLog('开始刷视频:' + item['name'] + ',倍速:' + String(rate) + '倍'); logs.addLog('视频观看信息每60秒上报一次,请耐心等待', 'green'); logs.addLog('如遇脚本使用异常情况,请检查脚本版本是否为最新版。', 'orange'); if (disableMonitor) { logs.addLog('解除多端学习监控有清除进度风险,请谨慎使用', 'orange'); } let dtype = 'Video'; if (item['module'].includes('audio')) { dtype = 'Audio'; rt = ''; } let playTime = 0, playsTime = 0, isdrag = '3', times = 0, encUrl = '', first = true, loop = setInterval(function () { if (rate <= 0) { clearInterval(loop); logs.addLog('奇怪的倍速,视频已自动跳过', 'orange'); setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } else if (item['doublespeed'] == 0 && rate > 1 && _w.top.unrivalReviewMode == '0') { //rate = 1; //logs.addLog('该视频不允许倍速播放,已恢复至一倍速,高倍速会被清空进度挂科,勿存侥幸', 'red'); } rt = missionList['m' + item['jobid']]['rt']; playsTime += rate; playTime = Math.ceil(playsTime); if (times == 0 || times % 30 == 0 || playTime >= item['duration']) { if (first) { playTime = 0; } if (playTime >= item['duration']) { clearInterval(loop); playTime = item['duration']; isdrag = '4'; } else if (playTime > 0) { isdrag = '0'; } encUrl = host + 'chaoXing/v3/getEnc.php?classid=' + classId + '&playtime=' + playTime + '&duration=' + item['duration'] + '&objectid=' + item[ 'objectId'] + '&jobid=' + item['jobid'] + '&uid=' + UID; busyThread += 1; var _bold_playTime = playTime; function ecOnload(res) { let enc = ''; if (res && res.status == 200) { enc = res.responseText; if (enc.includes('--#')) { let warnInfo = enc.match(new RegExp('--#(.*?)--#', "ig"))[0] .replace(/--#/ig, ''); logs.addLog(warnInfo, 'red'); enc = enc.replace(/--#(.*?)--#/ig, ''); } if (enc.indexOf('.stop') >= 0) { clearInterval(loop); stop = true; return; } } else { strEc = `[${classId}][${UID}][${item['jobid']}][${item['objectId']}][${playTime * 1000}][d_yHJ!$pdA~5][${item['duration'] * 1000}][0_${item['duration']}]`, enc = jq.md5(strEc); } if (enc.length != 32) { clearInterval(loop); stop = true; return; } let reportsUrl = reportUrl + '/' + item['dtoken'] + '?clazzId=' + classId + '&playingTime=' + playTime + '&duration=' + item['duration'] + '&clipTime=0_' + item[ 'duration'] + '&objectId=' + item['objectId'] + '&otherInfo=' + item['otherInfo'] + '&jobid=' + item[ 'jobid'] + '&userid=' + UID + '&isdrag=' + isdrag + '&view=pc&enc=' + enc + '&rt=' + rt + '&dtype=' + dtype + '&_t=' + String(Math.round(new Date())); GM_xmlhttpRequest({ method: "get", headers: { 'Host': _h, 'Referer': vrefer, 'Sec-Fetch-Site': 'same-origin', 'Content-Type': 'application/json' }, url: reportsUrl, onload: function (res) { try { let today = new Date(), todayStr = today.getFullYear() + 'd' + today.getMonth() + 'd' + today .getDate(), timelong = GM_getValue( 'unrivaltimelong', {}); if (timelong[UID] == undefined || timelong[UID]['today'] != todayStr ) { timelong[UID] = { 'time': 0, 'today': todayStr }; } else { timelong[UID]['time']++; } GM_setValue('unrivaltimelong', timelong); busyThread -= 1; if (timelong[UID]['time'] / 60 > 22 && item['doublespeed'] == 0 && _w.top .unrivalReviewMode == '0') { clearInterval(loop); logs.addLog( '今日学习时间过长,继续学习会导致清空进度,请明天再来', 'red'); setTimeout(function () { missionList['m' + item[ 'jobid']][ 'running' ] = false; missionList['m' + item[ 'jobid']][ 'done' ] = true; }, 5000); return; } let ispass = JSON.parse(res .responseText); first = false; if (ispass['isPassed'] && _w.top .unrivalReviewMode == '0') { logs.addLog('视频任务已完成', 'green'); missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; clearInterval(loop); return; } else if (isdrag == '4') { if (_w.top.unrivalReviewMode == '1') { logs.addLog('视频已观看完毕', 'green'); } else { logs.addLog('视频已观看完毕,但视频任务未完成', 'red'); } missionList['m' + item['jobid']][ 'running' ] = false; missionList['m' + item['jobid']][ 'done' ] = true; try { clearInterval(loop); } catch (e) { } } else { logs.addLog(item['name'] + '已观看' + _bold_playTime + '秒,剩余大约' + String(item['duration'] - _bold_playTime) + '秒'); } } catch (e) { console.log(e); if (res.responseText.indexOf('验证码') >= 0) { logs.addLog('已被超星风控,请点我处理,60秒后自动刷新页面', 'red'); missionList['m' + item['jobid']][ 'running' ] = false; clearInterval(loop); stop = true; setTimeout(function () { _l.reload(); }, 60000); return; } logs.addLog('超星返回错误信息,十秒后重试', 'red'); times = -10; return; } }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog( '请添加安全网址,将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:', 'red'); logs.addLog( '' ); stop = true; } else { logs.addLog('观看视频失败', 'red'); logs.addLog('错误原因:' + err.error, 'red'); } missionList['m' + item['jobid']][ 'running' ] = false; clearInterval(loop); } }); }; GM_xmlhttpRequest({ method: "get", url: encUrl, timeout: 2000, onload: ecOnload, onerror: function (err) { console.log(err); ecOnload(false); }, ontimeout: function (err) { console.log(err); ecOnload(false); } }); } times += 1; }, 1000); missionList['m' + item['jobid']]['running'] = true; }, doDocument = (item) => { missionList['m' + item['jobid']]['running'] = true; logs.addLog('开始刷文档:' + item['name']); setTimeout(function () { busyThread += 1; GM_xmlhttpRequest({ method: "get", url: _p + '//' + _h + '/ananas/job/document?jobid=' + item['jobid'] + '&knowledgeid=' + chapterId + '&courseid=' + courseId + '&clazzid=' + classId + '&jtoken=' + item['jtoken'], onload: function (res) { try { busyThread -= 1; let ispass = JSON.parse(res.responseText); if (ispass['status']) { logs.addLog('文档任务已完成', 'green'); } else { logs.addLog('文档已阅读完成,但任务点未完成', 'red'); } } catch (err) { console.log(err); console.log(res.responseText); logs.addLog('解析文档内容失败', 'red'); } missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog('请添加安全网址,将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:', 'red'); logs.addLog( '' ); stop = true; } else { logs.addLog('阅读文档失败', 'red'); logs.addLog('错误原因:' + err.error, 'red'); } missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; } }); }, parseInt(Math.random() * 2000 + 9000, 10)) }, doWork = (item) => { missionList['m' + item['jobid']]['running'] = true; logs.addLog('开始刷章节测试:' + item['name']); logs.addLog('您设置的答题通过率为:' + String(accuracy) + '%,只有在高于此正确率时才会提交测试(不是正确率,是通过率!)', 'blue'); _d.getElementById('workPanel').style.display = 'block'; _d.getElementById('frame_content').src = _p + '//' + _h + '/work/phone/work?workId=' + item['jobid'] .replace('work-', '') + '&courseId=' + courseId + '&clazzId=' + classId + '&knowledgeId=' + chapterId + '&jobId=' + item['jobid'] + '&enc=' + item['enc']; _w.top.unrivalWorkInfo = ''; _w.top.unrivalDoneWorkId = ''; setInterval(function () { if (_w.top.unrivalWorkInfo != '') { logs.addLog(_w.top.unrivalWorkInfo); _w.top.unrivalWorkInfo = ''; } }, 100); let checkcross = setInterval(function () { if (_w.top.unrivalWorkDone == false) { clearInterval(checkcross); return; } let ifW = _d.getElementById('frame_content').contentWindow; try { ifW.location.href; } catch (e) { console.log(e); if (e.message.indexOf('cross-origin') != -1) { clearInterval(checkcross); _w.top.unrivalWorkDone = true; return; } } }, 2000); let workDoneInterval = setInterval(function () { if (_w.top.unrivalWorkDone) { _w.top.unrivalWorkDone = false; clearInterval(workDoneInterval); _w.top.unrivalDoneWorkId = ''; _d.getElementById('workPanel').style.display = 'none'; _d.getElementById('frame_content').src = ''; setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); } }, 500); }, missionList = []; if (jobList.length <= 0) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('此页无任务,5秒后自动下一章', 'green'); } else { logs.addLog('此页无任务,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green'); } return; } for (let i = 0, l = jobList.length; i < l; i++) { let item = jobList[i]; if (item['type'] == 'video') { video_getReady(item); } else if (item['type'] == 'document') { missionList['m' + item['jobid']] = { 'type': 'document', 'jtoken': item['jtoken'], 'jobid': item['jobid'], 'name': item['property']['name'], 'done': false, 'running': false }; _d.getElementById('joblist').innerHTML += `
` + '[文档]' + item['property']['name'] + `
` } else if (item['type'] == 'workid' && _w.top.unrivalDoWork == '1') { missionList['m' + item['jobid']] = { 'type': 'work', 'workid': item['property']['workid'], 'jobid': item['jobid'], 'name': item['property']['title'], 'enc': item['enc'], 'done': false, 'running': false }; _d.getElementById('joblist').innerHTML += `
` + '[章节测试]' + item['property']['title'] + `
` } else { try { let jobName = item['property']['name']; if (jobName == undefined) { jobName = item['property']['title']; } _d.getElementById('joblist').innerHTML += `
` + '已跳过:' + jobName + `
` } catch (e) { } } } loopjob(); } else if (_l.href.includes("mycourse/studentstudy")) { var audiofile = 'data:audio/ogg;base64,T2dnUwACAAAAAAAAAABwRPFFAAAAAGFtEqwBHgF2b3JiaXMAAAAAAUAfAAAAAAAAUHgAAAAAAACZAU9nZ1MAAAAAAAAAAAAAcETxRQEAAAA7J4IBDP8F////////////tQN2b3JiaXMvAAAAWGlwaC5PcmcgbGliVm9yYmlzIEkgMjAxNDAxMjIgKFR1cnBha8OkcsOkamlpbikGAAAAJQAAAEVOQ09ERVI9U291bmQgU3R1ZGlvLCBsaWJWb3JiaXMgMS4zLjEbAAAAQUxCVU0gQVJUSVNUPUFkdmVudHVyZSBMYW5kFAAAAEFMQlVNPUFkdmVudHVyZSBMYW5kIQAAAEVOQ09ESU5HIEFQUExJQ0FUSU9OPVNvdW5kIFN0dWRpbxUAAABBUlRJU1Q9QWR2ZW50dXJlIExhbmQjAAAAVElUTEU9RW1wdHkgTG9vcCBGb3IgSlMgUGVyZm9ybWFuY2UBBXZvcmJpcxJCQ1YBAAABAAxSFCElGVNKYwiVUlIpBR1jUFtHHWPUOUYhZBBTiEkZpXtPKpVYSsgRUlgpRR1TTFNJlVKWKUUdYxRTSCFT1jFloXMUS4ZJCSVsTa50FkvomWOWMUYdY85aSp1j1jFFHWNSUkmhcxg6ZiVkFDpGxehifDA6laJCKL7H3lLpLYWKW4q91xpT6y2EGEtpwQhhc+211dxKasUYY4wxxsXiUyiC0JBVAAABAABABAFCQ1YBAAoAAMJQDEVRgNCQVQBABgCAABRFcRTHcRxHkiTLAkJDVgEAQAAAAgAAKI7hKJIjSZJkWZZlWZameZaouaov+64u667t6roOhIasBADIAAAYhiGH3knMkFOQSSYpVcw5CKH1DjnlFGTSUsaYYoxRzpBTDDEFMYbQKYUQ1E45pQwiCENInWTOIEs96OBi5zgQGrIiAIgCAACMQYwhxpBzDEoGIXKOScggRM45KZ2UTEoorbSWSQktldYi55yUTkompbQWUsuklNZCKwUAAAQ4AAAEWAiFhqwIAKIAABCDkFJIKcSUYk4xh5RSjinHkFLMOcWYcowx6CBUzDHIHIRIKcUYc0455iBkDCrmHIQMMgEAAAEOAAABFkKhISsCgDgBAIMkaZqlaaJoaZooeqaoqqIoqqrleabpmaaqeqKpqqaquq6pqq5seZ5peqaoqp4pqqqpqq5rqqrriqpqy6ar2rbpqrbsyrJuu7Ks256qyrapurJuqq5tu7Js664s27rkearqmabreqbpuqrr2rLqurLtmabriqor26bryrLryratyrKua6bpuqKr2q6purLtyq5tu7Ks+6br6rbqyrquyrLu27au+7KtC7vourauyq6uq7Ks67It67Zs20LJ81TVM03X9UzTdVXXtW3VdW1bM03XNV1XlkXVdWXVlXVddWVb90zTdU1XlWXTVWVZlWXddmVXl0XXtW1Vln1ddWVfl23d92VZ133TdXVblWXbV2VZ92Vd94VZt33dU1VbN11X103X1X1b131htm3fF11X11XZ1oVVlnXf1n1lmHWdMLqurqu27OuqLOu+ruvGMOu6MKy6bfyurQvDq+vGseu+rty+j2rbvvDqtjG8um4cu7Abv+37xrGpqm2brqvrpivrumzrvm/runGMrqvrqiz7uurKvm/ruvDrvi8Mo+vquirLurDasq/Lui4Mu64bw2rbwu7aunDMsi4Mt+8rx68LQ9W2heHVdaOr28ZvC8PSN3a+AACAAQcAgAATykChISsCgDgBAAYhCBVjECrGIIQQUgohpFQxBiFjDkrGHJQQSkkhlNIqxiBkjknIHJMQSmiplNBKKKWlUEpLoZTWUmotptRaDKG0FEpprZTSWmopttRSbBVjEDLnpGSOSSiltFZKaSlzTErGoKQOQiqlpNJKSa1lzknJoKPSOUippNJSSam1UEproZTWSkqxpdJKba3FGkppLaTSWkmptdRSba21WiPGIGSMQcmck1JKSamU0lrmnJQOOiqZg5JKKamVklKsmJPSQSglg4xKSaW1kkoroZTWSkqxhVJaa63VmFJLNZSSWkmpxVBKa621GlMrNYVQUgultBZKaa21VmtqLbZQQmuhpBZLKjG1FmNtrcUYSmmtpBJbKanFFluNrbVYU0s1lpJibK3V2EotOdZaa0ot1tJSjK21mFtMucVYaw0ltBZKaa2U0lpKrcXWWq2hlNZKKrGVklpsrdXYWow1lNJiKSm1kEpsrbVYW2w1ppZibLHVWFKLMcZYc0u11ZRai621WEsrNcYYa2415VIAAMCAAwBAgAlloNCQlQBAFAAAYAxjjEFoFHLMOSmNUs45JyVzDkIIKWXOQQghpc45CKW01DkHoZSUQikppRRbKCWl1losAACgwAEAIMAGTYnFAQoNWQkARAEAIMYoxRiExiClGIPQGKMUYxAqpRhzDkKlFGPOQcgYc85BKRljzkEnJYQQQimlhBBCKKWUAgAAChwAAAJs0JRYHKDQkBUBQBQAAGAMYgwxhiB0UjopEYRMSielkRJaCylllkqKJcbMWomtxNhICa2F1jJrJcbSYkatxFhiKgAA7MABAOzAQig0ZCUAkAcAQBijFGPOOWcQYsw5CCE0CDHmHIQQKsaccw5CCBVjzjkHIYTOOecghBBC55xzEEIIoYMQQgillNJBCCGEUkrpIIQQQimldBBCCKGUUgoAACpwAAAIsFFkc4KRoEJDVgIAeQAAgDFKOSclpUYpxiCkFFujFGMQUmqtYgxCSq3FWDEGIaXWYuwgpNRajLV2EFJqLcZaQ0qtxVhrziGl1mKsNdfUWoy15tx7ai3GWnPOuQAA3AUHALADG0U2JxgJKjRkJQCQBwBAIKQUY4w5h5RijDHnnENKMcaYc84pxhhzzjnnFGOMOeecc4wx55xzzjnGmHPOOeecc84556CDkDnnnHPQQeicc845CCF0zjnnHIQQCgAAKnAAAAiwUWRzgpGgQkNWAgDhAACAMZRSSimllFJKqKOUUkoppZRSAiGllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimVUkoppZRSSimllFJKKaUAIN8KBwD/BxtnWEk6KxwNLjRkJQAQDgAAGMMYhIw5JyWlhjEIpXROSkklNYxBKKVzElJKKYPQWmqlpNJSShmElGILIZWUWgqltFZrKam1lFIoKcUaS0qppdYy5ySkklpLrbaYOQelpNZaaq3FEEJKsbXWUmuxdVJSSa211lptLaSUWmstxtZibCWlllprqcXWWkyptRZbSy3G1mJLrcXYYosxxhoLAOBucACASLBxhpWks8LR4EJDVgIAIQEABDJKOeecgxBCCCFSijHnoIMQQgghREox5pyDEEIIIYSMMecghBBCCKGUkDHmHIQQQgghhFI65yCEUEoJpZRSSucchBBCCKWUUkoJIYQQQiillFJKKSGEEEoppZRSSiklhBBCKKWUUkoppYQQQiillFJKKaWUEEIopZRSSimllBJC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', audioPlayer = new Audio(audiofile); _w.top.backNow = 0; audioPlayer.loop = true; _w.audioPlayer = audioPlayer; setInterval(function () { try { _w.jQuery.fn.viewer.Constructor.prototype.show = () => { }; } catch (e) { } }, 1000); try { _w.unrivalScriptList.push('Fuck me please'); } catch (e) { _w.unrivalScriptList = ['Fuck me please']; } function checkOffline() { let dleft = _d.getElementsByClassName('left'); if (dleft.length == 1) { let img = dleft[0].getElementsByTagName('img'); if (img.length == 1) { if (img[0].src.indexOf('loading.gif') != -1) { return true; } } } return false; } setInterval(function () { if (checkOffline()) { setTimeout(function () { if (checkOffline()) { _l.reload(); } }, 10000) } }, 3000); _d.addEventListener('visibilitychange', function () { var c = 0; if (_w.top.backNow == 0) { _d.title = '⚠️请先激活挂机'; return } else { _d.title = '学生学习页面'; } if (_d.hidden) { audioPlayer.play(); var timer = setInterval(function () { if (c) { _d.title = '挂机中'; c = 0; } else { _d.title = '挂机中'; c = 1; } if (!_d.hidden) { clearInterval(timer); _d.title = '学生学习页面'; } }, 1300); } else { audioPlayer.pause(); } }); _w.unrivalgetTeacherAjax = _w.getTeacherAjax; _w.getTeacherAjax = (courseid, classid, cid) => { if (cid == getQueryVariable('chapterId')) { return; } _w.top.unrivalPageRd = ''; _w.unrivalgetTeacherAjax(courseid, classid, cid); } if (disableMonitor == 1) { _w.appendChild = _w.Element.prototype.appendChild; _w.Element.prototype.appendChild = function () { try { if (arguments[0].src.indexOf('detect.chaoxing.com') > 0) { return; } } catch (e) { } _w.appendChild.apply(this, arguments); }; } _w.jump = false; setInterval(function () { if (getQueryVariable('mooc2') == '1') { let tabs = _d.getElementsByClassName('posCatalog_select'); for (let i = 0, l = tabs.length; i < l; i++) { let tabId = tabs[i].getAttribute('id'); if (tabId.indexOf('cur') >= 0 && tabs[i].getAttribute('class') == 'posCatalog_select') { tabs[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + tabId.replace('cur', '') + "');"); } } } else { let h4s = _d.getElementsByTagName('h4'), h5s = _d.getElementsByTagName('h5'); for (let i = 0, l = h4s.length; i < l; i++) { if (h4s[i].getAttribute('id').indexOf('cur') >= 0) { h4s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + h4s[i].getAttribute('id').replace('cur', '') + "');"); } } for (let i = 0, l = h5s.length; i < l; i++) { if (h5s[i].getAttribute('id').indexOf('cur') >= 0) { h5s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + h5s[i].getAttribute('id').replace('cur', '') + "');"); } } } }, 1000); setInterval(function () { let but = null; if (_w.jump) { _w.jump = false; _w.top.unrivalDoneWorkId = ''; _w.jjump = (rd) => { if (rd != _w.top.unrivalPageRd) { return; } try { setTimeout(function () { if (jumpType == 1) { if (getQueryVariable('mooc2') == '1') { but = _d.getElementsByClassName( 'jb_btn jb_btn_92 fs14 prev_next next'); } else { but = _d.getElementsByClassName('orientationright'); } try { setTimeout(function () { if (rd != _w.top.unrivalPageRd) { return; } but[0].click(); }, 2000); } catch (e) { } return; } if (getQueryVariable('mooc2') == '1') { let ul = _d.getElementsByClassName('prev_ul')[0], lis = ul.getElementsByTagName('li'); for (let i = 0, l = lis.length; i < l; i++) { if (lis[i].getAttribute('class') == 'active') { if (i + 1 >= l) { break; } else { try { lis[i + 1].click(); } catch (e) { } return; } } } let tabs = _d.getElementsByClassName('posCatalog_select'); for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].getAttribute('class') == 'posCatalog_select posCatalog_active') { while (i + 1 < tabs.length) { let nextTab = tabs[i + 1]; if ((nextTab.innerHTML.includes( 'icon_Completed prevTips') && _w.top .unrivalReviewMode == '0') || nextTab .innerHTML.includes( 'catalog_points_er prevTips')) { i++; continue; } if (nextTab.id.indexOf('cur') < 0) { i++; continue; } let clickF = setInterval(function () { if (rd != _w.top.unrivalPageRd) { clearInterval(clickF); return; } nextTab.click(); }, 2000); break; } break; } } } else { let div = _d.getElementsByClassName('tabtags')[0], spans = div.getElementsByTagName('span'); for (let i = 0, l = spans.length; i < l; i++) { if (spans[i].getAttribute('class').indexOf('currents') >= 0) { if (i + 1 == l) { break; } else { try { spans[i + 1].click(); } catch (e) { } return; } } } let tabs = _d.getElementsByTagName('span'), newTabs = []; for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].getAttribute('style') != null && tabs[i] .getAttribute('style').indexOf( 'cursor:pointer;height:18px;') >= 0) { newTabs.push(tabs[i]); } } tabs = newTabs; for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].parentNode.getAttribute('class') == 'currents') { while (i + 1 < tabs.length) { let nextTab = tabs[i + 1].parentNode; if ((nextTab.innerHTML.includes( 'roundpoint blue') && _w.top .unrivalReviewMode == '0') || nextTab .innerHTML.includes('roundpointStudent lock') ) { i++; continue; } if (nextTab.id.indexOf('cur') < 0) { i++; continue; } let clickF = setInterval(function () { if (rd != _w.top.unrivalPageRd) { clearInterval(clickF); return; } nextTab.click(); }, 2000); break; } break; } } } }, 2000); } catch (e) { } } _w.onReadComplete1(); setTimeout('jjump("' + _w.top.unrivalPageRd + '")', 2856); } }, 200); } else if (_l.href.indexOf("work/phone/doHomeWork") > 0) { var wIdE = _d.getElementById('workLibraryId') || _d.getElementById('oldWorkId'), wid = wIdE.value; _w.top.unrivalWorkDone = false; _w.aalert = _w.alert; _w.alert = (msg) => { if (msg == '保存成功') { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); return; } aalert(msg); } if (_w.top.unrivalDoneWorkId == getQueryVariable('workId')) { _w.top.unrivalWorkDone = true; return; } _w.confirm = (msg) => { return true; } var questionList = [], questionsElement = _d.getElementsByClassName('Py-mian1'), questionNum = questionsElement.length, totalQuestionNum = questionNum; for (let i = 0; i < questionNum; i++) { let questionElement = questionsElement[i], idElements = questionElement.getElementsByTagName('input'), questionId = '0', question = questionElement.getElementsByClassName('Py-m1-title fs16')[0].innerHTML; question = handleImgs(question).replace(/(<([^>]+)>)/ig, '').replace(/[0-9]{1,3}.\[(.*?)\]/ig, '').replaceAll('\n', '').replace(/^\s+/ig, '').replace(/\s+$/ig, ''); for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name').indexOf('answer') >= 0) { questionId = idElements[z].getAttribute('name').replace('type', ''); break; } } catch (e) { console.log(e); continue; } } if (questionId == '0' || question == '') { continue; } typeE = questionElement.getElementsByTagName('input'); if (typeE == null || typeE == []) { continue; } let typeN = 'fuckme'; for (let g = 0, h = typeE.length; g < h; g++) { if (typeE[g].id == 'answertype' + questionId.replace('answer', '').replace('check', '')) { typeN = typeE[g].value; break; } } if (['0', '1', '3'].indexOf(typeN) < 0) { continue; } type = { '0': '单选题', '1': '多选题', '3': '判断题' }[typeN]; let optionList = { length: 0 }; if (['单选题', '多选题'].indexOf(type) >= 0) { let answersElements = questionElement.getElementsByClassName('answerList')[0].getElementsByTagName( 'li'); for (let x = 0, j = answersElements.length; x < j; x++) { let optionE = answersElements[x], optionTextE = trim(optionE.innerHTML.replace(/(^\s*)|(\s*$)/g, "")), optionText = optionTextE.slice(1).replace(/(^\s*)|(\s*$)/g, ""), optionValue = optionTextE.slice(0, 1), optionId = optionE.getAttribute('id-param'); if (optionText == '') { break; } optionList[optionText] = { 'id': optionId, 'value': optionValue } optionList.length++; } if (answersElements.length != optionList.length) { continue; } } questionList.push({ 'question': question, 'type': type, 'questionid': questionId, 'options': optionList }); } var qu = null, nowTime = -4000, busyThread = questionList.length, ctOnload = function (res, quu) { busyThread -= 1; var ctResult = { 'code': -1, 'finalUrl': '', 'data': '未找到答案' }; if (res) { try { var responseText = res.responseText, ctResult = JSON.parse(responseText); } catch (e) { console.log(e); if (res.finalUrl.includes('getAnswer.php')) { _w.top.unrivalWorkInfo = '查题错误,服务器连接失败'; return; } } } try { let choiceEs = _d.getElementsByTagName('li'); if (ctResult['code'] == -1 ) { try { if (ctResult['msg'] !== undefined) { _w.top.unrivalWorkInfo = ctResult['msg'] ; } } catch (e) { } busyThread += 1; GM_xmlhttpRequest({ method: "GET", headers: { 'Authorization': token, }, timeout: 6000, url: host + 'chaoXing/v3/getAnswer.php?tm=' + encodeURIComponent(quu['question'] .replace(/(^\s*)|(\s*$)/g, '')) + '&type=' + { '单选题': '0', '多选题': '1', '判断题': '3' }[quu['type']] + '&wid=' + wid + '&courseid=' + courseId, onload: function (res) { ctOnload(res, quu); }, onerror: function (err) { _w.top.unrivalWorkInfo = '查题错误,服务器连接失败'; console.log(err); busyThread -= 1; }, ontimeout: function (err) { _w.top.unrivalWorkInfo = '查题错误,服务器连接失败'; console.log(err); busyThread -= 1; } }); return; } try { var result = ctResult['data']; } catch (e) { _w.top.unrivalWorkInfo = '答案解析失败'; return; } _w.top.unrivalWorkInfo = '题目:' + quu['question'] + ':' + result; switch (quu['type']) { case '判断题': (function () { let answer = 'abaabaaba'; if ('正确是对√Tri'.indexOf(result) >= 0) { answer = 'true'; } else if ('错误否错×Fwr'.indexOf(result) >= 0) { answer = 'false'; } for (let u = 0, k = choiceEs.length; u < k; u++) { if (choiceEs[u].getAttribute('val-param') == answer && choiceEs[u].getAttribute( 'id-param') == quu['questionid'].replace( 'answer', '')) { choiceEs[u].click(); questionNum -= 1; return; } } if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + ':未找到正确答案,自动选【错】'; for (let u = 0, k = choiceEs.length; u < k; u++) { if (choiceEs[u].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[u].getAttribute('val-param') == 'false' && choiceEs[u].getAttribute( 'id-param') == quu['questionid'] .replace('answer', '')) { choiceEs[u].click(); return; } } } })(); break; case '单选题': (function () { let answerData = result; for (let option in quu['options']) { if (trim(option).replace(/\s/ig, '') == trim(answerData).replace(/\s/ig, '') || trim( option).replace(/\s/ig, '').includes(trim(answerData).replace(/\s/ig, '')) || trim(answerData).replace(/\s/ig, '').includes(trim(option).replace(/\s/ig, ''))) { for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName( 'em').length < 1) { continue; } if (choiceEs[y].getElementsByTagName( 'em')[0].getAttribute( 'id-param') == quu['options'][ option ]['value'] && choiceEs[y] .getAttribute('id-param') == quu[ 'questionid'].replace('answer', '')) { if (!choiceEs[y].getAttribute( 'class').includes('cur')) { choiceEs[y].click(); } questionNum -= 1; return; } } } } if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + ':未找到正确答案,自动选【B】'; for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[y].getElementsByTagName('em')[ 0].getAttribute('id-param') == 'B' && choiceEs[y].getAttribute( 'id-param') == quu['questionid'] .replace('answer', '')) { if (!choiceEs[y].getAttribute('class') .includes('cur')) { choiceEs[y].click(); } return; } } } })(); break; case '多选题': (function () { let answerData = trim(result).replace(/\s/ig, ''), hasAnswer = false; for (let option in quu['options']) { if (answerData.includes(trim(option).replace(/\s/ig, ''))) { for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName( 'em').length < 1) { continue; } if (choiceEs[y].getElementsByTagName( 'em')[0].getAttribute( 'id-param') == quu['options'][ option ]['value'] && choiceEs[y] .getAttribute('id-param') == quu[ 'questionid'].replace('answer', '')) { if (!choiceEs[y].getAttribute( 'class').includes('cur')) { choiceEs[y].click(); } hasAnswer = true; break; } } } } if (hasAnswer) { questionNum -= 1; } else if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + ':未找到正确答案,自动全选'; for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[y].getAttribute('id-param') == quu['questionid'].replace('answer', '') ) { if (!choiceEs[y].getAttribute('class') .includes('cur')) { choiceEs[y].click(); } } } } })(); break; } } catch (e) { console.log(e); } } for (let i = 0, l = questionList.length; i < l; i++) { nowTime += parseInt(Math.random() * 2000 + 2500, 10); setTimeout(function () { qu = questionList[i]; let param = 'question=' + encodeURIComponent( qu['question']); if (ctUrl.includes('icodef')) { param += '&type=' + { '单选题': '0', '多选题': '1', '判断题': '3' }[qu['type']] + '&id=' + wid; } GM_xmlhttpRequest({ method: "POST", headers: { 'Content-type': 'application/x-www-form-urlencoded', 'Authorization': token, }, url: ctUrl, timeout: 2000, data: param, onload: function (res) { ctOnload(res, qu); }, onerror: function () { ctOnload(false, qu); }, ontimeout: function () { ctOnload(false, qu); } }); }, nowTime); } var workInterval = setInterval(function () { if (busyThread != 0) { return; } clearInterval(workInterval); if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) * 100 >= accuracy && _w.top .unrivalAutoSubmit == '1') { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); _w.top.unrivalWorkInfo = '通过率符合标准,已提交答案'; setTimeout(function () { submitCheckTimes(); escapeBlank() submitAction() // setTimeout(function() { // document.querySelector(".cx_alert-blue").click() // }, parseInt(1000)); }, parseInt(Math.random() * 2000 + 3000, 10)); } else if (_w.top.unrivalAutoSave == 1) { _w.top.unrivalWorkInfo = '正确率不符合通过率或未设置自动提交,已自动保存答案'; if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) >= 0) { setTimeout(function () { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); _w.noSubmit(); }, 2000); } } else { _w.top.unrivalWorkInfo = '用户设置为不自动保存答案,请手动提交或保存作业'; } }, 1000); } else if (_l.href.includes('work/phone/selectWorkQuestionYiPiYue')) { _w.top.unrivalWorkDone = true; _w.top.unrivalDoneWorkId = getQueryVariable('workId'); } else if (_l.href.includes('stat2-ans.chaoxing.com/task/s/index')) { if (_w.top == _w) { return; } _d.getElementsByClassName('page-container studentStatistic')[0].setAttribute('class', 'studentStatistic'); _d.getElementsByClassName('page-item item-task-list minHeight390')[0].remove(); _d.getElementsByClassName('subNav clearfix')[0].remove(); setInterval(function () { _l.reload(); }, 90000); } else if (_l.href.includes('passport2.') && _l.href.includes('login?refer=http') && autoLogin == 1) { if (!(/^1[3456789]\d{9}$/.test(phoneNumber))) { alert('自动登录的手机号填写错误,无法登陆') return; } if (password == '') { alert('未填写登录密码,无法登陆') return; } GM_xmlhttpRequest({ method: "get", url: 'https://passport2-api.chaoxing.com/v11/loginregister?cx_xxt_passport=json&uname=' + phoneNumber + '&code=' + encodeURIComponent(password), onload: function (res) { try { let ispass = JSON.parse(res.responseText); if (ispass['status']) { _l.href = decodeURIComponent(getQueryVariable('refer')); } else { alert(ispass['mes']); } } catch (err) { console.log(res.responseText); alert('登陆失败'); } }, onerror: function (err) { alert('登陆错误'); } }); } else if (_l.href.includes('unrivalxxtbackground')) { _d.getElementsByTagName("html")[0].innerHTML = ` 学习通挂机小助手

学习通挂机小助手 


任务列表
运行日志
`; var logs = { "logArry": [], "addLog": function (str, color = "black") { if (this.logArry.length >= 50) { this.logArry.splice(0, 1); } var nowTime = new Date(), nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2), nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2), nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2), logElement = _d.getElementById('log'), logStr = ""; this.logArry.push("[" + nowHour + ":" + nowMin + ":" + nowSec + "] " + str + ""); for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) { logStr += this.logArry[logI] + "
"; } _d.getElementById('log').innerHTML = logStr; logElement.scrollTop = logElement.scrollHeight; } }; logs.addLog('此页面不必保持在最前端,后台会自动进行任务', 'green'); setInterval(function () { logs.addLog('此页面不必保持在最前端,后台会自动进行任务', 'green'); logs.addLog('如想禁用后台刷视频功能,请关闭脚本并重启浏览器', 'blue'); }, 120000) GM_addValueChangeListener('unrivalxxtbackgroundinfo', function (name, old_value, new_value, remote) { if (old_value != new_value) { logs.addLog(new_value); } }); setInterval(function () { if (Math.round(new Date() / 1000) - parseInt(GM_getValue('unrivalBackgroundVideoEnable', '6')) > 15) { logs.addLog('超星挂机小助手可能运行异常,如页面无反应,请尝试重启脚本猫或重启浏览器(脚本猫0.9.0版本有此问题)'); } }, 10000); var loopShow = () => { let jobList = GM_getValue('unrivalBackgroundList', '1'); if (jobList == '1') { _d.getElementById('joblist').innerHTML = '请将“超星挂机小助手”升级到最新版并重启浏览器'; } else { try { let jobHtml = ''; for (let i = 0, l = jobList.length; i < l; i++) { let status = ''; if (jobList[i]['done']) { status = '已完成'; } else if (parseInt(jobList[i]['playTime']) > 0) { status = '进行中'; } else { status = '等待中'; } if (jobList[i]['review']) { status += ':复习模式'; } jobHtml += `
` + '[' + status + ']' + jobList[i]['name'] + `
` } _d.getElementById('joblist').innerHTML = jobHtml; } catch (e) { _d.getElementById('joblist').innerHTML = '请将“超星挂机小助手”升级到最新版并重启浏览器!'; } } } loopShow(); setInterval(loopShow, 10000); } })();