// ==UserScript== // @name 自动答题脚本(全平台) // @version 1.0.2 // @namespace 自动答题 // @description 支持【超星学习通】【智慧树】【职教云系列】【雨课堂】【考试星】【168网校】【继续教育类】【绎通云课堂】【九江系列】【柠檬文才】【亿学宝云】【优课学堂】【小鹅通】【安徽继续教育】 【上海开放大学】 【华侨大学自考网络助学平台】【良师在线】【和学在线】【人卫慕课】【国家开放大学】【山财培训网(继续教育)】【浙江省高等学校在线开放课程共享平台】【国地质大学远程与继续教育学院】【重庆大学网络教育学院】【浙江省高等教育自学考试网络助学平台】 【湖南高等学历继续教育】 【优学院】 【学起系列】【青书学堂】 【学堂在线】【英华学堂】【广开网络教学平台】等平台的测验考试,内置题库,自动答题功能全聚合 // @author 全平台万能答题脚本改版 // @match *://*/* // @icon data:image/jpeg;base64,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 // @compatible chrome firefox edge // @grant GM_info // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_setValue // @grant GM_getValue // @grant GM_getResourceURL // @run-at document-start // @connect yuketang.cn // @connect ykt.io // @connect localhost // @connect baidu.com // @connect cx.icodef.com // @connect zhaojiaoben.cn // @connect scriptcat.org // @connect gitee.com // @connect greasyfork.org // @resource 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 * // @connect greasyfork.org // ==/UserScript== //全局配置参数 var GLOBAL = { //延迟加载,页面初始化完毕之后的等待1s之后再去搜题(防止页面未初始化完成,如果页面加载比较慢,可以调高该值) delay: 2e3, //填充答案的延迟,不建议小于0.5秒,默认0.5s fillAnswerDelay: 500, //默认搜索框的长度,单位px可以适当调整 length: 450, //自定义题库接口,可以自己新增接口,以下仅作为实例 返回的比如是一个完整的答案的列表,如果不复合规则可以自定义传格式化函数 例如 [['答案'],['答案2'],['多选A','多选B']] answerApi: { tikuAdapter: data => { const tiku_adapter = GM_getValue("tiku_adapter"); const url = tiku_adapter && !tiku_adapter.includes("undefined") ? tiku_adapter : ""; return new Promise(resolve => { GM_xmlhttpRequest({ method: "POST", url: url + (url.includes("?") ? "&" : "?") + "wannengDisable=1", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify({ question: data.question, options: data.options, type: data.type }), onload: function (r) { try { const res = JSON.parse(r.responseText); resolve(res.answer.allAnswer); } catch (e) { resolve([]); } }, onerror: function (e) { console.log(e); resolve([]); } }); }); } } }; (function () { "use strict"; const HTTP_STATUS = { 403: "请不要挂梯子或使用任何网络代理工具", 444: "您请求速率过大,IP已经被封禁,请等待片刻或者更换IP", 415: "请不要使用手机运行此脚本,否则可能出现异常", 429: "卡了,你等下别急,在搜索中,一直卡顿那就刷新页面重新打开", 500: "服务器发生预料之外的错误", 502: "运维哥哥正在火速部署服务器,请稍等片刻,1分钟内恢复正常", 503: "搜题服务不可见,请稍等片刻,1分钟内恢复正常", 504: "系统超时" }; const instance = axios.create({ baseURL: "https://lyck6.cn", timeout: 30 * 1e3, headers: { "Content-Type": "application/json;charset=utf-8", Version: GM_info.script.version }, validateStatus: function (status) { return status === 200; } }); instance.interceptors.response.use(response => { return response.data; }, error => { try { const code = error.response.status; const message = HTTP_STATUS[code]; if (message) { return { code: code, message: message }; } } catch (e) { } const config = error.config; return new Promise(resolve => { GM_xmlhttpRequest({ method: config.method, url: config.baseURL + config.url, headers: config.headers, data: config.data, timeout: config.timeout, onload: function (r) { if (r.status === 200) { try { resolve(JSON.parse(r.responseText)); } catch (e) { resolve(r.responseText); } } else { resolve({ code: r.status, message: HTTP_STATUS[r.status] || "错误码:" + r.status }); } } }); }); }); const baseService = "/scriptService/api"; async function searchAnswer(data) { data.location = location.href; const token = GM_getValue("start_pay") ? GM_getValue("token") || 0 : 0; const uri = token.length === 10 ? "/autoAnswer/" + token + "?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, "data:image/jpeg;base64,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"); 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 = ["广州华夏职业学院"]; 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: "别乱点乱输入" }); } } 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: "别乱点乱输入" }); } else { iframeMsg("tip", { tip: "别乱点乱输入" }); } } 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('