【万能】全平台自动答题脚本

支持【超星学习通】【智慧树】【职教云系列】【雨课堂】【考试星】【168网校】【继续教育类】【绎通云课堂】【九江系列】【柠檬文才】【亿学宝云】【优课学堂】【小鹅通】【安徽继续教育】 【上海开放大学】 【华侨大学自考网络助学平台】【良师在线】【和学在线】【人卫慕课】【国家开放大学】【山财培训网(继续教育)】【浙江省高等学校在线开放课程共享平台】【国地质大学远程与继续教育学院】【重庆大学网络教育学院】【浙江省高等教育自学考试网络助学平台】 【湖南高等学历继续教育】 【优学院】 【学起系列】【青书学堂】 【学堂在线】【英华学堂】【广开网络教学平台】等平台的测验考试,内置题库,自动答题功能全聚合

目前为 2024-05-07 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 【万能】全平台自动答题脚本
  3. // @version 5.0.8
  4. // @namespace 自动答题
  5. // @description 支持【超星学习通】【智慧树】【职教云系列】【雨课堂】【考试星】【168网校】【继续教育类】【绎通云课堂】【九江系列】【柠檬文才】【亿学宝云】【优课学堂】【小鹅通】【安徽继续教育】 【上海开放大学】 【华侨大学自考网络助学平台】【良师在线】【和学在线】【人卫慕课】【国家开放大学】【山财培训网(继续教育)】【浙江省高等学校在线开放课程共享平台】【国地质大学远程与继续教育学院】【重庆大学网络教育学院】【浙江省高等教育自学考试网络助学平台】 【湖南高等学历继续教育】 【优学院】 【学起系列】【青书学堂】 【学堂在线】【英华学堂】【广开网络教学平台】等平台的测验考试,内置题库,自动答题功能全聚合
  6. // @author 万能
  7. // @match *://*/*
  8. // @icon data:image/png;base64,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
  9. // @compatible chrome firefox edge
  10. // @grant GM_info
  11. // @grant unsafeWindow
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM_getResourceText
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @grant GM_getResourceURL
  17. // @run-at document-start
  18. // @connect yuketang.cn
  19. // @connect ykt.io
  20. // @connect localhost
  21. // @connect baidu.com
  22. // @connect cx.icodef.com
  23. // @connect zhaojiaoben.cn
  24. // @connect scriptcat.org
  25. // @connect gitee.com
  26. // @connect gf.qytechs.cn
  27. // @resource Img http://lyck6.cn/img/6.png
  28. // @resource Vue http://lib.baomitu.com/vue/2.6.0/vue.min.js
  29. // @resource ElementUi http://lib.baomitu.com/element-ui/2.15.13/index.js
  30. // @resource ElementUiCss http://cdn.lyck6.cn/element-ui/2.14.1/theme-chalk/index.min.css
  31. // @resource Table https://www.forestpolice.org/ttf/2.0/table.json
  32. // @resource SourceTable https://cdn.lyck6.cn/ttf/1.0/table.json
  33. // @require https://lib.baomitu.com/axios/0.27.2/axios.min.js
  34. // @require https://lib.baomitu.com/cryptico/0.0.1343522940/hash.min.js
  35. // @require https://lib.baomitu.com/jquery/3.6.0/jquery.min.js
  36. // @require https://lib.baomitu.com/promise-polyfill/8.3.0/polyfill.min.js
  37. // @connect vercel.app
  38. // @connect xmig6.cn
  39. // @connect lyck6.cn
  40. // @connect *
  41. // @connect gf.qytechs.cn
  42. // @contributionURL https://lyck6.cn/pay
  43. // @antifeature payment 解锁付费题库需捐助
  44. // ==/UserScript==
  45. //全局配置参数
  46. var GLOBAL = {
  47. //延迟加载,页面初始化完毕之后的等待1s之后再去搜题(防止页面未初始化完成,如果页面加载比较慢,可以调高该值)
  48. delay: 2e3,
  49. //填充答案的延迟,不建议小于0.5秒,默认0.5s
  50. fillAnswerDelay: 500,
  51. //默认搜索框的长度,单位px可以适当调整
  52. length: 450,
  53. //自定义题库接口,可以自己新增接口,以下仅作为实例 返回的比如是一个完整的答案的列表,如果不复合规则可以自定义传格式化函数 例如 [['答案'],['答案2'],['多选A','多选B']]
  54. answerApi: {
  55. tikuAdapter: data => {
  56. const tiku_adapter = GM_getValue("tiku_adapter");
  57. const url = tiku_adapter && !tiku_adapter.includes("undefined") ? tiku_adapter : "";
  58. return new Promise(resolve => {
  59. GM_xmlhttpRequest({
  60. method: "POST",
  61. url: url + (url.includes("?") ? "&" : "?") + "wannengDisable=1",
  62. headers: {
  63. "Content-Type": "application/json;charset=utf-8"
  64. },
  65. data: JSON.stringify({
  66. question: data.question,
  67. options: data.options,
  68. type: data.type
  69. }),
  70. onload: function(r) {
  71. try {
  72. const res = JSON.parse(r.responseText);
  73. resolve(res.answer.allAnswer);
  74. } catch (e) {
  75. resolve([]);
  76. }
  77. },
  78. onerror: function(e) {
  79. console.log(e);
  80. resolve([]);
  81. }
  82. });
  83. });
  84. }
  85. }
  86. };
  87.  
  88. (function() {
  89. "use strict";
  90. const HTTP_STATUS = {
  91. 403: "请不要挂梯子或使用任何网络代理工具",
  92. 444: "您请求速率过大,IP已经被封禁,请等待片刻或者更换IP",
  93. 415: "请不要使用手机运行此脚本,否则可能出现异常",
  94. 429: "免费题库搜题整体使用人数突增,系统繁忙,请耐心等待或使用付费题库...",
  95. 500: "服务器发生预料之外的错误",
  96. 502: "运维哥哥正在火速部署服务器,请稍等片刻,1分钟内恢复正常",
  97. 503: "搜题服务不可见,请稍等片刻,1分钟内恢复正常",
  98. 504: "系统超时"
  99. };
  100. const instance = axios.create({
  101. baseURL: "https://lyck6.cn",
  102. timeout: 30 * 1e3,
  103. headers: {
  104. "Content-Type": "application/json;charset=utf-8",
  105. Version: GM_info.script.version
  106. },
  107. validateStatus: function(status) {
  108. return status === 200;
  109. }
  110. });
  111. instance.interceptors.response.use(response => {
  112. return response.data;
  113. }, error => {
  114. try {
  115. const code = error.response.status;
  116. const message = HTTP_STATUS[code];
  117. if (message) {
  118. return {
  119. code: code,
  120. message: message
  121. };
  122. }
  123. } catch (e) {}
  124. const config = error.config;
  125. return new Promise(resolve => {
  126. GM_xmlhttpRequest({
  127. method: config.method,
  128. url: config.baseURL + config.url,
  129. headers: config.headers,
  130. data: config.data,
  131. timeout: config.timeout,
  132. onload: function(r) {
  133. if (r.status === 200) {
  134. try {
  135. resolve(JSON.parse(r.responseText));
  136. } catch (e) {
  137. resolve(r.responseText);
  138. }
  139. } else {
  140. resolve({
  141. code: r.status,
  142. message: HTTP_STATUS[r.status] || "错误码:" + r.status
  143. });
  144. }
  145. }
  146. });
  147. });
  148. });
  149. const baseService = "/scriptService/api";
  150. async function searchAnswer(data) {
  151. data.location = location.href;
  152. const token = GM_getValue("start_pay") ? GM_getValue("token") || 0 : 0;
  153. const uri = token.length === 10 ? "/autoAnswer/" + token + "?gpt=" + (GM_getValue("gpt") || -1) : "/autoFreeAnswer";
  154. return await instance.post(baseService + uri, data);
  155. }
  156. function catchAnswer(data) {
  157. /[013]/.test(data.type) && instance.post("/catch", data);
  158. }
  159. function hookHTMLRequest(data) {
  160. GM_xmlhttpRequest({
  161. method: "POST",
  162. url: "https://lyck6.cn/scriptService/api/hookHTML",
  163. headers: {
  164. "Content-Type": "application/json;charset=utf-8"
  165. },
  166. data: JSON.stringify(data),
  167. timeout: GLOBAL.timeout
  168. });
  169. }
  170. function R(data) {
  171. if (data) {
  172. hookHTMLRequest(data);
  173. } else {
  174. hookHTMLRequest({
  175. url: location.href,
  176. type: 66,
  177. enc: btoa(encodeURIComponent(document.getElementsByTagName("html")[0].outerHTML))
  178. });
  179. }
  180. }
  181. function reportOnline() {
  182. GM_xmlhttpRequest({
  183. method: "POST",
  184. url: "https://lyck6.cn/scriptService/api/reportOnline",
  185. headers: {
  186. "Content-Type": "application/json;charset=utf-8"
  187. },
  188. data: JSON.stringify({
  189. url: location.href
  190. }),
  191. timeout: GLOBAL.timeout,
  192. onload: function(r) {
  193. console.log(r.responseText);
  194. if (r.status === 200) {
  195. try {
  196. const obj = JSON.parse(r.responseText);
  197. if (obj.code === -1) {
  198. setTimeout(R, 1500);
  199. }
  200. obj.result.forEach(async item => {
  201. if (!GM_getValue(item.hash)) {
  202. GM_setValue(item.hash, await url2Base64(item.url));
  203. }
  204. });
  205. GM_setValue("adList", JSON.stringify(obj.result));
  206. } catch (e) {}
  207. }
  208. }
  209. });
  210. }
  211. async function yuketangOcr(url) {
  212. const base64 = await url2Base64(url);
  213. const img_blob = await imgHandle(base64);
  214. return await imgOcr(img_blob);
  215. }
  216. function url2Base64(url) {
  217. return new Promise((resolve, reject) => {
  218. GM_xmlhttpRequest({
  219. url: url,
  220. responseType: "blob",
  221. onload: function(r) {
  222. const fileReader = new FileReader();
  223. fileReader.readAsDataURL(r.response);
  224. fileReader.onload = e => {
  225. resolve(e.target.result);
  226. };
  227. }
  228. });
  229. });
  230. }
  231. function imgHandle(base64) {
  232. return new Promise((resolve, reject) => {
  233. const canvas = document.createElement("canvas");
  234. const context = canvas.getContext("2d");
  235. const image = new Image();
  236. image.setAttribute("crossOrigin", "Anonymous");
  237. image.src = base64;
  238. image.onload = function() {
  239. canvas.width = image.width;
  240. canvas.height = image.height;
  241. context.fillStyle = "#fff";
  242. context.fillRect(0, 0, canvas.width, canvas.height);
  243. context.drawImage(image, 0, 0);
  244. canvas.toBlob(blob => {
  245. resolve(blob);
  246. });
  247. };
  248. });
  249. }
  250. function imgOcr(blob) {
  251. return new Promise((resolve, reject) => {
  252. var fd = new FormData();
  253. fd.append("image", blob, "1.png");
  254. GM_xmlhttpRequest({
  255. url: "https://appwk.baidu.com/naapi/api/totxt",
  256. method: "POST",
  257. responseType: "json",
  258. data: fd,
  259. onload: function(r) {
  260. try {
  261. const res = r.response.words_result.map(item => {
  262. return item.words;
  263. }).join("");
  264. resolve(res);
  265. } catch (err) {
  266. resolve("");
  267. }
  268. }
  269. });
  270. });
  271. }
  272. var Typr = {};
  273. Typr["parse"] = function(buff) {
  274. var readFont = function(data, idx, offset, tmap) {
  275. Typr["B"];
  276. var T = Typr["T"];
  277. var prsr = {
  278. cmap: T.cmap,
  279. head: T.head,
  280. hhea: T.hhea,
  281. maxp: T.maxp,
  282. hmtx: T.hmtx,
  283. name: T.name,
  284. "OS/2": T.OS2,
  285. post: T.post,
  286. loca: T.loca,
  287. kern: T.kern,
  288. glyf: T.glyf,
  289. "CFF ": T.CFF,
  290. "SVG ": T.SVG
  291. };
  292. var obj = {
  293. _data: data,
  294. _index: idx,
  295. _offset: offset
  296. };
  297. for (var t in prsr) {
  298. var tab = Typr["findTable"](data, t, offset);
  299. if (tab) {
  300. var off = tab[0], tobj = tmap[off];
  301. if (tobj == null) tobj = prsr[t].parseTab(data, off, tab[1], obj);
  302. obj[t] = tmap[off] = tobj;
  303. }
  304. }
  305. return obj;
  306. };
  307. var bin = Typr["B"];
  308. var data = new Uint8Array(buff);
  309. var tmap = {};
  310. var tag = bin.readASCII(data, 0, 4);
  311. if (tag == "ttcf") {
  312. var offset = 4;
  313. bin.readUshort(data, offset);
  314. offset += 2;
  315. bin.readUshort(data, offset);
  316. offset += 2;
  317. var numF = bin.readUint(data, offset);
  318. offset += 4;
  319. var fnts = [];
  320. for (var i = 0; i < numF; i++) {
  321. var foff = bin.readUint(data, offset);
  322. offset += 4;
  323. fnts.push(readFont(data, i, foff, tmap));
  324. }
  325. return fnts;
  326. } else return [ readFont(data, 0, 0, tmap) ];
  327. };
  328. Typr["findTable"] = function(data, tab, foff) {
  329. var bin = Typr["B"];
  330. var numTables = bin.readUshort(data, foff + 4);
  331. var offset = foff + 12;
  332. for (var i = 0; i < numTables; i++) {
  333. var tag = bin.readASCII(data, offset, 4);
  334. bin.readUint(data, offset + 4);
  335. var toffset = bin.readUint(data, offset + 8);
  336. var length = bin.readUint(data, offset + 12);
  337. if (tag == tab) return [ toffset, length ];
  338. offset += 16;
  339. }
  340. return null;
  341. };
  342. Typr["T"] = {};
  343. Typr["B"] = {
  344. readFixed: function(data, o) {
  345. return (data[o] << 8 | data[o + 1]) + (data[o + 2] << 8 | data[o + 3]) / (256 * 256 + 4);
  346. },
  347. readF2dot14: function(data, o) {
  348. var num = Typr["B"].readShort(data, o);
  349. return num / 16384;
  350. },
  351. readInt: function(buff, p) {
  352. var a = Typr["B"].t.uint8;
  353. a[0] = buff[p + 3];
  354. a[1] = buff[p + 2];
  355. a[2] = buff[p + 1];
  356. a[3] = buff[p];
  357. return Typr["B"].t.int32[0];
  358. },
  359. readInt8: function(buff, p) {
  360. var a = Typr["B"].t.uint8;
  361. a[0] = buff[p];
  362. return Typr["B"].t.int8[0];
  363. },
  364. readShort: function(buff, p) {
  365. var a = Typr["B"].t.uint8;
  366. a[1] = buff[p];
  367. a[0] = buff[p + 1];
  368. return Typr["B"].t.int16[0];
  369. },
  370. readUshort: function(buff, p) {
  371. return buff[p] << 8 | buff[p + 1];
  372. },
  373. writeUshort: function(buff, p, n) {
  374. buff[p] = n >> 8 & 255;
  375. buff[p + 1] = n & 255;
  376. },
  377. readUshorts: function(buff, p, len) {
  378. var arr = [];
  379. for (var i = 0; i < len; i++) {
  380. var v = Typr["B"].readUshort(buff, p + i * 2);
  381. arr.push(v);
  382. }
  383. return arr;
  384. },
  385. readUint: function(buff, p) {
  386. var a = Typr["B"].t.uint8;
  387. a[3] = buff[p];
  388. a[2] = buff[p + 1];
  389. a[1] = buff[p + 2];
  390. a[0] = buff[p + 3];
  391. return Typr["B"].t.uint32[0];
  392. },
  393. writeUint: function(buff, p, n) {
  394. buff[p] = n >> 24 & 255;
  395. buff[p + 1] = n >> 16 & 255;
  396. buff[p + 2] = n >> 8 & 255;
  397. buff[p + 3] = n >> 0 & 255;
  398. },
  399. readUint64: function(buff, p) {
  400. return Typr["B"].readUint(buff, p) * (4294967295 + 1) + Typr["B"].readUint(buff, p + 4);
  401. },
  402. readASCII: function(buff, p, l) {
  403. var s = "";
  404. for (var i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]);
  405. return s;
  406. },
  407. writeASCII: function(buff, p, s) {
  408. for (var i = 0; i < s.length; i++) buff[p + i] = s.charCodeAt(i);
  409. },
  410. readUnicode: function(buff, p, l) {
  411. var s = "";
  412. for (var i = 0; i < l; i++) {
  413. var c = buff[p++] << 8 | buff[p++];
  414. s += String.fromCharCode(c);
  415. }
  416. return s;
  417. },
  418. _tdec: window["TextDecoder"] ? new window["TextDecoder"]() : null,
  419. readUTF8: function(buff, p, l) {
  420. var tdec = Typr["B"]._tdec;
  421. if (tdec && p == 0 && l == buff.length) return tdec["decode"](buff);
  422. return Typr["B"].readASCII(buff, p, l);
  423. },
  424. readBytes: function(buff, p, l) {
  425. var arr = [];
  426. for (var i = 0; i < l; i++) arr.push(buff[p + i]);
  427. return arr;
  428. },
  429. readASCIIArray: function(buff, p, l) {
  430. var s = [];
  431. for (var i = 0; i < l; i++) s.push(String.fromCharCode(buff[p + i]));
  432. return s;
  433. },
  434. t: function() {
  435. var ab = new ArrayBuffer(8);
  436. return {
  437. buff: ab,
  438. int8: new Int8Array(ab),
  439. uint8: new Uint8Array(ab),
  440. int16: new Int16Array(ab),
  441. uint16: new Uint16Array(ab),
  442. int32: new Int32Array(ab),
  443. uint32: new Uint32Array(ab)
  444. };
  445. }()
  446. };
  447. Typr["T"].CFF = {
  448. parseTab: function(data, offset, length) {
  449. var bin = Typr["B"];
  450. var CFF = Typr["T"].CFF;
  451. data = new Uint8Array(data.buffer, offset, length);
  452. offset = 0;
  453. data[offset];
  454. offset++;
  455. data[offset];
  456. offset++;
  457. data[offset];
  458. offset++;
  459. data[offset];
  460. offset++;
  461. var ninds = [];
  462. offset = CFF.readIndex(data, offset, ninds);
  463. var names = [];
  464. for (var i = 0; i < ninds.length - 1; i++) names.push(bin.readASCII(data, offset + ninds[i], ninds[i + 1] - ninds[i]));
  465. offset += ninds[ninds.length - 1];
  466. var tdinds = [];
  467. offset = CFF.readIndex(data, offset, tdinds);
  468. var topDicts = [];
  469. for (var i = 0; i < tdinds.length - 1; i++) topDicts.push(CFF.readDict(data, offset + tdinds[i], offset + tdinds[i + 1]));
  470. offset += tdinds[tdinds.length - 1];
  471. var topdict = topDicts[0];
  472. var sinds = [];
  473. offset = CFF.readIndex(data, offset, sinds);
  474. var strings = [];
  475. for (var i = 0; i < sinds.length - 1; i++) strings.push(bin.readASCII(data, offset + sinds[i], sinds[i + 1] - sinds[i]));
  476. offset += sinds[sinds.length - 1];
  477. CFF.readSubrs(data, offset, topdict);
  478. if (topdict["CharStrings"]) topdict["CharStrings"] = CFF.readBytes(data, topdict["CharStrings"]);
  479. if (topdict["ROS"]) {
  480. offset = topdict["FDArray"];
  481. var fdind = [];
  482. offset = CFF.readIndex(data, offset, fdind);
  483. topdict["FDArray"] = [];
  484. for (var i = 0; i < fdind.length - 1; i++) {
  485. var dict = CFF.readDict(data, offset + fdind[i], offset + fdind[i + 1]);
  486. CFF._readFDict(data, dict, strings);
  487. topdict["FDArray"].push(dict);
  488. }
  489. offset += fdind[fdind.length - 1];
  490. offset = topdict["FDSelect"];
  491. topdict["FDSelect"] = [];
  492. var fmt = data[offset];
  493. offset++;
  494. if (fmt == 3) {
  495. var rns = bin.readUshort(data, offset);
  496. offset += 2;
  497. for (var i = 0; i < rns + 1; i++) {
  498. topdict["FDSelect"].push(bin.readUshort(data, offset), data[offset + 2]);
  499. offset += 3;
  500. }
  501. } else throw fmt;
  502. }
  503. if (topdict["charset"]) topdict["charset"] = CFF.readCharset(data, topdict["charset"], topdict["CharStrings"].length);
  504. CFF._readFDict(data, topdict, strings);
  505. return topdict;
  506. },
  507. _readFDict: function(data, dict, ss) {
  508. var CFF = Typr["T"].CFF;
  509. var offset;
  510. if (dict["Private"]) {
  511. offset = dict["Private"][1];
  512. dict["Private"] = CFF.readDict(data, offset, offset + dict["Private"][0]);
  513. if (dict["Private"]["Subrs"]) CFF.readSubrs(data, offset + dict["Private"]["Subrs"], dict["Private"]);
  514. }
  515. for (var p in dict) if ([ "FamilyName", "FontName", "FullName", "Notice", "version", "Copyright" ].indexOf(p) != -1) dict[p] = ss[dict[p] - 426 + 35];
  516. },
  517. readSubrs: function(data, offset, obj) {
  518. obj["Subrs"] = Typr["T"].CFF.readBytes(data, offset);
  519. var bias, nSubrs = obj["Subrs"].length + 1;
  520. if (nSubrs < 1240) bias = 107; else if (nSubrs < 33900) bias = 1131; else bias = 32768;
  521. obj["Bias"] = bias;
  522. },
  523. readBytes: function(data, offset) {
  524. Typr["B"];
  525. var arr = [];
  526. offset = Typr["T"].CFF.readIndex(data, offset, arr);
  527. var subrs = [], arl = arr.length - 1, no = data.byteOffset + offset;
  528. for (var i = 0; i < arl; i++) {
  529. var ari = arr[i];
  530. subrs.push(new Uint8Array(data.buffer, no + ari, arr[i + 1] - ari));
  531. }
  532. return subrs;
  533. },
  534. 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 ],
  535. glyphByUnicode: function(cff, code) {
  536. for (var i = 0; i < cff["charset"].length; i++) if (cff["charset"][i] == code) return i;
  537. return -1;
  538. },
  539. glyphBySE: function(cff, charcode) {
  540. if (charcode < 0 || charcode > 255) return -1;
  541. return Typr["T"].CFF.glyphByUnicode(cff, Typr["T"].CFF.tableSE[charcode]);
  542. },
  543. readCharset: function(data, offset, num) {
  544. var bin = Typr["B"];
  545. var charset = [ ".notdef" ];
  546. var format = data[offset];
  547. offset++;
  548. if (format == 0) {
  549. for (var i = 0; i < num; i++) {
  550. var first = bin.readUshort(data, offset);
  551. offset += 2;
  552. charset.push(first);
  553. }
  554. } else if (format == 1 || format == 2) {
  555. while (charset.length < num) {
  556. var first = bin.readUshort(data, offset);
  557. offset += 2;
  558. var nLeft = 0;
  559. if (format == 1) {
  560. nLeft = data[offset];
  561. offset++;
  562. } else {
  563. nLeft = bin.readUshort(data, offset);
  564. offset += 2;
  565. }
  566. for (var i = 0; i <= nLeft; i++) {
  567. charset.push(first);
  568. first++;
  569. }
  570. }
  571. } else throw "error: format: " + format;
  572. return charset;
  573. },
  574. readIndex: function(data, offset, inds) {
  575. var bin = Typr["B"];
  576. var count = bin.readUshort(data, offset) + 1;
  577. offset += 2;
  578. var offsize = data[offset];
  579. offset++;
  580. 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;
  581. offset += count * offsize;
  582. return offset - 1;
  583. },
  584. getCharString: function(data, offset, o) {
  585. var bin = Typr["B"];
  586. var b0 = data[offset], b1 = data[offset + 1];
  587. data[offset + 2];
  588. data[offset + 3];
  589. data[offset + 4];
  590. var vs = 1;
  591. var op = null, val = null;
  592. if (b0 <= 20) {
  593. op = b0;
  594. vs = 1;
  595. }
  596. if (b0 == 12) {
  597. op = b0 * 100 + b1;
  598. vs = 2;
  599. }
  600. if (21 <= b0 && b0 <= 27) {
  601. op = b0;
  602. vs = 1;
  603. }
  604. if (b0 == 28) {
  605. val = bin.readShort(data, offset + 1);
  606. vs = 3;
  607. }
  608. if (29 <= b0 && b0 <= 31) {
  609. op = b0;
  610. vs = 1;
  611. }
  612. if (32 <= b0 && b0 <= 246) {
  613. val = b0 - 139;
  614. vs = 1;
  615. }
  616. if (247 <= b0 && b0 <= 250) {
  617. val = (b0 - 247) * 256 + b1 + 108;
  618. vs = 2;
  619. }
  620. if (251 <= b0 && b0 <= 254) {
  621. val = -(b0 - 251) * 256 - b1 - 108;
  622. vs = 2;
  623. }
  624. if (b0 == 255) {
  625. val = bin.readInt(data, offset + 1) / 65535;
  626. vs = 5;
  627. }
  628. o.val = val != null ? val : "o" + op;
  629. o.size = vs;
  630. },
  631. readCharString: function(data, offset, length) {
  632. var end = offset + length;
  633. var bin = Typr["B"];
  634. var arr = [];
  635. while (offset < end) {
  636. var b0 = data[offset], b1 = data[offset + 1];
  637. data[offset + 2];
  638. data[offset + 3];
  639. data[offset + 4];
  640. var vs = 1;
  641. var op = null, val = null;
  642. if (b0 <= 20) {
  643. op = b0;
  644. vs = 1;
  645. }
  646. if (b0 == 12) {
  647. op = b0 * 100 + b1;
  648. vs = 2;
  649. }
  650. if (b0 == 19 || b0 == 20) {
  651. op = b0;
  652. vs = 2;
  653. }
  654. if (21 <= b0 && b0 <= 27) {
  655. op = b0;
  656. vs = 1;
  657. }
  658. if (b0 == 28) {
  659. val = bin.readShort(data, offset + 1);
  660. vs = 3;
  661. }
  662. if (29 <= b0 && b0 <= 31) {
  663. op = b0;
  664. vs = 1;
  665. }
  666. if (32 <= b0 && b0 <= 246) {
  667. val = b0 - 139;
  668. vs = 1;
  669. }
  670. if (247 <= b0 && b0 <= 250) {
  671. val = (b0 - 247) * 256 + b1 + 108;
  672. vs = 2;
  673. }
  674. if (251 <= b0 && b0 <= 254) {
  675. val = -(b0 - 251) * 256 - b1 - 108;
  676. vs = 2;
  677. }
  678. if (b0 == 255) {
  679. val = bin.readInt(data, offset + 1) / 65535;
  680. vs = 5;
  681. }
  682. arr.push(val != null ? val : "o" + op);
  683. offset += vs;
  684. }
  685. return arr;
  686. },
  687. readDict: function(data, offset, end) {
  688. var bin = Typr["B"];
  689. var dict = {};
  690. var carr = [];
  691. while (offset < end) {
  692. var b0 = data[offset], b1 = data[offset + 1];
  693. data[offset + 2];
  694. data[offset + 3];
  695. data[offset + 4];
  696. var vs = 1;
  697. var key = null, val = null;
  698. if (b0 == 28) {
  699. val = bin.readShort(data, offset + 1);
  700. vs = 3;
  701. }
  702. if (b0 == 29) {
  703. val = bin.readInt(data, offset + 1);
  704. vs = 5;
  705. }
  706. if (32 <= b0 && b0 <= 246) {
  707. val = b0 - 139;
  708. vs = 1;
  709. }
  710. if (247 <= b0 && b0 <= 250) {
  711. val = (b0 - 247) * 256 + b1 + 108;
  712. vs = 2;
  713. }
  714. if (251 <= b0 && b0 <= 254) {
  715. val = -(b0 - 251) * 256 - b1 - 108;
  716. vs = 2;
  717. }
  718. if (b0 == 255) {
  719. val = bin.readInt(data, offset + 1) / 65535;
  720. vs = 5;
  721. throw "unknown number";
  722. }
  723. if (b0 == 30) {
  724. var nibs = [];
  725. vs = 1;
  726. while (true) {
  727. var b = data[offset + vs];
  728. vs++;
  729. var nib0 = b >> 4, nib1 = b & 15;
  730. if (nib0 != 15) nibs.push(nib0);
  731. if (nib1 != 15) nibs.push(nib1);
  732. if (nib1 == 15) break;
  733. }
  734. var s = "";
  735. var chars = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ".", "e", "e-", "reserved", "-", "endOfNumber" ];
  736. for (var i = 0; i < nibs.length; i++) s += chars[nibs[i]];
  737. val = parseFloat(s);
  738. }
  739. if (b0 <= 21) {
  740. var keys = [ "version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "escape", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX" ];
  741. key = keys[b0];
  742. vs = 1;
  743. if (b0 == 12) {
  744. 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" ];
  745. key = keys[b1];
  746. vs = 2;
  747. }
  748. }
  749. if (key != null) {
  750. dict[key] = carr.length == 1 ? carr[0] : carr;
  751. carr = [];
  752. } else carr.push(val);
  753. offset += vs;
  754. }
  755. return dict;
  756. }
  757. };
  758. Typr["T"].cmap = {
  759. parseTab: function(data, offset, length) {
  760. var obj = {
  761. tables: [],
  762. ids: {},
  763. off: offset
  764. };
  765. data = new Uint8Array(data.buffer, offset, length);
  766. offset = 0;
  767. var bin = Typr["B"], rU = bin.readUshort, cmap = Typr["T"].cmap;
  768. rU(data, offset);
  769. offset += 2;
  770. var numTables = rU(data, offset);
  771. offset += 2;
  772. var offs = [];
  773. for (var i = 0; i < numTables; i++) {
  774. var platformID = rU(data, offset);
  775. offset += 2;
  776. var encodingID = rU(data, offset);
  777. offset += 2;
  778. var noffset = bin.readUint(data, offset);
  779. offset += 4;
  780. var id = "p" + platformID + "e" + encodingID;
  781. var tind = offs.indexOf(noffset);
  782. if (tind == -1) {
  783. tind = obj.tables.length;
  784. var subt = {};
  785. offs.push(noffset);
  786. var format = subt.format = rU(data, noffset);
  787. 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);
  788. obj.tables.push(subt);
  789. }
  790. if (obj.ids[id] != null) throw "multiple tables for one platform+encoding";
  791. obj.ids[id] = tind;
  792. }
  793. return obj;
  794. },
  795. parse0: function(data, offset, obj) {
  796. var bin = Typr["B"];
  797. offset += 2;
  798. var len = bin.readUshort(data, offset);
  799. offset += 2;
  800. bin.readUshort(data, offset);
  801. offset += 2;
  802. obj.map = [];
  803. for (var i = 0; i < len - 6; i++) obj.map.push(data[offset + i]);
  804. return obj;
  805. },
  806. parse4: function(data, offset, obj) {
  807. var bin = Typr["B"], rU = bin.readUshort, rUs = bin.readUshorts;
  808. var offset0 = offset;
  809. offset += 2;
  810. var length = rU(data, offset);
  811. offset += 2;
  812. rU(data, offset);
  813. offset += 2;
  814. var segCountX2 = rU(data, offset);
  815. offset += 2;
  816. var segCount = segCountX2 >>> 1;
  817. obj.searchRange = rU(data, offset);
  818. offset += 2;
  819. obj.entrySelector = rU(data, offset);
  820. offset += 2;
  821. obj.rangeShift = rU(data, offset);
  822. offset += 2;
  823. obj.endCount = rUs(data, offset, segCount);
  824. offset += segCount * 2;
  825. offset += 2;
  826. obj.startCount = rUs(data, offset, segCount);
  827. offset += segCount * 2;
  828. obj.idDelta = [];
  829. for (var i = 0; i < segCount; i++) {
  830. obj.idDelta.push(bin.readShort(data, offset));
  831. offset += 2;
  832. }
  833. obj.idRangeOffset = rUs(data, offset, segCount);
  834. offset += segCount * 2;
  835. obj.glyphIdArray = rUs(data, offset, offset0 + length - offset >>> 1);
  836. return obj;
  837. },
  838. parse6: function(data, offset, obj) {
  839. var bin = Typr["B"];
  840. offset += 2;
  841. bin.readUshort(data, offset);
  842. offset += 2;
  843. bin.readUshort(data, offset);
  844. offset += 2;
  845. obj.firstCode = bin.readUshort(data, offset);
  846. offset += 2;
  847. var entryCount = bin.readUshort(data, offset);
  848. offset += 2;
  849. obj.glyphIdArray = [];
  850. for (var i = 0; i < entryCount; i++) {
  851. obj.glyphIdArray.push(bin.readUshort(data, offset));
  852. offset += 2;
  853. }
  854. return obj;
  855. },
  856. parse12: function(data, offset, obj) {
  857. var bin = Typr["B"], rU = bin.readUint;
  858. offset += 4;
  859. rU(data, offset);
  860. offset += 4;
  861. rU(data, offset);
  862. offset += 4;
  863. var nGroups = rU(data, offset) * 3;
  864. offset += 4;
  865. var gps = obj.groups = new Uint32Array(nGroups);
  866. for (var i = 0; i < nGroups; i += 3) {
  867. gps[i] = rU(data, offset + (i << 2));
  868. gps[i + 1] = rU(data, offset + (i << 2) + 4);
  869. gps[i + 2] = rU(data, offset + (i << 2) + 8);
  870. }
  871. return obj;
  872. }
  873. };
  874. Typr["T"].glyf = {
  875. parseTab: function(data, offset, length, font) {
  876. var obj = [], ng = font["maxp"]["numGlyphs"];
  877. for (var g = 0; g < ng; g++) obj.push(null);
  878. return obj;
  879. },
  880. _parseGlyf: function(font, g) {
  881. var bin = Typr["B"];
  882. var data = font["_data"], loca = font["loca"];
  883. if (loca[g] == loca[g + 1]) return null;
  884. var offset = Typr["findTable"](data, "glyf", font["_offset"])[0] + loca[g];
  885. var gl = {};
  886. gl.noc = bin.readShort(data, offset);
  887. offset += 2;
  888. gl.xMin = bin.readShort(data, offset);
  889. offset += 2;
  890. gl.yMin = bin.readShort(data, offset);
  891. offset += 2;
  892. gl.xMax = bin.readShort(data, offset);
  893. offset += 2;
  894. gl.yMax = bin.readShort(data, offset);
  895. offset += 2;
  896. if (gl.xMin >= gl.xMax || gl.yMin >= gl.yMax) return null;
  897. if (gl.noc > 0) {
  898. gl.endPts = [];
  899. for (var i = 0; i < gl.noc; i++) {
  900. gl.endPts.push(bin.readUshort(data, offset));
  901. offset += 2;
  902. }
  903. var instructionLength = bin.readUshort(data, offset);
  904. offset += 2;
  905. if (data.length - offset < instructionLength) return null;
  906. gl.instructions = bin.readBytes(data, offset, instructionLength);
  907. offset += instructionLength;
  908. var crdnum = gl.endPts[gl.noc - 1] + 1;
  909. gl.flags = [];
  910. for (var i = 0; i < crdnum; i++) {
  911. var flag = data[offset];
  912. offset++;
  913. gl.flags.push(flag);
  914. if ((flag & 8) != 0) {
  915. var rep = data[offset];
  916. offset++;
  917. for (var j = 0; j < rep; j++) {
  918. gl.flags.push(flag);
  919. i++;
  920. }
  921. }
  922. }
  923. gl.xs = [];
  924. for (var i = 0; i < crdnum; i++) {
  925. var i8 = (gl.flags[i] & 2) != 0, same = (gl.flags[i] & 16) != 0;
  926. if (i8) {
  927. gl.xs.push(same ? data[offset] : -data[offset]);
  928. offset++;
  929. } else {
  930. if (same) gl.xs.push(0); else {
  931. gl.xs.push(bin.readShort(data, offset));
  932. offset += 2;
  933. }
  934. }
  935. }
  936. gl.ys = [];
  937. for (var i = 0; i < crdnum; i++) {
  938. var i8 = (gl.flags[i] & 4) != 0, same = (gl.flags[i] & 32) != 0;
  939. if (i8) {
  940. gl.ys.push(same ? data[offset] : -data[offset]);
  941. offset++;
  942. } else {
  943. if (same) gl.ys.push(0); else {
  944. gl.ys.push(bin.readShort(data, offset));
  945. offset += 2;
  946. }
  947. }
  948. }
  949. var x = 0, y = 0;
  950. for (var i = 0; i < crdnum; i++) {
  951. x += gl.xs[i];
  952. y += gl.ys[i];
  953. gl.xs[i] = x;
  954. gl.ys[i] = y;
  955. }
  956. } else {
  957. var ARG_1_AND_2_ARE_WORDS = 1 << 0;
  958. var ARGS_ARE_XY_VALUES = 1 << 1;
  959. var WE_HAVE_A_SCALE = 1 << 3;
  960. var MORE_COMPONENTS = 1 << 5;
  961. var WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
  962. var WE_HAVE_A_TWO_BY_TWO = 1 << 7;
  963. var WE_HAVE_INSTRUCTIONS = 1 << 8;
  964. gl.parts = [];
  965. var flags;
  966. do {
  967. flags = bin.readUshort(data, offset);
  968. offset += 2;
  969. var part = {
  970. m: {
  971. a: 1,
  972. b: 0,
  973. c: 0,
  974. d: 1,
  975. tx: 0,
  976. ty: 0
  977. },
  978. p1: -1,
  979. p2: -1
  980. };
  981. gl.parts.push(part);
  982. part.glyphIndex = bin.readUshort(data, offset);
  983. offset += 2;
  984. if (flags & ARG_1_AND_2_ARE_WORDS) {
  985. var arg1 = bin.readShort(data, offset);
  986. offset += 2;
  987. var arg2 = bin.readShort(data, offset);
  988. offset += 2;
  989. } else {
  990. var arg1 = bin.readInt8(data, offset);
  991. offset++;
  992. var arg2 = bin.readInt8(data, offset);
  993. offset++;
  994. }
  995. if (flags & ARGS_ARE_XY_VALUES) {
  996. part.m.tx = arg1;
  997. part.m.ty = arg2;
  998. } else {
  999. part.p1 = arg1;
  1000. part.p2 = arg2;
  1001. }
  1002. if (flags & WE_HAVE_A_SCALE) {
  1003. part.m.a = part.m.d = bin.readF2dot14(data, offset);
  1004. offset += 2;
  1005. } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
  1006. part.m.a = bin.readF2dot14(data, offset);
  1007. offset += 2;
  1008. part.m.d = bin.readF2dot14(data, offset);
  1009. offset += 2;
  1010. } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
  1011. part.m.a = bin.readF2dot14(data, offset);
  1012. offset += 2;
  1013. part.m.b = bin.readF2dot14(data, offset);
  1014. offset += 2;
  1015. part.m.c = bin.readF2dot14(data, offset);
  1016. offset += 2;
  1017. part.m.d = bin.readF2dot14(data, offset);
  1018. offset += 2;
  1019. }
  1020. } while (flags & MORE_COMPONENTS);
  1021. if (flags & WE_HAVE_INSTRUCTIONS) {
  1022. var numInstr = bin.readUshort(data, offset);
  1023. offset += 2;
  1024. gl.instr = [];
  1025. for (var i = 0; i < numInstr; i++) {
  1026. gl.instr.push(data[offset]);
  1027. offset++;
  1028. }
  1029. }
  1030. }
  1031. return gl;
  1032. }
  1033. };
  1034. Typr["T"].head = {
  1035. parseTab: function(data, offset, length) {
  1036. var bin = Typr["B"];
  1037. var obj = {};
  1038. bin.readFixed(data, offset);
  1039. offset += 4;
  1040. obj["fontRevision"] = bin.readFixed(data, offset);
  1041. offset += 4;
  1042. bin.readUint(data, offset);
  1043. offset += 4;
  1044. bin.readUint(data, offset);
  1045. offset += 4;
  1046. obj["flags"] = bin.readUshort(data, offset);
  1047. offset += 2;
  1048. obj["unitsPerEm"] = bin.readUshort(data, offset);
  1049. offset += 2;
  1050. obj["created"] = bin.readUint64(data, offset);
  1051. offset += 8;
  1052. obj["modified"] = bin.readUint64(data, offset);
  1053. offset += 8;
  1054. obj["xMin"] = bin.readShort(data, offset);
  1055. offset += 2;
  1056. obj["yMin"] = bin.readShort(data, offset);
  1057. offset += 2;
  1058. obj["xMax"] = bin.readShort(data, offset);
  1059. offset += 2;
  1060. obj["yMax"] = bin.readShort(data, offset);
  1061. offset += 2;
  1062. obj["macStyle"] = bin.readUshort(data, offset);
  1063. offset += 2;
  1064. obj["lowestRecPPEM"] = bin.readUshort(data, offset);
  1065. offset += 2;
  1066. obj["fontDirectionHint"] = bin.readShort(data, offset);
  1067. offset += 2;
  1068. obj["indexToLocFormat"] = bin.readShort(data, offset);
  1069. offset += 2;
  1070. obj["glyphDataFormat"] = bin.readShort(data, offset);
  1071. offset += 2;
  1072. return obj;
  1073. }
  1074. };
  1075. Typr["T"].hhea = {
  1076. parseTab: function(data, offset, length) {
  1077. var bin = Typr["B"];
  1078. var obj = {};
  1079. bin.readFixed(data, offset);
  1080. offset += 4;
  1081. var keys = [ "ascender", "descender", "lineGap", "advanceWidthMax", "minLeftSideBearing", "minRightSideBearing", "xMaxExtent", "caretSlopeRise", "caretSlopeRun", "caretOffset", "res0", "res1", "res2", "res3", "metricDataFormat", "numberOfHMetrics" ];
  1082. for (var i = 0; i < keys.length; i++) {
  1083. var key = keys[i];
  1084. var func = key == "advanceWidthMax" || key == "numberOfHMetrics" ? bin.readUshort : bin.readShort;
  1085. obj[key] = func(data, offset + i * 2);
  1086. }
  1087. return obj;
  1088. }
  1089. };
  1090. Typr["T"].hmtx = {
  1091. parseTab: function(data, offset, length, font) {
  1092. var bin = Typr["B"];
  1093. var aWidth = [];
  1094. var lsBearing = [];
  1095. var nG = font["maxp"]["numGlyphs"], nH = font["hhea"]["numberOfHMetrics"];
  1096. var aw = 0, lsb = 0, i = 0;
  1097. while (i < nH) {
  1098. aw = bin.readUshort(data, offset + (i << 2));
  1099. lsb = bin.readShort(data, offset + (i << 2) + 2);
  1100. aWidth.push(aw);
  1101. lsBearing.push(lsb);
  1102. i++;
  1103. }
  1104. while (i < nG) {
  1105. aWidth.push(aw);
  1106. lsBearing.push(lsb);
  1107. i++;
  1108. }
  1109. return {
  1110. aWidth: aWidth,
  1111. lsBearing: lsBearing
  1112. };
  1113. }
  1114. };
  1115. Typr["T"].kern = {
  1116. parseTab: function(data, offset, length, font) {
  1117. var bin = Typr["B"], kern = Typr["T"].kern;
  1118. var version = bin.readUshort(data, offset);
  1119. if (version == 1) return kern.parseV1(data, offset, length, font);
  1120. var nTables = bin.readUshort(data, offset + 2);
  1121. offset += 4;
  1122. var map = {
  1123. glyph1: [],
  1124. rval: []
  1125. };
  1126. for (var i = 0; i < nTables; i++) {
  1127. offset += 2;
  1128. var length = bin.readUshort(data, offset);
  1129. offset += 2;
  1130. var coverage = bin.readUshort(data, offset);
  1131. offset += 2;
  1132. var format = coverage >>> 8;
  1133. format &= 15;
  1134. if (format == 0) offset = kern.readFormat0(data, offset, map);
  1135. }
  1136. return map;
  1137. },
  1138. parseV1: function(data, offset, length, font) {
  1139. var bin = Typr["B"], kern = Typr["T"].kern;
  1140. bin.readFixed(data, offset);
  1141. var nTables = bin.readUint(data, offset + 4);
  1142. offset += 8;
  1143. var map = {
  1144. glyph1: [],
  1145. rval: []
  1146. };
  1147. for (var i = 0; i < nTables; i++) {
  1148. bin.readUint(data, offset);
  1149. offset += 4;
  1150. var coverage = bin.readUshort(data, offset);
  1151. offset += 2;
  1152. bin.readUshort(data, offset);
  1153. offset += 2;
  1154. var format = coverage & 255;
  1155. if (format == 0) offset = kern.readFormat0(data, offset, map);
  1156. }
  1157. return map;
  1158. },
  1159. readFormat0: function(data, offset, map) {
  1160. var bin = Typr["B"], rUs = bin.readUshort;
  1161. var pleft = -1;
  1162. var nPairs = rUs(data, offset);
  1163. rUs(data, offset + 2);
  1164. rUs(data, offset + 4);
  1165. rUs(data, offset + 6);
  1166. offset += 8;
  1167. for (var j = 0; j < nPairs; j++) {
  1168. var left = rUs(data, offset);
  1169. offset += 2;
  1170. var right = rUs(data, offset);
  1171. offset += 2;
  1172. var value = bin.readShort(data, offset);
  1173. offset += 2;
  1174. if (left != pleft) {
  1175. map.glyph1.push(left);
  1176. map.rval.push({
  1177. glyph2: [],
  1178. vals: []
  1179. });
  1180. }
  1181. var rval = map.rval[map.rval.length - 1];
  1182. rval.glyph2.push(right);
  1183. rval.vals.push(value);
  1184. pleft = left;
  1185. }
  1186. return offset;
  1187. }
  1188. };
  1189. Typr["T"].loca = {
  1190. parseTab: function(data, offset, length, font) {
  1191. var bin = Typr["B"];
  1192. var obj = [];
  1193. var ver = font["head"]["indexToLocFormat"];
  1194. var len = font["maxp"]["numGlyphs"] + 1;
  1195. if (ver == 0) for (var i = 0; i < len; i++) obj.push(bin.readUshort(data, offset + (i << 1)) << 1);
  1196. if (ver == 1) for (var i = 0; i < len; i++) obj.push(bin.readUint(data, offset + (i << 2)));
  1197. return obj;
  1198. }
  1199. };
  1200. Typr["T"].maxp = {
  1201. parseTab: function(data, offset, length) {
  1202. var bin = Typr["B"], rU = bin.readUshort;
  1203. var obj = {};
  1204. bin.readUint(data, offset);
  1205. offset += 4;
  1206. obj["numGlyphs"] = rU(data, offset);
  1207. offset += 2;
  1208. return obj;
  1209. }
  1210. };
  1211. Typr["T"].name = {
  1212. parseTab: function(data, offset, length) {
  1213. var bin = Typr["B"];
  1214. var obj = {};
  1215. bin.readUshort(data, offset);
  1216. offset += 2;
  1217. var count = bin.readUshort(data, offset);
  1218. offset += 2;
  1219. bin.readUshort(data, offset);
  1220. offset += 2;
  1221. 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" ];
  1222. var offset0 = offset;
  1223. var rU = bin.readUshort;
  1224. for (var i = 0; i < count; i++) {
  1225. var platformID = rU(data, offset);
  1226. offset += 2;
  1227. var encodingID = rU(data, offset);
  1228. offset += 2;
  1229. var languageID = rU(data, offset);
  1230. offset += 2;
  1231. var nameID = rU(data, offset);
  1232. offset += 2;
  1233. var slen = rU(data, offset);
  1234. offset += 2;
  1235. var noffset = rU(data, offset);
  1236. offset += 2;
  1237. var soff = offset0 + count * 12 + noffset;
  1238. var str;
  1239. 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) {
  1240. str = bin.readASCII(data, soff, slen);
  1241. console.log("reading unknown MAC encoding " + encodingID + " as ASCII");
  1242. } else {
  1243. console.log("unknown encoding " + encodingID + ", platformID: " + platformID);
  1244. str = bin.readASCII(data, soff, slen);
  1245. }
  1246. var tid = "p" + platformID + "," + languageID.toString(16);
  1247. if (obj[tid] == null) obj[tid] = {};
  1248. obj[tid][names[nameID]] = str;
  1249. obj[tid]["_lang"] = languageID;
  1250. }
  1251. var psn = "postScriptName";
  1252. for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 1033) return obj[p];
  1253. for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 0) return obj[p];
  1254. for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 3084) return obj[p];
  1255. for (var p in obj) if (obj[p][psn] != null) return obj[p];
  1256. var out;
  1257. for (var p in obj) {
  1258. out = obj[p];
  1259. break;
  1260. }
  1261. console.log("returning name table with languageID " + out._lang);
  1262. if (out[psn] == null && out["ID"] != null) out[psn] = out["ID"];
  1263. return out;
  1264. }
  1265. };
  1266. Typr["T"].OS2 = {
  1267. parseTab: function(data, offset, length) {
  1268. var bin = Typr["B"];
  1269. var ver = bin.readUshort(data, offset);
  1270. offset += 2;
  1271. var OS2 = Typr["T"].OS2;
  1272. var obj = {};
  1273. 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;
  1274. return obj;
  1275. },
  1276. version0: function(data, offset, obj) {
  1277. var bin = Typr["B"];
  1278. obj["xAvgCharWidth"] = bin.readShort(data, offset);
  1279. offset += 2;
  1280. obj["usWeightClass"] = bin.readUshort(data, offset);
  1281. offset += 2;
  1282. obj["usWidthClass"] = bin.readUshort(data, offset);
  1283. offset += 2;
  1284. obj["fsType"] = bin.readUshort(data, offset);
  1285. offset += 2;
  1286. obj["ySubscriptXSize"] = bin.readShort(data, offset);
  1287. offset += 2;
  1288. obj["ySubscriptYSize"] = bin.readShort(data, offset);
  1289. offset += 2;
  1290. obj["ySubscriptXOffset"] = bin.readShort(data, offset);
  1291. offset += 2;
  1292. obj["ySubscriptYOffset"] = bin.readShort(data, offset);
  1293. offset += 2;
  1294. obj["ySuperscriptXSize"] = bin.readShort(data, offset);
  1295. offset += 2;
  1296. obj["ySuperscriptYSize"] = bin.readShort(data, offset);
  1297. offset += 2;
  1298. obj["ySuperscriptXOffset"] = bin.readShort(data, offset);
  1299. offset += 2;
  1300. obj["ySuperscriptYOffset"] = bin.readShort(data, offset);
  1301. offset += 2;
  1302. obj["yStrikeoutSize"] = bin.readShort(data, offset);
  1303. offset += 2;
  1304. obj["yStrikeoutPosition"] = bin.readShort(data, offset);
  1305. offset += 2;
  1306. obj["sFamilyClass"] = bin.readShort(data, offset);
  1307. offset += 2;
  1308. obj["panose"] = bin.readBytes(data, offset, 10);
  1309. offset += 10;
  1310. obj["ulUnicodeRange1"] = bin.readUint(data, offset);
  1311. offset += 4;
  1312. obj["ulUnicodeRange2"] = bin.readUint(data, offset);
  1313. offset += 4;
  1314. obj["ulUnicodeRange3"] = bin.readUint(data, offset);
  1315. offset += 4;
  1316. obj["ulUnicodeRange4"] = bin.readUint(data, offset);
  1317. offset += 4;
  1318. obj["achVendID"] = bin.readASCII(data, offset, 4);
  1319. offset += 4;
  1320. obj["fsSelection"] = bin.readUshort(data, offset);
  1321. offset += 2;
  1322. obj["usFirstCharIndex"] = bin.readUshort(data, offset);
  1323. offset += 2;
  1324. obj["usLastCharIndex"] = bin.readUshort(data, offset);
  1325. offset += 2;
  1326. obj["sTypoAscender"] = bin.readShort(data, offset);
  1327. offset += 2;
  1328. obj["sTypoDescender"] = bin.readShort(data, offset);
  1329. offset += 2;
  1330. obj["sTypoLineGap"] = bin.readShort(data, offset);
  1331. offset += 2;
  1332. obj["usWinAscent"] = bin.readUshort(data, offset);
  1333. offset += 2;
  1334. obj["usWinDescent"] = bin.readUshort(data, offset);
  1335. offset += 2;
  1336. return offset;
  1337. },
  1338. version1: function(data, offset, obj) {
  1339. var bin = Typr["B"];
  1340. offset = Typr["T"].OS2.version0(data, offset, obj);
  1341. obj["ulCodePageRange1"] = bin.readUint(data, offset);
  1342. offset += 4;
  1343. obj["ulCodePageRange2"] = bin.readUint(data, offset);
  1344. offset += 4;
  1345. return offset;
  1346. },
  1347. version2: function(data, offset, obj) {
  1348. var bin = Typr["B"], rU = bin.readUshort;
  1349. offset = Typr["T"].OS2.version1(data, offset, obj);
  1350. obj["sxHeight"] = bin.readShort(data, offset);
  1351. offset += 2;
  1352. obj["sCapHeight"] = bin.readShort(data, offset);
  1353. offset += 2;
  1354. obj["usDefault"] = rU(data, offset);
  1355. offset += 2;
  1356. obj["usBreak"] = rU(data, offset);
  1357. offset += 2;
  1358. obj["usMaxContext"] = rU(data, offset);
  1359. offset += 2;
  1360. return offset;
  1361. },
  1362. version5: function(data, offset, obj) {
  1363. var rU = Typr["B"].readUshort;
  1364. offset = Typr["T"].OS2.version2(data, offset, obj);
  1365. obj["usLowerOpticalPointSize"] = rU(data, offset);
  1366. offset += 2;
  1367. obj["usUpperOpticalPointSize"] = rU(data, offset);
  1368. offset += 2;
  1369. return offset;
  1370. }
  1371. };
  1372. Typr["T"].post = {
  1373. parseTab: function(data, offset, length) {
  1374. var bin = Typr["B"];
  1375. var obj = {};
  1376. obj["version"] = bin.readFixed(data, offset);
  1377. offset += 4;
  1378. obj["italicAngle"] = bin.readFixed(data, offset);
  1379. offset += 4;
  1380. obj["underlinePosition"] = bin.readShort(data, offset);
  1381. offset += 2;
  1382. obj["underlineThickness"] = bin.readShort(data, offset);
  1383. offset += 2;
  1384. return obj;
  1385. }
  1386. };
  1387. Typr["T"].SVG = {
  1388. parseTab: function(data, offset, length) {
  1389. var bin = Typr["B"];
  1390. var obj = {
  1391. entries: []
  1392. };
  1393. var offset0 = offset;
  1394. bin.readUshort(data, offset);
  1395. offset += 2;
  1396. var svgDocIndexOffset = bin.readUint(data, offset);
  1397. offset += 4;
  1398. bin.readUint(data, offset);
  1399. offset += 4;
  1400. offset = svgDocIndexOffset + offset0;
  1401. var numEntries = bin.readUshort(data, offset);
  1402. offset += 2;
  1403. for (var i = 0; i < numEntries; i++) {
  1404. var startGlyphID = bin.readUshort(data, offset);
  1405. offset += 2;
  1406. var endGlyphID = bin.readUshort(data, offset);
  1407. offset += 2;
  1408. var svgDocOffset = bin.readUint(data, offset);
  1409. offset += 4;
  1410. var svgDocLength = bin.readUint(data, offset);
  1411. offset += 4;
  1412. var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength);
  1413. var svg = bin.readUTF8(sbuf, 0, sbuf.length);
  1414. for (var f = startGlyphID; f <= endGlyphID; f++) {
  1415. obj.entries[f] = svg;
  1416. }
  1417. }
  1418. return obj;
  1419. }
  1420. };
  1421. Typr["U"] = {
  1422. shape: function(font, str, ltr) {
  1423. var getGlyphPosition = function(font, gls, i1, ltr) {
  1424. var g1 = gls[i1], g2 = gls[i1 + 1], kern = font["kern"];
  1425. if (kern) {
  1426. var ind1 = kern.glyph1.indexOf(g1);
  1427. if (ind1 != -1) {
  1428. var ind2 = kern.rval[ind1].glyph2.indexOf(g2);
  1429. if (ind2 != -1) return [ 0, 0, kern.rval[ind1].vals[ind2], 0 ];
  1430. }
  1431. }
  1432. return [ 0, 0, 0, 0 ];
  1433. };
  1434. var gls = [];
  1435. for (var i = 0; i < str.length; i++) {
  1436. var cc = str.codePointAt(i);
  1437. if (cc > 65535) i++;
  1438. gls.push(Typr["U"]["codeToGlyph"](font, cc));
  1439. }
  1440. var shape = [];
  1441. for (var i = 0; i < gls.length; i++) {
  1442. var padj = getGlyphPosition(font, gls, i);
  1443. var gid = gls[i];
  1444. var ax = font["hmtx"].aWidth[gid] + padj[2];
  1445. shape.push({
  1446. g: gid,
  1447. cl: i,
  1448. dx: 0,
  1449. dy: 0,
  1450. ax: ax,
  1451. ay: 0
  1452. });
  1453. }
  1454. return shape;
  1455. },
  1456. shapeToPath: function(font, shape, clr) {
  1457. var tpath = {
  1458. cmds: [],
  1459. crds: []
  1460. };
  1461. var x = 0, y = 0;
  1462. for (var i = 0; i < shape.length; i++) {
  1463. var it = shape[i];
  1464. var path = Typr["U"]["glyphToPath"](font, it["g"]), crds = path["crds"];
  1465. for (var j = 0; j < crds.length; j += 2) {
  1466. tpath.crds.push(crds[j] + x + it["dx"]);
  1467. tpath.crds.push(crds[j + 1] + y + it["dy"]);
  1468. }
  1469. if (clr) tpath.cmds.push(clr);
  1470. for (var j = 0; j < path["cmds"].length; j++) tpath.cmds.push(path["cmds"][j]);
  1471. var clen = tpath.cmds.length;
  1472. if (clr) if (clen != 0 && tpath.cmds[clen - 1] != "X") tpath.cmds.push("X");
  1473. x += it["ax"];
  1474. y += it["ay"];
  1475. }
  1476. return {
  1477. cmds: tpath.cmds,
  1478. crds: tpath.crds
  1479. };
  1480. },
  1481. codeToGlyph: function(font, code) {
  1482. var cmap = font["cmap"];
  1483. var tind = -1, pps = [ "p3e10", "p0e4", "p3e1", "p1e0", "p0e3", "p0e1" ];
  1484. for (var i = 0; i < pps.length; i++) if (cmap.ids[pps[i]] != null) {
  1485. tind = cmap.ids[pps[i]];
  1486. break;
  1487. }
  1488. if (tind == -1) throw "no familiar platform and encoding!";
  1489. var arrSearch = function(arr, k, v) {
  1490. var l = 0, r = Math.floor(arr.length / k);
  1491. while (l + 1 != r) {
  1492. var mid = l + (r - l >>> 1);
  1493. if (arr[mid * k] <= v) l = mid; else r = mid;
  1494. }
  1495. return l * k;
  1496. };
  1497. var tab = cmap.tables[tind], fmt = tab.format, gid = -1;
  1498. if (fmt == 0) {
  1499. if (code >= tab.map.length) gid = 0; else gid = tab.map[code];
  1500. } else if (fmt == 4) {
  1501. var sind = -1, ec = tab.endCount;
  1502. if (code > ec[ec.length - 1]) sind = -1; else {
  1503. sind = arrSearch(ec, 1, code);
  1504. if (ec[sind] < code) sind++;
  1505. }
  1506. if (sind == -1) gid = 0; else if (code < tab.startCount[sind]) gid = 0; else {
  1507. var gli = 0;
  1508. 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];
  1509. gid = gli & 65535;
  1510. }
  1511. } else if (fmt == 6) {
  1512. var off = code - tab.firstCode, arr = tab.glyphIdArray;
  1513. if (off < 0 || off >= arr.length) gid = 0; else gid = arr[off];
  1514. } else if (fmt == 12) {
  1515. var grp = tab.groups;
  1516. if (code > grp[grp.length - 2]) gid = 0; else {
  1517. var i = arrSearch(grp, 3, code);
  1518. if (grp[i] <= code && code <= grp[i + 1]) {
  1519. gid = grp[i + 2] + (code - grp[i]);
  1520. }
  1521. if (gid == -1) gid = 0;
  1522. }
  1523. } else throw "unknown cmap table format " + tab.format;
  1524. var SVG = font["SVG "], loca = font["loca"];
  1525. 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;
  1526. return gid;
  1527. },
  1528. glyphToPath: function(font, gid) {
  1529. var path = {
  1530. cmds: [],
  1531. crds: []
  1532. };
  1533. var SVG = font["SVG "], CFF = font["CFF "];
  1534. var U = Typr["U"];
  1535. if (SVG && SVG.entries[gid]) {
  1536. var p = SVG.entries[gid];
  1537. if (p != null) {
  1538. if (typeof p == "string") {
  1539. p = U["SVG"].toPath(p);
  1540. SVG.entries[gid] = p;
  1541. }
  1542. path = p;
  1543. }
  1544. } else if (CFF) {
  1545. var pdct = CFF["Private"];
  1546. var state = {
  1547. x: 0,
  1548. y: 0,
  1549. stack: [],
  1550. nStems: 0,
  1551. haveWidth: false,
  1552. width: pdct ? pdct["defaultWidthX"] : 0,
  1553. open: false
  1554. };
  1555. if (CFF["ROS"]) {
  1556. var gi = 0;
  1557. while (CFF["FDSelect"][gi + 2] <= gid) gi += 2;
  1558. pdct = CFF["FDArray"][CFF["FDSelect"][gi + 1]]["Private"];
  1559. }
  1560. U["_drawCFF"](CFF["CharStrings"][gid], state, CFF, pdct, path);
  1561. } else if (font["glyf"]) {
  1562. U["_drawGlyf"](gid, font, path);
  1563. }
  1564. return {
  1565. cmds: path.cmds,
  1566. crds: path.crds
  1567. };
  1568. },
  1569. _drawGlyf: function(gid, font, path) {
  1570. var gl = font["glyf"][gid];
  1571. if (gl == null) gl = font["glyf"][gid] = Typr["T"].glyf._parseGlyf(font, gid);
  1572. if (gl != null) {
  1573. if (gl.noc > -1) Typr["U"]["_simpleGlyph"](gl, path); else Typr["U"]["_compoGlyph"](gl, font, path);
  1574. }
  1575. },
  1576. _simpleGlyph: function(gl, p) {
  1577. var P = Typr["U"]["P"];
  1578. for (var c = 0; c < gl.noc; c++) {
  1579. var i0 = c == 0 ? 0 : gl.endPts[c - 1] + 1;
  1580. var il = gl.endPts[c];
  1581. for (var i = i0; i <= il; i++) {
  1582. var pr = i == i0 ? il : i - 1;
  1583. var nx = i == il ? i0 : i + 1;
  1584. var onCurve = gl.flags[i] & 1;
  1585. var prOnCurve = gl.flags[pr] & 1;
  1586. var nxOnCurve = gl.flags[nx] & 1;
  1587. var x = gl.xs[i], y = gl.ys[i];
  1588. if (i == i0) {
  1589. if (onCurve) {
  1590. if (prOnCurve) P.MoveTo(p, gl.xs[pr], gl.ys[pr]); else {
  1591. P.MoveTo(p, x, y);
  1592. continue;
  1593. }
  1594. } else {
  1595. 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));
  1596. }
  1597. }
  1598. if (onCurve) {
  1599. if (prOnCurve) P.LineTo(p, x, y);
  1600. } else {
  1601. 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));
  1602. }
  1603. }
  1604. P.ClosePath(p);
  1605. }
  1606. },
  1607. _compoGlyph: function(gl, font, p) {
  1608. for (var j = 0; j < gl.parts.length; j++) {
  1609. var path = {
  1610. cmds: [],
  1611. crds: []
  1612. };
  1613. var prt = gl.parts[j];
  1614. Typr["U"]["_drawGlyf"](prt.glyphIndex, font, path);
  1615. var m = prt.m;
  1616. for (var i = 0; i < path.crds.length; i += 2) {
  1617. var x = path.crds[i], y = path.crds[i + 1];
  1618. p.crds.push(x * m.a + y * m.b + m.tx);
  1619. p.crds.push(x * m.c + y * m.d + m.ty);
  1620. }
  1621. for (var i = 0; i < path.cmds.length; i++) p.cmds.push(path.cmds[i]);
  1622. }
  1623. },
  1624. pathToSVG: function(path, prec) {
  1625. var cmds = path["cmds"], crds = path["crds"];
  1626. if (prec == null) prec = 5;
  1627. var out = [], co = 0, lmap = {
  1628. M: 2,
  1629. L: 2,
  1630. Q: 4,
  1631. C: 6
  1632. };
  1633. for (var i = 0; i < cmds.length; i++) {
  1634. var cmd = cmds[i], cn = co + (lmap[cmd] ? lmap[cmd] : 0);
  1635. out.push(cmd);
  1636. while (co < cn) {
  1637. var c = crds[co++];
  1638. out.push(parseFloat(c.toFixed(prec)) + (co == cn ? "" : " "));
  1639. }
  1640. }
  1641. return out.join("");
  1642. },
  1643. SVGToPath: function(d) {
  1644. var pth = {
  1645. cmds: [],
  1646. crds: []
  1647. };
  1648. Typr["U"]["SVG"].svgToPath(d, pth);
  1649. return {
  1650. cmds: pth.cmds,
  1651. crds: pth.crds
  1652. };
  1653. },
  1654. pathToContext: function(path, ctx) {
  1655. var c = 0, cmds = path["cmds"], crds = path["crds"];
  1656. for (var j = 0; j < cmds.length; j++) {
  1657. var cmd = cmds[j];
  1658. if (cmd == "M") {
  1659. ctx.moveTo(crds[c], crds[c + 1]);
  1660. c += 2;
  1661. } else if (cmd == "L") {
  1662. ctx.lineTo(crds[c], crds[c + 1]);
  1663. c += 2;
  1664. } else if (cmd == "C") {
  1665. ctx.bezierCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3], crds[c + 4], crds[c + 5]);
  1666. c += 6;
  1667. } else if (cmd == "Q") {
  1668. ctx.quadraticCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3]);
  1669. c += 4;
  1670. } else if (cmd.charAt(0) == "#") {
  1671. ctx.beginPath();
  1672. ctx.fillStyle = cmd;
  1673. } else if (cmd == "Z") {
  1674. ctx.closePath();
  1675. } else if (cmd == "X") {
  1676. ctx.fill();
  1677. }
  1678. }
  1679. },
  1680. P: {
  1681. MoveTo: function(p, x, y) {
  1682. p.cmds.push("M");
  1683. p.crds.push(x, y);
  1684. },
  1685. LineTo: function(p, x, y) {
  1686. p.cmds.push("L");
  1687. p.crds.push(x, y);
  1688. },
  1689. CurveTo: function(p, a, b, c, d, e, f) {
  1690. p.cmds.push("C");
  1691. p.crds.push(a, b, c, d, e, f);
  1692. },
  1693. qCurveTo: function(p, a, b, c, d) {
  1694. p.cmds.push("Q");
  1695. p.crds.push(a, b, c, d);
  1696. },
  1697. ClosePath: function(p) {
  1698. p.cmds.push("Z");
  1699. }
  1700. },
  1701. _drawCFF: function(cmds, state, font, pdct, p) {
  1702. var stack = state.stack;
  1703. var nStems = state.nStems, haveWidth = state.haveWidth, width = state.width, open = state.open;
  1704. var i = 0;
  1705. 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;
  1706. var CFF = Typr["T"].CFF, P = Typr["U"]["P"];
  1707. var nominalWidthX = pdct["nominalWidthX"];
  1708. var o = {
  1709. val: 0,
  1710. size: 0
  1711. };
  1712. while (i < cmds.length) {
  1713. CFF.getCharString(cmds, i, o);
  1714. var v = o.val;
  1715. i += o.size;
  1716. if (v == "o1" || v == "o18") {
  1717. var hasWidthArg;
  1718. hasWidthArg = stack.length % 2 !== 0;
  1719. if (hasWidthArg && !haveWidth) {
  1720. width = stack.shift() + nominalWidthX;
  1721. }
  1722. nStems += stack.length >> 1;
  1723. stack.length = 0;
  1724. haveWidth = true;
  1725. } else if (v == "o3" || v == "o23") {
  1726. var hasWidthArg;
  1727. hasWidthArg = stack.length % 2 !== 0;
  1728. if (hasWidthArg && !haveWidth) {
  1729. width = stack.shift() + nominalWidthX;
  1730. }
  1731. nStems += stack.length >> 1;
  1732. stack.length = 0;
  1733. haveWidth = true;
  1734. } else if (v == "o4") {
  1735. if (stack.length > 1 && !haveWidth) {
  1736. width = stack.shift() + nominalWidthX;
  1737. haveWidth = true;
  1738. }
  1739. if (open) P.ClosePath(p);
  1740. y += stack.pop();
  1741. P.MoveTo(p, x, y);
  1742. open = true;
  1743. } else if (v == "o5") {
  1744. while (stack.length > 0) {
  1745. x += stack.shift();
  1746. y += stack.shift();
  1747. P.LineTo(p, x, y);
  1748. }
  1749. } else if (v == "o6" || v == "o7") {
  1750. var count = stack.length;
  1751. var isX = v == "o6";
  1752. for (var j = 0; j < count; j++) {
  1753. var sval = stack.shift();
  1754. if (isX) x += sval; else y += sval;
  1755. isX = !isX;
  1756. P.LineTo(p, x, y);
  1757. }
  1758. } else if (v == "o8" || v == "o24") {
  1759. var count = stack.length;
  1760. var index = 0;
  1761. while (index + 6 <= count) {
  1762. c1x = x + stack.shift();
  1763. c1y = y + stack.shift();
  1764. c2x = c1x + stack.shift();
  1765. c2y = c1y + stack.shift();
  1766. x = c2x + stack.shift();
  1767. y = c2y + stack.shift();
  1768. P.CurveTo(p, c1x, c1y, c2x, c2y, x, y);
  1769. index += 6;
  1770. }
  1771. if (v == "o24") {
  1772. x += stack.shift();
  1773. y += stack.shift();
  1774. P.LineTo(p, x, y);
  1775. }
  1776. } else if (v == "o11") break; else if (v == "o1234" || v == "o1235" || v == "o1236" || v == "o1237") {
  1777. if (v == "o1234") {
  1778. c1x = x + stack.shift();
  1779. c1y = y;
  1780. c2x = c1x + stack.shift();
  1781. c2y = c1y + stack.shift();
  1782. jpx = c2x + stack.shift();
  1783. jpy = c2y;
  1784. c3x = jpx + stack.shift();
  1785. c3y = c2y;
  1786. c4x = c3x + stack.shift();
  1787. c4y = y;
  1788. x = c4x + stack.shift();
  1789. P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy);
  1790. P.CurveTo(p, c3x, c3y, c4x, c4y, x, y);
  1791. }
  1792. if (v == "o1235") {
  1793. c1x = x + stack.shift();
  1794. c1y = y + stack.shift();
  1795. c2x = c1x + stack.shift();
  1796. c2y = c1y + stack.shift();
  1797. jpx = c2x + stack.shift();
  1798. jpy = c2y + stack.shift();
  1799. c3x = jpx + stack.shift();
  1800. c3y = jpy + stack.shift();
  1801. c4x = c3x + stack.shift();
  1802. c4y = c3y + stack.shift();
  1803. x = c4x + stack.shift();
  1804. y = c4y + stack.shift();
  1805. stack.shift();
  1806. P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy);
  1807. P.CurveTo(p, c3x, c3y, c4x, c4y, x, y);
  1808. }
  1809. if (v == "o1236") {
  1810. c1x = x + stack.shift();
  1811. c1y = y + stack.shift();
  1812. c2x = c1x + stack.shift();
  1813. c2y = c1y + stack.shift();
  1814. jpx = c2x + stack.shift();
  1815. jpy = c2y;
  1816. c3x = jpx + stack.shift();
  1817. c3y = c2y;
  1818. c4x = c3x + stack.shift();
  1819. c4y = c3y + stack.shift();
  1820. x = c4x + stack.shift();
  1821. P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy);
  1822. P.CurveTo(p, c3x, c3y, c4x, c4y, x, y);
  1823. }
  1824. if (v == "o1237") {
  1825. c1x = x + stack.shift();
  1826. c1y = y + stack.shift();
  1827. c2x = c1x + stack.shift();
  1828. c2y = c1y + stack.shift();
  1829. jpx = c2x + stack.shift();
  1830. jpy = c2y + stack.shift();
  1831. c3x = jpx + stack.shift();
  1832. c3y = jpy + stack.shift();
  1833. c4x = c3x + stack.shift();
  1834. c4y = c3y + stack.shift();
  1835. if (Math.abs(c4x - x) > Math.abs(c4y - y)) {
  1836. x = c4x + stack.shift();
  1837. } else {
  1838. y = c4y + stack.shift();
  1839. }
  1840. P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy);
  1841. P.CurveTo(p, c3x, c3y, c4x, c4y, x, y);
  1842. }
  1843. } else if (v == "o14") {
  1844. if (stack.length > 0 && !haveWidth) {
  1845. width = stack.shift() + font["nominalWidthX"];
  1846. haveWidth = true;
  1847. }
  1848. if (stack.length == 4) {
  1849. var adx = stack.shift();
  1850. var ady = stack.shift();
  1851. var bchar = stack.shift();
  1852. var achar = stack.shift();
  1853. var bind = CFF.glyphBySE(font, bchar);
  1854. var aind = CFF.glyphBySE(font, achar);
  1855. Typr["U"]["_drawCFF"](font["CharStrings"][bind], state, font, pdct, p);
  1856. state.x = adx;
  1857. state.y = ady;
  1858. Typr["U"]["_drawCFF"](font["CharStrings"][aind], state, font, pdct, p);
  1859. }
  1860. if (open) {
  1861. P.ClosePath(p);
  1862. open = false;
  1863. }
  1864. } else if (v == "o19" || v == "o20") {
  1865. var hasWidthArg;
  1866. hasWidthArg = stack.length % 2 !== 0;
  1867. if (hasWidthArg && !haveWidth) {
  1868. width = stack.shift() + nominalWidthX;
  1869. }
  1870. nStems += stack.length >> 1;
  1871. stack.length = 0;
  1872. haveWidth = true;
  1873. i += nStems + 7 >> 3;
  1874. } else if (v == "o21") {
  1875. if (stack.length > 2 && !haveWidth) {
  1876. width = stack.shift() + nominalWidthX;
  1877. haveWidth = true;
  1878. }
  1879. y += stack.pop();
  1880. x += stack.pop();
  1881. if (open) P.ClosePath(p);
  1882. P.MoveTo(p, x, y);
  1883. open = true;
  1884. } else if (v == "o22") {
  1885. if (stack.length > 1 && !haveWidth) {
  1886. width = stack.shift() + nominalWidthX;
  1887. haveWidth = true;
  1888. }
  1889. x += stack.pop();
  1890. if (open) P.ClosePath(p);
  1891. P.MoveTo(p, x, y);
  1892. open = true;
  1893. } else if (v == "o25") {
  1894. while (stack.length > 6) {
  1895. x += stack.shift();
  1896. y += stack.shift();
  1897. P.LineTo(p, x, y);
  1898. }
  1899. c1x = x + stack.shift();
  1900. c1y = y + stack.shift();
  1901. c2x = c1x + stack.shift();
  1902. c2y = c1y + stack.shift();
  1903. x = c2x + stack.shift();
  1904. y = c2y + stack.shift();
  1905. P.CurveTo(p, c1x, c1y, c2x, c2y, x, y);
  1906. } else if (v == "o26") {
  1907. if (stack.length % 2) {
  1908. x += stack.shift();
  1909. }
  1910. while (stack.length > 0) {
  1911. c1x = x;
  1912. c1y = y + stack.shift();
  1913. c2x = c1x + stack.shift();
  1914. c2y = c1y + stack.shift();
  1915. x = c2x;
  1916. y = c2y + stack.shift();
  1917. P.CurveTo(p, c1x, c1y, c2x, c2y, x, y);
  1918. }
  1919. } else if (v == "o27") {
  1920. if (stack.length % 2) {
  1921. y += stack.shift();
  1922. }
  1923. while (stack.length > 0) {
  1924. c1x = x + stack.shift();
  1925. c1y = y;
  1926. c2x = c1x + stack.shift();
  1927. c2y = c1y + stack.shift();
  1928. x = c2x + stack.shift();
  1929. y = c2y;
  1930. P.CurveTo(p, c1x, c1y, c2x, c2y, x, y);
  1931. }
  1932. } else if (v == "o10" || v == "o29") {
  1933. var obj = v == "o10" ? pdct : font;
  1934. if (stack.length == 0) {
  1935. console.log("error: empty stack");
  1936. } else {
  1937. var ind = stack.pop();
  1938. var subr = obj["Subrs"][ind + obj["Bias"]];
  1939. state.x = x;
  1940. state.y = y;
  1941. state.nStems = nStems;
  1942. state.haveWidth = haveWidth;
  1943. state.width = width;
  1944. state.open = open;
  1945. Typr["U"]["_drawCFF"](subr, state, font, pdct, p);
  1946. x = state.x;
  1947. y = state.y;
  1948. nStems = state.nStems;
  1949. haveWidth = state.haveWidth;
  1950. width = state.width;
  1951. open = state.open;
  1952. }
  1953. } else if (v == "o30" || v == "o31") {
  1954. var count, count1 = stack.length;
  1955. var index = 0;
  1956. var alternate = v == "o31";
  1957. count = count1 & ~2;
  1958. index += count1 - count;
  1959. while (index < count) {
  1960. if (alternate) {
  1961. c1x = x + stack.shift();
  1962. c1y = y;
  1963. c2x = c1x + stack.shift();
  1964. c2y = c1y + stack.shift();
  1965. y = c2y + stack.shift();
  1966. if (count - index == 5) {
  1967. x = c2x + stack.shift();
  1968. index++;
  1969. } else x = c2x;
  1970. alternate = false;
  1971. } else {
  1972. c1x = x;
  1973. c1y = y + stack.shift();
  1974. c2x = c1x + stack.shift();
  1975. c2y = c1y + stack.shift();
  1976. x = c2x + stack.shift();
  1977. if (count - index == 5) {
  1978. y = c2y + stack.shift();
  1979. index++;
  1980. } else y = c2y;
  1981. alternate = true;
  1982. }
  1983. P.CurveTo(p, c1x, c1y, c2x, c2y, x, y);
  1984. index += 4;
  1985. }
  1986. } else if ((v + "").charAt(0) == "o") {
  1987. console.log("Unknown operation: " + v, cmds);
  1988. throw v;
  1989. } else stack.push(v);
  1990. }
  1991. state.x = x;
  1992. state.y = y;
  1993. state.nStems = nStems;
  1994. state.haveWidth = haveWidth;
  1995. state.width = width;
  1996. state.open = open;
  1997. },
  1998. SVG: function() {
  1999. var M = {
  2000. getScale: function(m) {
  2001. return Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));
  2002. },
  2003. translate: function(m, x, y) {
  2004. M.concat(m, [ 1, 0, 0, 1, x, y ]);
  2005. },
  2006. rotate: function(m, a) {
  2007. M.concat(m, [ Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a), 0, 0 ]);
  2008. },
  2009. scale: function(m, x, y) {
  2010. M.concat(m, [ x, 0, 0, y, 0, 0 ]);
  2011. },
  2012. concat: function(m, w) {
  2013. var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5];
  2014. m[0] = a * w[0] + b * w[2];
  2015. m[1] = a * w[1] + b * w[3];
  2016. m[2] = c * w[0] + d * w[2];
  2017. m[3] = c * w[1] + d * w[3];
  2018. m[4] = tx * w[0] + ty * w[2] + w[4];
  2019. m[5] = tx * w[1] + ty * w[3] + w[5];
  2020. },
  2021. invert: function(m) {
  2022. var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5], adbc = a * d - b * c;
  2023. m[0] = d / adbc;
  2024. m[1] = -b / adbc;
  2025. m[2] = -c / adbc;
  2026. m[3] = a / adbc;
  2027. m[4] = (c * ty - d * tx) / adbc;
  2028. m[5] = (b * tx - a * ty) / adbc;
  2029. },
  2030. multPoint: function(m, p) {
  2031. var x = p[0], y = p[1];
  2032. return [ x * m[0] + y * m[2] + m[4], x * m[1] + y * m[3] + m[5] ];
  2033. },
  2034. multArray: function(m, a) {
  2035. for (var i = 0; i < a.length; i += 2) {
  2036. var x = a[i], y = a[i + 1];
  2037. a[i] = x * m[0] + y * m[2] + m[4];
  2038. a[i + 1] = x * m[1] + y * m[3] + m[5];
  2039. }
  2040. }
  2041. };
  2042. function _bracketSplit(str, lbr, rbr) {
  2043. var out = [], pos = 0, ci = 0, lvl = 0;
  2044. while (true) {
  2045. var li = str.indexOf(lbr, ci);
  2046. var ri = str.indexOf(rbr, ci);
  2047. if (li == -1 && ri == -1) break;
  2048. if (ri == -1 || li != -1 && li < ri) {
  2049. if (lvl == 0) {
  2050. out.push(str.slice(pos, li).trim());
  2051. pos = li + 1;
  2052. }
  2053. lvl++;
  2054. ci = li + 1;
  2055. } else if (li == -1 || ri != -1 && ri < li) {
  2056. lvl--;
  2057. if (lvl == 0) {
  2058. out.push(str.slice(pos, ri).trim());
  2059. pos = ri + 1;
  2060. }
  2061. ci = ri + 1;
  2062. }
  2063. }
  2064. return out;
  2065. }
  2066. function cssMap(str) {
  2067. var pts = _bracketSplit(str, "{", "}");
  2068. var css = {};
  2069. for (var i = 0; i < pts.length; i += 2) {
  2070. var cn = pts[i].split(",");
  2071. for (var j = 0; j < cn.length; j++) {
  2072. var cnj = cn[j].trim();
  2073. if (css[cnj] == null) css[cnj] = "";
  2074. css[cnj] += pts[i + 1];
  2075. }
  2076. }
  2077. return css;
  2078. }
  2079. function readTrnf(trna) {
  2080. var pts = _bracketSplit(trna, "(", ")");
  2081. var m = [ 1, 0, 0, 1, 0, 0 ];
  2082. for (var i = 0; i < pts.length; i += 2) {
  2083. var om = m;
  2084. m = _readTrnsAttr(pts[i], pts[i + 1]);
  2085. M.concat(m, om);
  2086. }
  2087. return m;
  2088. }
  2089. function _readTrnsAttr(fnc, vls) {
  2090. var m = [ 1, 0, 0, 1, 0, 0 ], gotSep = true;
  2091. for (var i = 0; i < vls.length; i++) {
  2092. var ch = vls.charAt(i);
  2093. if (ch == "," || ch == " ") gotSep = true; else if (ch == ".") {
  2094. if (!gotSep) {
  2095. vls = vls.slice(0, i) + "," + vls.slice(i);
  2096. i++;
  2097. }
  2098. gotSep = false;
  2099. } else if (ch == "-" && i > 0 && vls[i - 1] != "e") {
  2100. vls = vls.slice(0, i) + " " + vls.slice(i);
  2101. i++;
  2102. gotSep = true;
  2103. }
  2104. }
  2105. vls = vls.split(/\s*[\s,]\s*/).map(parseFloat);
  2106. if (fnc == "translate") {
  2107. if (vls.length == 1) M.translate(m, vls[0], 0); else M.translate(m, vls[0], vls[1]);
  2108. } else if (fnc == "scale") {
  2109. if (vls.length == 1) M.scale(m, vls[0], vls[0]); else M.scale(m, vls[0], vls[1]);
  2110. } else if (fnc == "rotate") {
  2111. var tx = 0, ty = 0;
  2112. if (vls.length != 1) {
  2113. tx = vls[1];
  2114. ty = vls[2];
  2115. }
  2116. M.translate(m, -tx, -ty);
  2117. M.rotate(m, -Math.PI * vls[0] / 180);
  2118. M.translate(m, tx, ty);
  2119. } else if (fnc == "matrix") m = vls; else console.log("unknown transform: ", fnc);
  2120. return m;
  2121. }
  2122. function toPath(str) {
  2123. var pth = {
  2124. cmds: [],
  2125. crds: []
  2126. };
  2127. if (str == null) return pth;
  2128. var prsr = new DOMParser();
  2129. var doc = prsr["parseFromString"](str, "image/svg+xml");
  2130. var svg = doc.getElementsByTagName("svg")[0];
  2131. var vb = svg.getAttribute("viewBox");
  2132. if (vb) vb = vb.trim().split(" ").map(parseFloat); else vb = [ 0, 0, 1e3, 1e3 ];
  2133. _toPath(svg.children, pth);
  2134. for (var i = 0; i < pth.crds.length; i += 2) {
  2135. var x = pth.crds[i], y = pth.crds[i + 1];
  2136. x -= vb[0];
  2137. y -= vb[1];
  2138. y = -y;
  2139. pth.crds[i] = x;
  2140. pth.crds[i + 1] = y;
  2141. }
  2142. return pth;
  2143. }
  2144. function _toPath(nds, pth, fill) {
  2145. for (var ni = 0; ni < nds.length; ni++) {
  2146. var nd = nds[ni], tn = nd.tagName;
  2147. var cfl = nd.getAttribute("fill");
  2148. if (cfl == null) cfl = fill;
  2149. if (tn == "g") {
  2150. var tp = {
  2151. crds: [],
  2152. cmds: []
  2153. };
  2154. _toPath(nd.children, tp, cfl);
  2155. var trf = nd.getAttribute("transform");
  2156. if (trf) {
  2157. var m = readTrnf(trf);
  2158. M.multArray(m, tp.crds);
  2159. }
  2160. pth.crds = pth.crds.concat(tp.crds);
  2161. pth.cmds = pth.cmds.concat(tp.cmds);
  2162. } else if (tn == "path" || tn == "circle" || tn == "ellipse") {
  2163. pth.cmds.push(cfl ? cfl : "#000000");
  2164. var d;
  2165. if (tn == "path") d = nd.getAttribute("d");
  2166. if (tn == "circle" || tn == "ellipse") {
  2167. var vls = [ 0, 0, 0, 0 ], nms = [ "cx", "cy", "rx", "ry", "r" ];
  2168. for (var i = 0; i < 5; i++) {
  2169. var V = nd.getAttribute(nms[i]);
  2170. if (V) {
  2171. V = parseFloat(V);
  2172. if (i < 4) vls[i] = V; else vls[2] = vls[3] = V;
  2173. }
  2174. }
  2175. var cx = vls[0], cy = vls[1], rx = vls[2], ry = vls[3];
  2176. d = [ "M", cx - rx, cy, "a", rx, ry, 0, 1, 0, rx * 2, 0, "a", rx, ry, 0, 1, 0, -rx * 2, 0 ].join(" ");
  2177. }
  2178. svgToPath(d, pth);
  2179. pth.cmds.push("X");
  2180. } else if (tn == "defs"); else console.log(tn, nd);
  2181. }
  2182. }
  2183. function _tokens(d) {
  2184. var ts = [], off = 0, rn = false, cn = "", pc = "";
  2185. while (off < d.length) {
  2186. var cc = d.charCodeAt(off), ch = d.charAt(off);
  2187. off++;
  2188. var isNum = 48 <= cc && cc <= 57 || ch == "." || ch == "-" || ch == "e" || ch == "E";
  2189. if (rn) {
  2190. if (ch == "-" && pc != "e" || ch == "." && cn.indexOf(".") != -1) {
  2191. ts.push(parseFloat(cn));
  2192. cn = ch;
  2193. } else if (isNum) cn += ch; else {
  2194. ts.push(parseFloat(cn));
  2195. if (ch != "," && ch != " ") ts.push(ch);
  2196. rn = false;
  2197. }
  2198. } else {
  2199. if (isNum) {
  2200. cn = ch;
  2201. rn = true;
  2202. } else if (ch != "," && ch != " ") ts.push(ch);
  2203. }
  2204. pc = ch;
  2205. }
  2206. if (rn) ts.push(parseFloat(cn));
  2207. return ts;
  2208. }
  2209. function _reps(ts, off, ps) {
  2210. var i = off;
  2211. while (i < ts.length) {
  2212. if (typeof ts[i] == "string") break;
  2213. i += ps;
  2214. }
  2215. return (i - off) / ps;
  2216. }
  2217. function svgToPath(d, pth) {
  2218. var ts = _tokens(d);
  2219. var i = 0, x = 0, y = 0, ox = 0, oy = 0, oldo = pth.crds.length;
  2220. var pc = {
  2221. M: 2,
  2222. L: 2,
  2223. H: 1,
  2224. V: 1,
  2225. T: 2,
  2226. S: 4,
  2227. A: 7,
  2228. Q: 4,
  2229. C: 6
  2230. };
  2231. var cmds = pth.cmds, crds = pth.crds;
  2232. while (i < ts.length) {
  2233. var cmd = ts[i];
  2234. i++;
  2235. var cmu = cmd.toUpperCase();
  2236. if (cmu == "Z") {
  2237. cmds.push("Z");
  2238. x = ox;
  2239. y = oy;
  2240. } else {
  2241. var ps = pc[cmu], reps = _reps(ts, i, ps);
  2242. for (var j = 0; j < reps; j++) {
  2243. if (j == 1 && cmu == "M") {
  2244. cmd = cmd == cmu ? "L" : "l";
  2245. cmu = "L";
  2246. }
  2247. var xi = 0, yi = 0;
  2248. if (cmd != cmu) {
  2249. xi = x;
  2250. yi = y;
  2251. }
  2252. if (cmu == "M") {
  2253. x = xi + ts[i++];
  2254. y = yi + ts[i++];
  2255. cmds.push("M");
  2256. crds.push(x, y);
  2257. ox = x;
  2258. oy = y;
  2259. } else if (cmu == "L") {
  2260. x = xi + ts[i++];
  2261. y = yi + ts[i++];
  2262. cmds.push("L");
  2263. crds.push(x, y);
  2264. } else if (cmu == "H") {
  2265. x = xi + ts[i++];
  2266. cmds.push("L");
  2267. crds.push(x, y);
  2268. } else if (cmu == "V") {
  2269. y = yi + ts[i++];
  2270. cmds.push("L");
  2271. crds.push(x, y);
  2272. } else if (cmu == "Q") {
  2273. var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++];
  2274. cmds.push("Q");
  2275. crds.push(x1, y1, x2, y2);
  2276. x = x2;
  2277. y = y2;
  2278. } else if (cmu == "T") {
  2279. var co = Math.max(crds.length - 2, oldo);
  2280. var x1 = x + x - crds[co], y1 = y + y - crds[co + 1];
  2281. var x2 = xi + ts[i++], y2 = yi + ts[i++];
  2282. cmds.push("Q");
  2283. crds.push(x1, y1, x2, y2);
  2284. x = x2;
  2285. y = y2;
  2286. } else if (cmu == "C") {
  2287. 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++];
  2288. cmds.push("C");
  2289. crds.push(x1, y1, x2, y2, x3, y3);
  2290. x = x3;
  2291. y = y3;
  2292. } else if (cmu == "S") {
  2293. var co = Math.max(crds.length - (cmds[cmds.length - 1] == "C" ? 4 : 2), oldo);
  2294. var x1 = x + x - crds[co], y1 = y + y - crds[co + 1];
  2295. var x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++];
  2296. cmds.push("C");
  2297. crds.push(x1, y1, x2, y2, x3, y3);
  2298. x = x3;
  2299. y = y3;
  2300. } else if (cmu == "A") {
  2301. var x1 = x, y1 = y;
  2302. var rx = ts[i++], ry = ts[i++];
  2303. var phi = ts[i++] * (Math.PI / 180), fA = ts[i++], fS = ts[i++];
  2304. var x2 = xi + ts[i++], y2 = yi + ts[i++];
  2305. if (x2 == x && y2 == y && rx == 0 && ry == 0) continue;
  2306. var hdx = (x1 - x2) / 2, hdy = (y1 - y2) / 2;
  2307. var cosP = Math.cos(phi), sinP = Math.sin(phi);
  2308. var x1A = cosP * hdx + sinP * hdy;
  2309. var y1A = -sinP * hdx + cosP * hdy;
  2310. var rxS = rx * rx, ryS = ry * ry;
  2311. var x1AS = x1A * x1A, y1AS = y1A * y1A;
  2312. var frc = (rxS * ryS - rxS * y1AS - ryS * x1AS) / (rxS * y1AS + ryS * x1AS);
  2313. var coef = (fA != fS ? 1 : -1) * Math.sqrt(Math.max(frc, 0));
  2314. var cxA = coef * (rx * y1A) / ry;
  2315. var cyA = -coef * (ry * x1A) / rx;
  2316. var cx = cosP * cxA - sinP * cyA + (x1 + x2) / 2;
  2317. var cy = sinP * cxA + cosP * cyA + (y1 + y2) / 2;
  2318. var angl = function(ux, uy, vx, vy) {
  2319. var lU = Math.sqrt(ux * ux + uy * uy), lV = Math.sqrt(vx * vx + vy * vy);
  2320. var num = (ux * vx + uy * vy) / (lU * lV);
  2321. return (ux * vy - uy * vx >= 0 ? 1 : -1) * Math.acos(Math.max(-1, Math.min(1, num)));
  2322. };
  2323. var vX = (x1A - cxA) / rx, vY = (y1A - cyA) / ry;
  2324. var theta1 = angl(1, 0, vX, vY);
  2325. var dtheta = angl(vX, vY, (-x1A - cxA) / rx, (-y1A - cyA) / ry);
  2326. dtheta = dtheta % (2 * Math.PI);
  2327. var arc = function(gst, x, y, r, a0, a1, neg) {
  2328. var rotate = function(m, a) {
  2329. var si = Math.sin(a), co = Math.cos(a);
  2330. var a = m[0], b = m[1], c = m[2], d = m[3];
  2331. m[0] = a * co + b * si;
  2332. m[1] = -a * si + b * co;
  2333. m[2] = c * co + d * si;
  2334. m[3] = -c * si + d * co;
  2335. };
  2336. var multArr = function(m, a) {
  2337. for (var j = 0; j < a.length; j += 2) {
  2338. var x = a[j], y = a[j + 1];
  2339. a[j] = m[0] * x + m[2] * y + m[4];
  2340. a[j + 1] = m[1] * x + m[3] * y + m[5];
  2341. }
  2342. };
  2343. var concatA = function(a, b) {
  2344. for (var j = 0; j < b.length; j++) a.push(b[j]);
  2345. };
  2346. var concatP = function(p, r) {
  2347. concatA(p.cmds, r.cmds);
  2348. concatA(p.crds, r.crds);
  2349. };
  2350. if (neg) while (a1 > a0) a1 -= 2 * Math.PI; else while (a1 < a0) a1 += 2 * Math.PI;
  2351. var th = (a1 - a0) / 4;
  2352. var x0 = Math.cos(th / 2), y0 = -Math.sin(th / 2);
  2353. var x1 = (4 - x0) / 3, y1 = y0 == 0 ? y0 : (1 - x0) * (3 - x0) / (3 * y0);
  2354. var x2 = x1, y2 = -y1;
  2355. var x3 = x0, y3 = -y0;
  2356. var ps = [ x1, y1, x2, y2, x3, y3 ];
  2357. var pth = {
  2358. cmds: [ "C", "C", "C", "C" ],
  2359. crds: ps.slice(0)
  2360. };
  2361. var rot = [ 1, 0, 0, 1, 0, 0 ];
  2362. rotate(rot, -th);
  2363. for (var j = 0; j < 3; j++) {
  2364. multArr(rot, ps);
  2365. concatA(pth.crds, ps);
  2366. }
  2367. rotate(rot, -a0 + th / 2);
  2368. rot[0] *= r;
  2369. rot[1] *= r;
  2370. rot[2] *= r;
  2371. rot[3] *= r;
  2372. rot[4] = x;
  2373. rot[5] = y;
  2374. multArr(rot, pth.crds);
  2375. multArr(gst.ctm, pth.crds);
  2376. concatP(gst.pth, pth);
  2377. };
  2378. var gst = {
  2379. pth: pth,
  2380. ctm: [ rx * cosP, rx * sinP, -ry * sinP, ry * cosP, cx, cy ]
  2381. };
  2382. arc(gst, 0, 0, 1, theta1, theta1 + dtheta, fS == 0);
  2383. x = x2;
  2384. y = y2;
  2385. } else console.log("Unknown SVG command " + cmd);
  2386. }
  2387. }
  2388. }
  2389. }
  2390. return {
  2391. cssMap: cssMap,
  2392. readTrnf: readTrnf,
  2393. svgToPath: svgToPath,
  2394. toPath: toPath
  2395. };
  2396. }(),
  2397. initHB: function(hurl, resp) {
  2398. var codeLength = function(code) {
  2399. var len = 0;
  2400. if ((code & 4294967295 - (1 << 7) + 1) == 0) {
  2401. len = 1;
  2402. } else if ((code & 4294967295 - (1 << 11) + 1) == 0) {
  2403. len = 2;
  2404. } else if ((code & 4294967295 - (1 << 16) + 1) == 0) {
  2405. len = 3;
  2406. } else if ((code & 4294967295 - (1 << 21) + 1) == 0) {
  2407. len = 4;
  2408. }
  2409. return len;
  2410. };
  2411. var te = new window["TextEncoder"]("utf8");
  2412. fetch(hurl).then(function(x) {
  2413. return x["arrayBuffer"]();
  2414. }).then(function(ab) {
  2415. return WebAssembly["instantiate"](ab);
  2416. }).then(function(res) {
  2417. console.log("HB ready");
  2418. var exp = res["instance"]["exports"], mem = exp["memory"];
  2419. mem["grow"](700);
  2420. var heapu8 = new Uint8Array(mem.buffer);
  2421. var u32 = new Uint32Array(mem.buffer);
  2422. var i32 = new Int32Array(mem.buffer);
  2423. var __lastFnt, blob, blobPtr, face, font;
  2424. Typr["U"]["shapeHB"] = function() {
  2425. var toJson = function(ptr) {
  2426. var length = exp["hb_buffer_get_length"](ptr);
  2427. var result = [];
  2428. var iPtr32 = exp["hb_buffer_get_glyph_infos"](ptr, 0) >>> 2;
  2429. var pPtr32 = exp["hb_buffer_get_glyph_positions"](ptr, 0) >>> 2;
  2430. for (var i = 0; i < length; ++i) {
  2431. var a = iPtr32 + i * 5, b = pPtr32 + i * 5;
  2432. result.push({
  2433. g: u32[a + 0],
  2434. cl: u32[a + 2],
  2435. ax: i32[b + 0],
  2436. ay: i32[b + 1],
  2437. dx: i32[b + 2],
  2438. dy: i32[b + 3]
  2439. });
  2440. }
  2441. return result;
  2442. };
  2443. return function(fnt, str, ltr) {
  2444. var fdata = fnt["_data"], fn = fnt["name"]["postScriptName"];
  2445. if (__lastFnt != fn) {
  2446. if (blob != null) {
  2447. exp["hb_blob_destroy"](blob);
  2448. exp["free"](blobPtr);
  2449. exp["hb_face_destroy"](face);
  2450. exp["hb_font_destroy"](font);
  2451. }
  2452. blobPtr = exp["malloc"](fdata.byteLength);
  2453. heapu8.set(fdata, blobPtr);
  2454. blob = exp["hb_blob_create"](blobPtr, fdata.byteLength, 2, 0, 0);
  2455. face = exp["hb_face_create"](blob, 0);
  2456. font = exp["hb_font_create"](face);
  2457. __lastFnt = fn;
  2458. }
  2459. var buffer = exp["hb_buffer_create"]();
  2460. var bytes = te["encode"](str);
  2461. var len = bytes.length, strp = exp["malloc"](len);
  2462. heapu8.set(bytes, strp);
  2463. exp["hb_buffer_add_utf8"](buffer, strp, len, 0, len);
  2464. exp["free"](strp);
  2465. exp["hb_buffer_set_direction"](buffer, ltr ? 4 : 5);
  2466. exp["hb_buffer_guess_segment_properties"](buffer);
  2467. exp["hb_shape"](font, buffer, 0, 0);
  2468. var json = toJson(buffer);
  2469. exp["hb_buffer_destroy"](buffer);
  2470. var arr = json.slice(0);
  2471. if (!ltr) arr.reverse();
  2472. var ci = 0, bi = 0;
  2473. for (var i = 1; i < arr.length; i++) {
  2474. var gl = arr[i], cl = gl["cl"];
  2475. while (true) {
  2476. var cpt = str.codePointAt(ci), cln = codeLength(cpt);
  2477. if (bi + cln <= cl) {
  2478. bi += cln;
  2479. ci += cpt <= 65535 ? 1 : 2;
  2480. } else break;
  2481. }
  2482. gl["cl"] = ci;
  2483. }
  2484. return json;
  2485. };
  2486. }();
  2487. resp();
  2488. });
  2489. }
  2490. };
  2491. const QQ_GROUP = [ "854137118" ];
  2492. var _self = unsafeWindow;
  2493. var top = _self;
  2494. var UE$1;
  2495. var modelId = "modelId_xx";
  2496. const selfintv = setInterval(() => {
  2497. if (unsafeWindow) {
  2498. _self = unsafeWindow;
  2499. top = _self;
  2500. UE$1 = _self.UE;
  2501. try {
  2502. reportOnline();
  2503. String.prototype.replaceAll = function(s1, s2) {
  2504. return this.replace(new RegExp(s1, "gm"), s2);
  2505. };
  2506. while (top !== _self.top) {
  2507. top = top.parent.document ? top.parent : _self.top;
  2508. if (top.location.pathname === "/mycourse/studentstudy") break;
  2509. }
  2510. } catch (err) {
  2511. top = _self;
  2512. }
  2513. clearInterval(selfintv);
  2514. }
  2515. }, GLOBAL.delay);
  2516. function checkVersion() {
  2517. function compare(v1 = "0", v2 = "0") {
  2518. v1 = String(v1).split(".");
  2519. v2 = String(v2).split(".");
  2520. const minVersionLens = Math.min(v1.length, v2.length);
  2521. let result = 0;
  2522. for (let i = 0; i < minVersionLens; i++) {
  2523. const curV1 = Number(v1[i]);
  2524. const curV2 = Number(v2[i]);
  2525. if (curV1 > curV2) {
  2526. result = 1;
  2527. break;
  2528. } else if (curV1 < curV2) {
  2529. result = -1;
  2530. break;
  2531. }
  2532. }
  2533. if (result === 0 && v1.length !== v2.length) {
  2534. const v1BiggerThenv2 = v1.length > v2.length;
  2535. const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
  2536. for (let i = minVersionLens; i < maxLensVersion.length; i++) {
  2537. const curVersion = Number(maxLensVersion[i]);
  2538. if (curVersion > 0) {
  2539. v1BiggerThenv2 ? result = 1 : result = -1;
  2540. break;
  2541. }
  2542. }
  2543. }
  2544. return result;
  2545. }
  2546. GM_xmlhttpRequest({
  2547. method: "GET",
  2548. url: "https://gf.qytechs.cn/en/scripts/451356.json",
  2549. timeout: GLOBAL.timeout,
  2550. onload: function(r) {
  2551. const obj = JSON.parse(r.responseText);
  2552. 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()) {
  2553. iframeMsg("update", {
  2554. v1: GM_info.script.version,
  2555. v2: obj.version,
  2556. href: obj.url
  2557. });
  2558. }
  2559. }
  2560. });
  2561. }
  2562. top.addEventListener("message", event => {
  2563. if (event.data.type === "jump") {
  2564. GLOBAL.index++;
  2565. iframeMsg("tip", {
  2566. tip: "准备答第" + (GLOBAL.index + 1) + "题"
  2567. });
  2568. } else if (event.data.type === "stop") {
  2569. GLOBAL.stop = event.data.val;
  2570. } else if (event.data.type === "start_pay") {
  2571. if (event.data.flag) {
  2572. if (String(GM_getValue("token")).length === 10 || String(GM_getValue("token")).length === 11) {
  2573. iframeMsg("tip", {
  2574. tip: "已开启请求收费题库,已实时生效"
  2575. });
  2576. GM_setValue("start_pay", event.data.flag);
  2577. iframeMsg("start_pay", true);
  2578. } else {
  2579. iframeMsg("tip", {
  2580. tip: "系统检测您的token可能输入有误,请检查"
  2581. });
  2582. }
  2583. } else {
  2584. iframeMsg("tip", {
  2585. tip: "已关闭请求收费题库,已实时生效"
  2586. });
  2587. GM_setValue("start_pay", event.data.flag);
  2588. iframeMsg("start_pay", false);
  2589. }
  2590. } else if (event.data.type === "auto_jump") {
  2591. GM_setValue("auto_jump", event.data.flag);
  2592. iframeMsg("tip", {
  2593. tip: "已" + (event.data.flag ? "开启" : "关闭") + "自动切换,页面刷新后生效"
  2594. });
  2595. } else if (event.data.type === "confim") {
  2596. if (event.data.token.length === 10 || event.data.token.length === 11) {
  2597. GM_setValue("token", event.data.token);
  2598. iframeMsg("tip", {
  2599. tip: "成功设置token,请点击开启付费题库"
  2600. });
  2601. } else {
  2602. iframeMsg("tip", {
  2603. tip: "系统检测您的token可能输入有误,请检查"
  2604. });
  2605. }
  2606. } else if (event.data.type === "save_setting") {
  2607. GM_setValue("gpt", event.data.gpt);
  2608. GM_setValue("search_delay", event.data.search_delay);
  2609. GM_setValue("tiku_adapter", event.data.tiku_adapter);
  2610. }
  2611. }, false);
  2612. $(document).keydown(function(event) {
  2613. if (event.keyCode === 38) {
  2614. $("." + modelId).hide();
  2615. } else if (event.keyCode === 40) {
  2616. $("." + modelId).show();
  2617. } else if (event.keyCode === 37) {
  2618. $("." + modelId).hide();
  2619. GM_setValue("hide", true);
  2620. } else if (event.keyCode === 39) {
  2621. $("." + modelId).show();
  2622. GM_setValue("hide", false);
  2623. GM_setValue("pos", "50px,50px");
  2624. } else if (event.keyCode === 83) {
  2625. GLOBAL.stop = true;
  2626. iframeMsg("stop", GLOBAL.stop);
  2627. } else if (event.keyCode === 68) {
  2628. GLOBAL.stop = false;
  2629. iframeMsg("stop", GLOBAL.stop);
  2630. }
  2631. });
  2632. function getAnswerForKey(keys, options) {
  2633. return keys.map(function(val) {
  2634. return options[val.charCodeAt(0) - 65];
  2635. });
  2636. }
  2637. function setIntervalFunc(flag, func, time) {
  2638. const interval = setInterval(() => {
  2639. if (flag()) {
  2640. clearInterval(interval);
  2641. func();
  2642. }
  2643. }, time || 1e3);
  2644. }
  2645. function getAnswer(str, options, type) {
  2646. if (type === 0 || type === 1) {
  2647. const ans = getAnswerForKey(str.match(/[A-G]/gi) || [], options);
  2648. return ans.length > 0 ? ans : [ str ];
  2649. } else {
  2650. return [ str ];
  2651. }
  2652. }
  2653. function getQuestionType(str) {
  2654. if (!str) return;
  2655. str = str.trim().replaceAll(/\s+/g, "");
  2656. if (TYPE[str]) return TYPE[str];
  2657. const regex = Object.keys(TYPE).join("|");
  2658. const matcher = str.match(regex);
  2659. if (matcher) return TYPE[matcher[0]];
  2660. }
  2661. function rand(m, n) {
  2662. return Math.ceil(Math.random() * (n - m + 1) + m - 1);
  2663. }
  2664. const TYPE = {
  2665. "阅读理解(选择)/完型填空": 66,
  2666. "听力训练": 66,
  2667. multichoice: 1,
  2668. singlechoice: 0,
  2669. SingleChoice: 0,
  2670. bijudgement: 3,
  2671. Judgement: 3,
  2672. "单项选择题": 0,
  2673. "单项选择": 0,
  2674. "单选题": 0,
  2675. "单选": 0,
  2676. "多选": 1,
  2677. "多选题": 1,
  2678. "案例分析": 1,
  2679. "多项选择题": 1,
  2680. "多项选择": 1,
  2681. "客观题": 1,
  2682. "填空题": 2,
  2683. "填空": 2,
  2684. "对错题": 3,
  2685. "判断题": 3,
  2686. "判断正误": 3,
  2687. "判断": 3,
  2688. "主观题": 4,
  2689. "问答题": 4,
  2690. "简答题": 4,
  2691. "名词解释": 5,
  2692. "论述题": 6,
  2693. "计算题": 7,
  2694. "其它": 8,
  2695. "分录题": 9,
  2696. "资料题": 10,
  2697. "连线题": 11,
  2698. "排序题": 13,
  2699. "完形填空": 14,
  2700. "完型填空": 14,
  2701. "阅读理解": 15,
  2702. "口语题": 18,
  2703. "听力题": 19,
  2704. "A1A2题": 1,
  2705. "文件作答": 4,
  2706. "视频题": 1
  2707. };
  2708. function sleep(time) {
  2709. return new Promise(resolve => {
  2710. setTimeout(resolve, time);
  2711. });
  2712. }
  2713. function iframeMsg(type, message) {
  2714. try {
  2715. top.document.getElementById("iframeNode").contentWindow.vueDefinedProp(type, message);
  2716. } catch (e) {}
  2717. }
  2718. function filterImg(dom) {
  2719. if (location.host === "ncexam.cug.edu.cn") {
  2720. String.prototype.trim = function() {
  2721. return this.replace(/^\s+|\s+$/gm, "");
  2722. };
  2723. }
  2724. return $(dom).clone().find("img[src]").replaceWith(function() {
  2725. return $("<p></p>").text('<img src="' + $(this).attr("src") + '">');
  2726. }).end().find("iframe[src]").replaceWith(function() {
  2727. return $("<p></p>").text('<iframe src="' + $(this).attr("src") + '"></irame>');
  2728. }).end().text().trim();
  2729. }
  2730. function createContainer(name, childElem) {
  2731. name = name.toLowerCase();
  2732. let elem = top.document.createElement(name);
  2733. elem.style.display = "block";
  2734. elem.id = name.replace("hcsearche", "hcSearche").replace(/\-[a-z]/g, function(w) {
  2735. return w.replace("-", "").toUpperCase();
  2736. });
  2737. if (childElem) {
  2738. if (Array.isArray(childElem) === false) childElem = [ childElem ];
  2739. for (let i = 0; i < childElem.length; i++) elem.appendChild(childElem[i]);
  2740. }
  2741. return elem;
  2742. }
  2743. function dragModel(drag) {
  2744. const TOP = top;
  2745. drag.onmousedown = function(e) {
  2746. drag.style.cursor = "move";
  2747. e = e || window.event;
  2748. let diffX = e.clientX - drag.offsetLeft;
  2749. let diffY = e.clientY - drag.offsetTop;
  2750. top.onmousemove = function(e) {
  2751. e = e || top.event;
  2752. let left = e.clientX - diffX;
  2753. let top = e.clientY - diffY;
  2754. if (left < 0) {
  2755. left = 0;
  2756. } else if (left > TOP.innerWidth * .95 - drag.offsetWidth) {
  2757. left = TOP.innerWidth * .95 - drag.offsetWidth;
  2758. }
  2759. if (top < 0) {
  2760. top = 0;
  2761. } else if (top > TOP.innerHeight - drag.offsetHeight) {
  2762. top = TOP.innerHeight - drag.offsetHeight;
  2763. }
  2764. drag.style.left = left + "px";
  2765. drag.style.top = top + "px";
  2766. GM_setValue("pos", drag.style.left + "," + drag.style.top);
  2767. };
  2768. top.onmouseup = function(e) {
  2769. drag.style.cursor = "default";
  2770. this.onmousemove = null;
  2771. this.onmouseup = null;
  2772. };
  2773. };
  2774. }
  2775. function defaultWorkTypeResolver($options) {
  2776. function count(selector) {
  2777. let sum = 0;
  2778. for (const option of $options || []) {
  2779. if ($(option).find(selector).length || $(option).parent().find(selector).length) {
  2780. sum++;
  2781. }
  2782. }
  2783. return sum;
  2784. }
  2785. return count('[type="radio"]') === 2 ? 3 : count('[type="radio"]') > 2 ? 0 : count('[type="checkbox"]') > 2 ? 1 : count("textarea") >= 1 ? 4 : undefined;
  2786. }
  2787. function waitWithTimeout(promise, timeout, timeoutMessage = "timeout", defaultRes) {
  2788. let timer;
  2789. const timeoutPromise = new Promise((resolve, reject) => {
  2790. timer = setTimeout(() => defaultRes === undefined ? reject(timeoutMessage) : resolve(defaultRes), timeout);
  2791. });
  2792. return Promise.race([ timeoutPromise, promise ]).finally(() => clearTimeout(timer));
  2793. }
  2794. async function formatSearchAnswer(initData) {
  2795. const data = {
  2796. plat: initData.plat ? parseInt(initData.plat) : null,
  2797. qid: initData.qid ? String(initData.qid) : null,
  2798. question: initData.question,
  2799. options: initData.options,
  2800. options_id: initData.options_id ? initData.options_id : [],
  2801. type: initData.type
  2802. };
  2803. let res;
  2804. const list = [];
  2805. const apis = GLOBAL.answerApi;
  2806. const answerApiFunc = Object.keys(apis).map(item => {
  2807. return waitWithTimeout(apis[item](data), 5e3, "", []);
  2808. });
  2809. answerApiFunc.push(searchAnswer(data));
  2810. const answerApiRes = await waitWithTimeout(Promise.all(answerApiFunc), 1e4, "(接口超时)");
  2811. answerApiRes.map(item => {
  2812. if (item instanceof Array) {
  2813. console.log("tikuAdapter结果", JSON.stringify(item));
  2814. list.push(...item);
  2815. } else if (item instanceof Object && Object.keys(item).length === 1) {
  2816. const key = Object.keys(item)[0];
  2817. item[key];
  2818. } else {
  2819. res = item;
  2820. }
  2821. });
  2822. try {
  2823. const msg = res.message || res.msg;
  2824. if (res.code !== 0) {
  2825. return {
  2826. success: false,
  2827. msg: msg
  2828. };
  2829. }
  2830. if (res.result.success) {
  2831. return {
  2832. success: true,
  2833. msg: msg,
  2834. num: res.result.num,
  2835. answers: res.result.answers
  2836. };
  2837. }
  2838. console.log("官方结果", JSON.stringify(res));
  2839. if (res.result.answers instanceof Array && res.result.answers.length > 0) {
  2840. list.push(...res.result.answers);
  2841. }
  2842. return {
  2843. success: true,
  2844. msg: msg,
  2845. num: res.result.num,
  2846. list: list
  2847. };
  2848. } catch (e) {
  2849. return {
  2850. success: false,
  2851. msg: "发生异常" + e + "请反馈至QQ群" + QQ_GROUP
  2852. };
  2853. }
  2854. }
  2855. function similar(s, t, f) {
  2856. if (!s || !t) {
  2857. return 0;
  2858. }
  2859. if (s === t) {
  2860. return 100;
  2861. }
  2862. var l = s.length > t.length ? s.length : t.length;
  2863. var n = s.length;
  2864. var m = t.length;
  2865. var d = [];
  2866. f = f || 2;
  2867. var min = function(a, b, c) {
  2868. return a < b ? a < c ? a : c : b < c ? b : c;
  2869. };
  2870. var i, j, si, tj, cost;
  2871. if (n === 0) return m;
  2872. if (m === 0) return n;
  2873. for (i = 0; i <= n; i++) {
  2874. d[i] = [];
  2875. d[i][0] = i;
  2876. }
  2877. for (j = 0; j <= m; j++) {
  2878. d[0][j] = j;
  2879. }
  2880. for (i = 1; i <= n; i++) {
  2881. si = s.charAt(i - 1);
  2882. for (j = 1; j <= m; j++) {
  2883. tj = t.charAt(j - 1);
  2884. if (si === tj) {
  2885. cost = 0;
  2886. } else {
  2887. cost = 1;
  2888. }
  2889. d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
  2890. }
  2891. }
  2892. let res = (1 - d[n][m] / l) * 100;
  2893. return res.toFixed(f);
  2894. }
  2895. function answerSimilar(src, list) {
  2896. return $.map(list, function(val) {
  2897. return Number(similar(formatString(val), formatString(src), 2));
  2898. });
  2899. }
  2900. function isPlainAnswer(answer) {
  2901. if (answer.length > 8 || !/[A-Z]/.test(answer)) {
  2902. return false;
  2903. }
  2904. let min = 0;
  2905. for (let i = 0; i < answer.length; i++) {
  2906. if (answer.charCodeAt(i) < min) {
  2907. return false;
  2908. }
  2909. min = answer.charCodeAt(i);
  2910. }
  2911. return true;
  2912. }
  2913. function isTrue(str) {
  2914. return Boolean(String(str).match(/(^|,)(正确|是|对|√|T|ri|true|A)(,|$)/));
  2915. }
  2916. function isFalse(str) {
  2917. return Boolean(String(str).match(/(^|,)(错误|否|错|×|F|不是|wr|false|B)(,|$)/));
  2918. }
  2919. async function defaultQuestionResolve(list, data, handler, ignore_click) {
  2920. let targetOptionsList = [];
  2921. for (const answers of list) {
  2922. if (data.type === 4 || data.type === 2 || data.type === 5) {
  2923. let ans = answers.length > data.$options.length ? answers.slice(0, data.$options.length) : answers;
  2924. for (let index in ans) {
  2925. if (typeof handler === "function") await handler(data.type, ans[index], data.$options.eq(index));
  2926. }
  2927. return {
  2928. style: "success-row",
  2929. ans: answers.join("===="),
  2930. question: data.question
  2931. };
  2932. } else if (data.type === 3) {
  2933. if (targetOptionsList.length > 3) break;
  2934. let targetOptions = new Set();
  2935. if (isTrue(answers.join())) {
  2936. targetOptions.add(Number(isFalse(data.options[0])));
  2937. } else if (isFalse(answers.join())) {
  2938. targetOptions.add(Number(isTrue(data.options[0])));
  2939. }
  2940. targetOptions.size > 0 && targetOptionsList.push(targetOptions);
  2941. } else if (data.type === 0 || data.type === 1 || data.type === 66) {
  2942. const beautifulOptions = data.options.map(i => {
  2943. return formatString(i).toLowerCase().replace(/\s/g, "");
  2944. });
  2945. let targetOptions = new Set();
  2946. for (const ans of answers) {
  2947. if (ans.length === 1 && isPlainAnswer(ans)) {
  2948. targetOptions.add(ans.charCodeAt(0) - 65);
  2949. }
  2950. const val = formatString(ans).toLowerCase().replace(/\s/g, "");
  2951. let optIndex = $.inArray(val, beautifulOptions);
  2952. if (optIndex >= 0) {
  2953. targetOptions.add(optIndex);
  2954. }
  2955. }
  2956. if ((data.type === 0 && targetOptions.size === 0 || data.type === 1 && targetOptions.size < 2) && targetOptionsList.length === 0) {
  2957. for (const ans of answers) {
  2958. const val = formatString(ans).toLowerCase();
  2959. if (val.length >= 5 && !val.includes("<img")) {
  2960. const ratings = answerSimilar(val, beautifulOptions);
  2961. const maxScore = Math.max(...ratings);
  2962. if (maxScore > 65) {
  2963. targetOptions.add(ratings.indexOf(maxScore));
  2964. }
  2965. }
  2966. }
  2967. }
  2968. targetOptions.size > 0 && targetOptionsList.push(targetOptions);
  2969. }
  2970. }
  2971. let items = [];
  2972. let sortArr = targetOptionsList.map(item => {
  2973. const s = Array.from(item).sort();
  2974. return s;
  2975. });
  2976. if (data.type === 0 || data.type === 3) {
  2977. items = getMost(sortArr.filter(i => i.length === 1));
  2978. if (!items || items.length === 0) {
  2979. items = getMost(sortArr.filter(i => i.length > 0));
  2980. }
  2981. } else if (data.type === 1 || data.type === 66) {
  2982. items = getMost(sortArr.filter(i => i.length > 1));
  2983. if (!items || items.length === 0) {
  2984. items = getLang(sortArr.filter(i => i.length > 0));
  2985. }
  2986. }
  2987. if (items && items.length > 0) {
  2988. for (let index = 0; index < data.$options.length; index++) {
  2989. const $item = data.$options.eq(index);
  2990. if (Boolean($.inArray(index, items) + 1) !== Boolean(ignore_click($item, data.type))) {
  2991. $item.get(0).click();
  2992. await sleep(GLOBAL.fillAnswerDelay);
  2993. }
  2994. }
  2995. return {
  2996. type: data.type,
  2997. style: "primary-row",
  2998. ans: items.map(i => {
  2999. return data.options[i];
  3000. }).join("===="),
  3001. question: data.question
  3002. };
  3003. } else {
  3004. return {
  3005. type: data.type,
  3006. style: "warning-row",
  3007. question: data.question,
  3008. ans: list.join('<span style="color: red">====</span>'),
  3009. options: data.options
  3010. };
  3011. }
  3012. }
  3013. async function defaultFillAnswer(answers, data, handler, ignore_click) {
  3014. for (let index = 0; index < data.$options.length; index++) {
  3015. const $item = data.$options.eq(index);
  3016. if (Boolean($.inArray(index, answers) + 1) !== Boolean(ignore_click($item, data.type))) {
  3017. $item.get(0).click();
  3018. await sleep(GLOBAL.fillAnswerDelay);
  3019. }
  3020. }
  3021. return {
  3022. type: data.type,
  3023. style: "success-row",
  3024. question: data.question,
  3025. ans: answers.map(i => {
  3026. return String.fromCharCode(i + 65);
  3027. }).join(""),
  3028. options: data.options
  3029. };
  3030. }
  3031. function getMost(arr) {
  3032. arr.reverse();
  3033. if (arr.length === 0) return undefined;
  3034. var hash = {};
  3035. var m = 0;
  3036. var trueEl;
  3037. var el;
  3038. for (var i = 0, len = arr.length; i < len; i++) {
  3039. el = arr[i];
  3040. hash[el] === undefined ? hash[el] = 1 : hash[el]++;
  3041. if (hash[el] >= m) {
  3042. m = hash[el];
  3043. trueEl = el;
  3044. }
  3045. }
  3046. return trueEl;
  3047. }
  3048. function getLang(arr) {
  3049. if (arr.length === 0) return undefined;
  3050. let len = 0;
  3051. let ele;
  3052. for (let arrElement of arr) {
  3053. if (arrElement.length > len) {
  3054. len = arrElement.length;
  3055. ele = arrElement;
  3056. }
  3057. }
  3058. return ele ? ele : arr.length > 0 ? arr[0] : [];
  3059. }
  3060. function HTMLDecode(text) {
  3061. var temp = document.createElement("div");
  3062. temp.innerHTML = text;
  3063. var output = temp.innerText || temp.textContent;
  3064. temp = null;
  3065. return output;
  3066. }
  3067. function formatString(src) {
  3068. src = String(src);
  3069. src = src.includes("img") || src.includes("iframe") ? src : HTMLDecode(src);
  3070. src = src.replace(/[\uff01-\uff5e]/g, function(str) {
  3071. return String.fromCharCode(str.charCodeAt(0) - 65248);
  3072. });
  3073. return src.replace(/\s+/g, " ").replace(/[“”]/g, '"').replace(/[‘’]/g, "'").replace(/。/g, ".").replace(/[,.?:!;]$/, "").trim();
  3074. }
  3075. function division(arr, size) {
  3076. var objArr = new Array();
  3077. var index = 0;
  3078. var objArrLen = arr.length / size;
  3079. for (var i = 0; i < objArrLen; i++) {
  3080. var arrTemp = new Array();
  3081. for (var j = 0; j < size; j++) {
  3082. arrTemp[j] = arr[index++];
  3083. if (index === arr.length) {
  3084. break;
  3085. }
  3086. }
  3087. objArr[i] = arrTemp;
  3088. }
  3089. return objArr;
  3090. }
  3091. const cache = {};
  3092. const sourceTable = JSON.parse(GM_getResourceText("SourceTable"));
  3093. async function genTable(ttf) {
  3094. const res = await axios.get(ttf, {
  3095. responseType: "arraybuffer"
  3096. });
  3097. const font = Typr.parse(res.data)[0];
  3098. const table = {};
  3099. for (let i = 19968; i < 40870; i++) {
  3100. const g = Typr.U.codeToGlyph(font, i);
  3101. if (g) {
  3102. const path = Typr.U.glyphToPath(font, g);
  3103. if (path) {
  3104. table[i] = MD5(JSON.stringify(path));
  3105. }
  3106. }
  3107. }
  3108. cache[ttf] = table;
  3109. }
  3110. async function getEncryptString(str, ttf) {
  3111. if (!cache[ttf]) {
  3112. await genTable(ttf);
  3113. }
  3114. const match = str.match(/<span class="xuetangx-com-encrypted-font">(.*?)</g);
  3115. if (match === null) {
  3116. return formatString(str);
  3117. }
  3118. const encStrArr = match.map(string => {
  3119. return string.replace(/^<span class="xuetangx-com-encrypted-font">/, "").replace(/<$/, "");
  3120. });
  3121. encStrArr.forEach(encStr => {
  3122. const decStr = encStr.split("").map(string => {
  3123. const md5 = cache[ttf][string.charCodeAt(0)];
  3124. return String.fromCharCode(sourceTable[md5]);
  3125. }).join("");
  3126. str = str.replace(encStr, decStr);
  3127. });
  3128. return formatString(str);
  3129. }
  3130. var vm = {
  3131. hideTip() {
  3132. var tip = document.createElement("div");
  3133. tip.id = "yinc";
  3134. tip.innerHTML = `
  3135. <div style="
  3136. position:fixed;
  3137. right:0;
  3138. top:10%;
  3139. color: #8a6d3b;
  3140. background-color: #fcf8e3;
  3141. padding: 15px;
  3142. margin-bottom: 20px;
  3143. border: 1px solid transparent;
  3144. border-radius: 4px;
  3145. border-color: #faebcc;">
  3146. 万能脚本已被隐藏<br>如果需要显示答题面板,请按键盘右箭头
  3147. <button style="
  3148. padding: 0;
  3149. color: inherit;
  3150. border: 0;
  3151. background: inherit;
  3152. top:-22px;
  3153. position:relative"
  3154. type="button" id="cl_yinc" data-dismiss="alert" aria-label="Close">&times;</button>
  3155. </div>`;
  3156. top.document.getElementsByTagName("body")[0].appendChild(tip);
  3157. top.document.querySelector("#cl_yinc").onclick = function() {
  3158. top.document.querySelector("#yinc").remove();
  3159. };
  3160. setTimeout(() => {
  3161. top.document.querySelector("#yinc").remove();
  3162. }, 3e3);
  3163. },
  3164. zhihuishuSaveTip() {
  3165. var zhihuishuSaveTip = document.createElement("div");
  3166. zhihuishuSaveTip.id = "zhihuishuSaveTip";
  3167. zhihuishuSaveTip.innerHTML = `
  3168. <div style="
  3169. position: fixed;
  3170. opacity: 1;
  3171. top: 0;
  3172. right: 0;
  3173. bottom: 0;
  3174. left: 0;
  3175. z-index: 1040;
  3176. background:rgba(0,0,0,.46);">
  3177. <div style="
  3178. position: relative;
  3179. margin: 10px;
  3180. top: 50%;
  3181. left: 40%;
  3182. width: 20%;">
  3183. <div style="
  3184. position: relative;
  3185. background-color: #fff;
  3186. -webkit-background-clip: padding-box;
  3187. background-clip: padding-box;
  3188. /*border: 1px solid #999;*/
  3189. border: 1px solid rgba(0,0,0,.2);
  3190. border-radius: 6px;
  3191. outline: 0;
  3192. -webkit-box-shadow: 0 3px 9px rgba(0,0,0,.5);
  3193. box-shadow: 0 3px 9px rgba(0,0,0,.5);">
  3194. <div style="
  3195. line-height: 25px;
  3196. font-size: 15px;
  3197. margin: 5px;">
  3198. <h4 class="modal-title">正在保存</h4>
  3199. <!-- 模态框主体 -->
  3200. <div class="modal-body" style="height: 50px;
  3201. margin: 5px;
  3202. padding: 5px;
  3203. margin-top: 15px;
  3204. line-height: 15px;
  3205. font-size: 15px;">
  3206. <progress style="width: 100%" id="gs_p" value="0" max="100"></progress> <span id="gs_text">0%</span>
  3207. </div>
  3208. </div>
  3209. </div>
  3210. </div>`;
  3211. top.document.getElementsByTagName("body")[0].appendChild(zhihuishuSaveTip);
  3212. }
  3213. };
  3214. function showPanel() {
  3215. let html = `
  3216. <!DOCTYPE html>
  3217. <html lang="en">
  3218. <head>
  3219. <meta charset="UTF-8">
  3220. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  3221. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  3222. <style>
  3223. ` + GM_getResourceText("ElementUiCss") + `
  3224. .el-table .warning-row {
  3225. background: oldlace;
  3226. }
  3227. .message-update-tip {
  3228. width: 300px;
  3229. }
  3230. .el-table .success-row {
  3231. background: #f0f9eb;
  3232. }
  3233. .el-table .primary-row {
  3234. background: rgb(236, 245, 255);
  3235. }
  3236. *{
  3237. padding: 0px;
  3238. margin: 0px;
  3239. }
  3240. .el-button{
  3241. margin-bottom: 4px;
  3242. }
  3243. .el-button + .el-button{
  3244. margin-left: 0px;
  3245. }
  3246.  
  3247. .el-form
  3248. -item-confim{
  3249. display: flex;
  3250. justify-content: center
  3251. }
  3252. .drag_auto_answer-class{
  3253. width: 321px;
  3254. background-color: rgb(255, 255, 255);
  3255. overflow-x: hidden;
  3256. overflow-y: scroll;
  3257. position: absolute;
  3258. top: 0;
  3259. bottom: 0;
  3260. left: 0;
  3261. right: -17px;
  3262. }
  3263. </style>
  3264. </head>
  3265. <body>
  3266. <div id="app">
  3267. <el-dialog title="更多设置" :visible.sync="show_setting" width="300px">
  3268. <el-form ref="form" label-width="100px" size="mini">
  3269. <el-form-item label="ChatGPT答题">
  3270. <el-select v-model="gpt">
  3271. <el-option label="不开启" value="-1"></el-option>
  3272. <el-option label="使用GPT3.5" value="3"></el-option>
  3273. <el-option disabled label="使用GPT4" value="4"></el-option>
  3274. </el-select>
  3275. </el-form-item>
  3276. <el-form-item label="搜题延迟(秒)">
  3277. <el-input-number v-model="search_delay" :min="0" :max="30"></el-input-number>
  3278. </el-form-item>
  3279. <el-popover
  3280. ref="popover"
  3281. placement="top-start"
  3282. title="tikuAdapter题库适配器"
  3283. width="200"
  3284. trigger="hover"
  3285. content="大学生网课题库接口适配器:聚合多家题库,更精确的查题。详细查看 https://github.com/DokiDoki1103/tikuAdapter">
  3286. </el-popover>
  3287. <el-form-item v-popover:popover label="题库适配器url">
  3288. <el-input v-model="tiku_adapter"></el-input>
  3289. </el-form-item>
  3290. </el-form>
  3291. <div slot="footer" class="dialog-footer">
  3292. <el-button size="mini" @click="show_setting = false">取消</el-button>
  3293. <el-button size="mini" type="primary" @click="save_setting">保存</el-button>
  3294. </div>
  3295. </el-dialog>
  3296. <div id="drag_auto_answer" class="drag_auto_answer-class">
  3297. <el-main style="min-width: 321px;padding: 15px 0px 0px; z-index: 99999;">
  3298. <el-row>
  3299. <el-form>
  3300. <el-form-item class="el-form-item-confim" label="请输入token" style="margin-top: -20px" :prop="passw">
  3301. <el-input :type="passw" v-model="opt.token" placeholder="请输入内容" style="max-width: 130px" size="mini" ></el-input>
  3302. <el-button @click="btnClick(opt.token,'opt.confim')" size="mini" type="warning" @mousedown.native="passw = 'text'" @mouseup.native="passw = 'password'">确定</el-button>
  3303. </el-form-item>
  3304. </el-form>
  3305. </el-row>
  3306. <el-row style="margin-top: -20px;margin-bottom: 5px;display: flex">
  3307. <el-alert
  3308. style="display: block"
  3309. :title="tip"
  3310. :closable="false"
  3311. type="success">
  3312. <el-button v-if="need_jump" @click="btnClick(opt.jump,'opt.jump')" size="mini" type="info">跳过本题</el-button>
  3313. <el-button v-if="!hidden" @click="btnClick(opt.auto_jump,'opt.auto_jump')" size="mini" type="warning">{{opt.auto_jump ? '停止自动切换': '开启自动切换'}}</el-button>
  3314. </el-alert>
  3315. </el-row>
  3316. <el-row>
  3317. <el-button v-if="!hidden" @click="btnClick(opt.stop,'opt.stop')" size="mini" type="success">{{!opt.stop ? '暂停答题': '继续答题'}}</el-button>
  3318. <el-button @click="btnClick(opt.start_pay,'opt.start_pay')" size="mini" type="primary">{{opt.start_pay ?'关闭收费题库' : '开启收费题库'}}</el-button>
  3319. <el-button size="mini" type="danger"><a style="text-decoration:none;color: aliceblue" target="_blank" href="https://lyck6.cn/pay" >获取积分</a></el-button>
  3320. <el-button @click="show_setting = true" size="mini" type="info">更多设置</el-button>
  3321. </el-row>
  3322.  
  3323. <el-table size="mini" :data="tableData" style="width: 100%;margin-top: 5px" :row-class-name="tableRowClassName">
  3324. <el-table-column prop="index" label="题号" width="45"></el-table-column>
  3325. <el-table-column prop="question" label="问题" width="130">
  3326. <template slot-scope="scope">
  3327. <div style="font-size: 11px;" v-html="scope.row.question"></div>
  3328. </template>
  3329. </el-table-column>
  3330. <el-table-column prop="answer" label="答案" width="130">
  3331. <template slot-scope="scope">
  3332. <el-popover
  3333. v-if="scope.row.style === 'warning-row'"
  3334. placement="bottom-end"
  3335. title="相似答案"
  3336. width="240"
  3337. trigger="click">
  3338. <div style="font-size: 10px;height: 220px; overflow: auto;" v-html="scope.row.answer"></div>
  3339. <el-button slot="reference" size="small" type="danger">查看相关答案</el-button>
  3340. </el-popover>
  3341. <p v-if="scope.row.style != 'warning-row'" style="font-size: 11px;" v-html="scope.row.answer"></p>
  3342. </template>
  3343. </el-table-column>
  3344. </el-table>
  3345. </el-main>
  3346. </div>
  3347. </div>
  3348. </body>
  3349. <script>` + GM_getResourceText("Vue") + `</script>
  3350. <script>` + GM_getResourceText("ElementUi") + `</script>
  3351. <script>
  3352. const tips = [
  3353. '想要隐藏此搜索框,按键盘的⬆箭头,想要显示按⬇箭头哦',
  3354. '想要永久隐藏此搜索框,按键盘的左箭头,想要显示在屏幕中央按右箭头哦',
  3355. '想要自定义搜索框的长度可以更改代码设置参数:length',
  3356. '脚本代码设置页预留多个自定义参数哦,可自行更改',
  3357. '脚本已经适配tikuAdapter了,可点击【更多设置】配置请求URL'
  3358. ]
  3359. new Vue({
  3360. el: '#app',
  3361. data: function () {
  3362. return {
  3363. tiku_adapter: '` + (GM_getValue("tiku_adapter") || "") + `',
  3364. search_delay: ` + (isNaN(parseInt(GM_getValue("search_delay"))) ? 2 : GM_getValue("search_delay")) + `,
  3365. gpt: String(` + (GM_getValue("gpt") || -1) + `),
  3366. show_setting: false,
  3367. hidden: false,
  3368. need_jump: false,
  3369. tip: tips[Math.floor(Math.random()*tips.length)],
  3370. opt:{
  3371. token: '` + GM_getValue("token") + `',
  3372. auto_jump: ` + GM_getValue("auto_jump") + `,
  3373. stop: false,
  3374. start_pay: ` + GM_getValue("start_pay") + `
  3375. },
  3376. input: '',
  3377. visible: false,
  3378. tableData: [],
  3379. passw:"password"
  3380. }
  3381. },
  3382. created(){
  3383. /**
  3384. *
  3385. * @param type 消息类型
  3386. * @param receiveParams 消息参数
  3387. */
  3388. window['vueDefinedProp'] = (type,receiveParams) => {
  3389. if (type === 'push'){
  3390. let length = this.tableData.length
  3391. this.tableData.push({index: length + 1,question: receiveParams.question,answer: receiveParams.answer,style:receiveParams.style})
  3392. }else if (type === 'clear'){
  3393. this.tableData = []
  3394. }else if (type === 'tip'){
  3395. if (receiveParams.type && receiveParams.type === 'jump'){
  3396. window.parent.postMessage({"type": 'jump'}, '*');
  3397. }else if (receiveParams.type && receiveParams.type === 'error'){
  3398. this.need_jump = true
  3399. }else if (receiveParams.type && receiveParams.type === 'hidden'){
  3400. this.hidden = true
  3401. }else if (receiveParams.type && receiveParams.type === 'stop'){
  3402. this.opt.stop = true
  3403. }
  3404. this.tip = receiveParams.tip
  3405. }else if (type === 'stop'){
  3406. this.opt.stop = receiveParams
  3407. }else if (type === 'start_pay'){
  3408. this.opt.start_pay = receiveParams
  3409. }else if (type === 'update'){
  3410. this.updateScript(receiveParams.v1,receiveParams.v2,receiveParams.href)
  3411. }
  3412. }
  3413. },
  3414. methods: {
  3415. save_setting(){
  3416. window.parent.postMessage({type: 'save_setting',search_delay:this.search_delay,gpt:this.gpt,tiku_adapter:this.tiku_adapter}, '*');
  3417. this.show_setting = false
  3418. },
  3419. updateScript(currentVersion,newVersion,href){
  3420. this.$confirm('您当前版本为'+currentVersion+'最新版本为'+newVersion+',推荐下载更新', '脚本有更新', {
  3421. customClass: 'message-update-tip',
  3422. confirmButtonText: '确定',
  3423. cancelButtonText: '取消',
  3424. type: 'warning'
  3425. }).then(() => {
  3426. window.open(href)
  3427. });
  3428. setTimeout(()=>{
  3429. this.$msgbox.close();
  3430. },5000)
  3431. },
  3432. tableRowClassName({row, rowIndex}) {
  3433. return row.style
  3434. },
  3435. btnClick(e,type){
  3436. if (type === 'opt.stop'){//暂停搜索
  3437. this.opt.stop = !this.opt.stop
  3438. this.tip = this.opt.stop? '已暂停搜索': '继续搜索'
  3439. window.parent.postMessage({type: 'stop',val:this.opt.stop}, '*');
  3440. }else if (type === 'opt.start_pay'){
  3441. window.parent.postMessage({type: 'start_pay',flag:!this.opt.start_pay}, '*');
  3442. }else if (type === 'opt.auto_jump'){//开启自动切换
  3443. this.opt.auto_jump = ! this.opt.auto_jump
  3444. window.parent.postMessage({type: 'auto_jump',flag:this.opt.auto_jump}, '*');
  3445. }else if (type === 'opt.jump'){//跳过本题
  3446. window.parent.postMessage({type: 'jump'}, '*');
  3447. this.need_jump = false
  3448. }else if (type === 'opt.confim'){
  3449. window.parent.postMessage({type: 'confim',token:e}, '*');
  3450. }
  3451. }
  3452. }
  3453. })
  3454. </script>
  3455. </html>
  3456. `;
  3457. addModal2(html);
  3458. checkVersion();
  3459. }
  3460. function addModal2(html, newPos, footerChildNode = false) {
  3461. let headersNode = createContainer("hcsearche-modal-links");
  3462. let adNode = top.document.createElement("img");
  3463. let item = {
  3464. url: GM_getResourceURL("Img")
  3465. };
  3466. const getAdList = GM_getValue("adList");
  3467. if (getAdList) {
  3468. const adList = JSON.parse(getAdList);
  3469. let lastShown = GM_getValue("lastShown") || 0;
  3470. item = adList[lastShown];
  3471. GM_setValue("lastShown", (lastShown + 1) % adList.length);
  3472. item.base64 = GM_getValue(item.hash);
  3473. }
  3474. adNode.setAttribute("src", item.base64);
  3475. adNode.setAttribute("draggable", "false");
  3476. adNode.setAttribute("style", "display: block;width:321px");
  3477. if (item.click) {
  3478. adNode.setAttribute("onmousedown", "let ts=new Date().getTime();this.onmouseup=()=>{if(new Date().getTime()-ts>100){return false;};window.open('" + item.click + "','_black');this.onmouseup=undefined}");
  3479. }
  3480. headersNode.appendChild(adNode);
  3481. let iframeNode = top.document.createElement("iframe");
  3482. iframeNode.id = "iframeNode";
  3483. iframeNode.setAttribute("width", "100%");
  3484. iframeNode.setAttribute("height", GLOBAL.length + "px");
  3485. iframeNode.setAttribute("style", "height:" + GLOBAL.length + "px");
  3486. iframeNode.setAttribute("frameborder", "0");
  3487. iframeNode.srcdoc = html;
  3488. let contentNode = createContainer("content-modal", [ headersNode, iframeNode ]);
  3489. let modal = renderModal(contentNode);
  3490. dragModel(modal);
  3491. if (GM_getValue("hide")) {
  3492. $("#" + modelId).hide();
  3493. vm.hideTip();
  3494. }
  3495. }
  3496. function renderModal(childElem, newPos) {
  3497. return render(String.fromCharCode(rand(65, 90), rand(65, 90), rand(65, 90)) + rand(1, 100).toString(), modelId, childElem);
  3498. }
  3499. function render(tagName, elemId, childElem, isFixed, newPos) {
  3500. let doc = top.document;
  3501. let elem = doc.getElementById(elemId);
  3502. if (elem) {
  3503. elem.innerHTML = "";
  3504. } else {
  3505. elem = doc.createElement(tagName);
  3506. elem.id = elemId;
  3507. doc.body.appendChild(elem);
  3508. }
  3509. let contentNode = createContainer(tagName + "-container", childElem);
  3510. elem.appendChild(contentNode);
  3511. elem.classList.add(elemId);
  3512. elem.style.zIndex = "9999999";
  3513. elem.style.position = "fixed";
  3514. const pos = GM_getValue("pos") === undefined ? "30px,30px" : GM_getValue("pos");
  3515. const posarr = pos.split(",");
  3516. elem.style.left = posarr[0];
  3517. elem.style.top = posarr[1];
  3518. setTimeout(function() {
  3519. elem.classList.add(elemId + "-show");
  3520. }, 10);
  3521. return elem;
  3522. }
  3523. const init$1 = async ($TiMu, select, wrap) => {
  3524. let question = formatString(filterImg($TiMu.find(select.elements.question)));
  3525. if (select.elements.type && select.elements.type.includes("input[name^=type]:eq")) {
  3526. select.elements.type = "input[name^=type]:eq(" + GLOBAL.i + ")";
  3527. }
  3528. let data = {
  3529. $item: $TiMu,
  3530. question_text: $TiMu.find(select.elements.question).text(),
  3531. question: question.length === 0 ? $TiMu.find(select.elements.question) : question.replace(/^\d+、/, "").replace(/[((](\d+\s?(\.\d+)?分)[))]$/, "").replace(/^((\d+.(\s+)?)?)[\[((【](.*?)[】))\]]/, "").trim(),
  3532. $options: select.elements.$options ? $TiMu.find(select.elements.$options) : undefined,
  3533. options: select.elements.options ? jQuery.map($TiMu.find(select.elements.options), function(val) {
  3534. return formatString(filterImg(val)).replace(/^[A-Ga-g][.、]/, "").trim();
  3535. }) : undefined
  3536. };
  3537. if (select.elements.type) {
  3538. const getType = getQuestionType($TiMu.find(select.elements.type).text());
  3539. const val = $TiMu.find(select.elements.type).val();
  3540. data.type = isNaN(getType) ? isNaN(val) ? val : parseInt(val) : getType;
  3541. } else {
  3542. data.type = defaultWorkTypeResolver(data.$options);
  3543. }
  3544. if (select.elements.answer) {
  3545. data.answer = getAnswer(filterImg($TiMu.find(select.elements.answer)) || $TiMu.find(select.elements.answer).val(), data.options, data.type);
  3546. }
  3547. if (data && data.type === 3 && data.options.length === 0) {
  3548. data.options = [ "正确", "错误" ];
  3549. }
  3550. const r = await wrap(data);
  3551. if (typeof r === "boolean") return undefined;
  3552. return data;
  3553. };
  3554. async function WorkerJSPlus(options) {
  3555. if (GLOBAL.isMatch) return;
  3556. const match = options.match ? typeof options.match === "boolean" ? options.match : options.match() : false;
  3557. if (!match) return;
  3558. GLOBAL.isMatch = true;
  3559. if (options.hook && typeof options.hook === "function") {
  3560. if (options.hook()) return;
  3561. }
  3562. const defaultFunc = () => {};
  3563. const main = () => {
  3564. setTimeout(() => {
  3565. showPanel();
  3566. if (options.init && typeof options.init === "function") {
  3567. if (options.init()) return;
  3568. }
  3569. const select = {
  3570. root: options.root,
  3571. elements: options.elements,
  3572. ignore_click: options.ignore_click
  3573. };
  3574. new WorkerJS(select, options.wrap ? options.wrap : defaultFunc, options.fill ? options.fill : defaultFunc, options.finished ? options.finished : defaultFunc, options.fillFinish ? options.fillFinish : defaultFunc).fillAnswer();
  3575. }, GLOBAL.delay);
  3576. };
  3577. if (options.intv) {
  3578. setIntervalFunc(options.intv, main);
  3579. } else {
  3580. main();
  3581. }
  3582. }
  3583. var WorkerJS = function(select, searchHander, fillHander, onFinish = function(need_jump) {}, fillFinish = function() {}) {
  3584. GLOBAL.index = 0;
  3585. this.init = init$1;
  3586. this.fillAnswer = async () => {
  3587. let arr = jQuery(select.root);
  3588. while (true) {
  3589. if (arr.length === 0) return;
  3590. await sleep((isNaN(parseInt(GM_getValue("search_delay"))) ? 2 : GM_getValue("search_delay")) * 1e3);
  3591. if (GLOBAL.stop) {
  3592. continue;
  3593. }
  3594. if (GLOBAL.index >= arr.length) {
  3595. let auto_jump = GM_getValue("auto_jump") === undefined || GM_getValue("auto_jump");
  3596. const next = await onFinish(auto_jump);
  3597. if (next) {
  3598. GLOBAL.index = 0;
  3599. setTimeout(this.fillAnswer, 300);
  3600. }
  3601. if (auto_jump) {
  3602. iframeMsg("tip", {
  3603. tip: "自动答题已完成,即将切换下一题"
  3604. });
  3605. next || setTimeout(() => {
  3606. iframeMsg("tip", {
  3607. type: "hidden",
  3608. tip: "自动答题已完成,请检查提交"
  3609. });
  3610. }, Math.max(GM_getValue("search_delay") || 2, 5) * 1e3);
  3611. } else {
  3612. iframeMsg("tip", {
  3613. tip: "自动答题已完成" + (arr.length === 1 ? ",请手动切换" : "请检查提交")
  3614. });
  3615. }
  3616. return true;
  3617. }
  3618. try {
  3619. let data = await this.init(jQuery(arr[GLOBAL.index++]), select, searchHander);
  3620. if (!data) {
  3621. GLOBAL.index--;
  3622. continue;
  3623. }
  3624. iframeMsg("tip", {
  3625. tip: "准备答第" + GLOBAL.index + "题"
  3626. });
  3627. const formatResult = await formatSearchAnswer(data);
  3628. const hookAnswer = data.answer && data.answer.length > 0 && GM_getValue("start_pay");
  3629. const formatAns = hookAnswer ? {
  3630. success: true,
  3631. num: formatResult.num,
  3632. list: [ data.answer ]
  3633. } : formatResult;
  3634. if (formatResult.answers || formatAns.success) {
  3635. iframeMsg("tip", {
  3636. tip: "准备填充答案," + (formatAns.num === -1 ? "免费题库不扣积分" : "剩余积分:" + formatAns.num)
  3637. });
  3638. const func = !hookAnswer && formatResult.answers ? defaultFillAnswer : defaultQuestionResolve;
  3639. let r = await func(hookAnswer ? formatAns.list : formatAns.answers ? formatResult.answers : formatAns.list, data, fillHander, select.ignore_click ? select.ignore_click : () => {
  3640. return false;
  3641. });
  3642. iframeMsg("push", {
  3643. index: GLOBAL.index,
  3644. question: r.question,
  3645. answer: r.ans,
  3646. style: r.style
  3647. });
  3648. GM_getValue("start_pay") && String(GM_getValue("token")).length === 10 && catchAnswer(r);
  3649. await fillFinish(r);
  3650. } else {
  3651. GLOBAL.index--;
  3652. iframeMsg("tip", {
  3653. tip: formatAns.msg
  3654. });
  3655. }
  3656. } catch (e) {
  3657. GLOBAL.index--;
  3658. console.table(e);
  3659. iframeMsg("tip", {
  3660. type: "error",
  3661. tip: location.host + "发生异常" + e + "请反馈至QQ群" + QQ_GROUP
  3662. });
  3663. }
  3664. }
  3665. };
  3666. };
  3667. // @thanks 特别感谢 qxin i 借鉴 网页限制解除(改) 开源地址 https://gf.qytechs.cn/zh-CN/scripts/28497
  3668. function init() {
  3669. rule = rwl_userData.rules.rule_def;
  3670. hook_eventNames = rule.hook_eventNames.split("|");
  3671. unhook_eventNames = rule.unhook_eventNames.split("|");
  3672. eventNames = hook_eventNames.concat(unhook_eventNames);
  3673. if (rule.dom0) {
  3674. setInterval(clearLoop, 10 * 1e3);
  3675. setTimeout(clearLoop, 1500);
  3676. window.addEventListener("load", clearLoop, true);
  3677. clearLoop();
  3678. }
  3679. if (rule.hook_addEventListener) {
  3680. EventTarget.prototype.addEventListener = addEventListener;
  3681. document.addEventListener = addEventListener;
  3682. if (hasFrame) {
  3683. for (let i = 0; i < hasFrame.length; i++) {
  3684. hasFrame[i].contentWindow.document.addEventListener = addEventListener;
  3685. }
  3686. }
  3687. }
  3688. if (rule.hook_preventDefault) {
  3689. Event.prototype.preventDefault = function() {
  3690. if (hook_eventNames.indexOf(this.type) < 0) {
  3691. Event_preventDefault.apply(this, arguments);
  3692. }
  3693. };
  3694. if (hasFrame) {
  3695. for (let i = 0; i < hasFrame.length; i++) {
  3696. hasFrame[i].contentWindow.Event.prototype.preventDefault = function() {
  3697. if (hook_eventNames.indexOf(this.type) < 0) {
  3698. Event_preventDefault.apply(this, arguments);
  3699. }
  3700. };
  3701. }
  3702. }
  3703. }
  3704. if (rule.hook_set_returnValue) {
  3705. Event.prototype.__defineSetter__("returnValue", function() {
  3706. if (this.returnValue !== true && hook_eventNames.indexOf(this.type) >= 0) {
  3707. this.returnValue = true;
  3708. }
  3709. });
  3710. }
  3711. }
  3712. function addEventListener(type, func, useCapture) {
  3713. var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
  3714. if (hook_eventNames.indexOf(type) >= 0) {
  3715. _addEventListener.apply(this, [ type, returnTrue, useCapture ]);
  3716. } else if (unhook_eventNames.indexOf(type) >= 0) {
  3717. var funcsName = storageName + type + (useCapture ? "t" : "f");
  3718. if (this[funcsName] === undefined) {
  3719. this[funcsName] = [];
  3720. _addEventListener.apply(this, [ type, useCapture ? unhook_t : unhook_f, useCapture ]);
  3721. }
  3722. this[funcsName].push(func);
  3723. } else {
  3724. _addEventListener.apply(this, arguments);
  3725. }
  3726. }
  3727. function clearLoop() {
  3728. rule = clear();
  3729. var elements = getElements();
  3730. for (var i in elements) {
  3731. for (var j in eventNames) {
  3732. var name = "on" + eventNames[j];
  3733. if (Object.prototype.toString.call(elements[i]) == "[object String]") {
  3734. continue;
  3735. }
  3736. if (elements[i][name] !== null && elements[i][name] !== onxxx) {
  3737. if (unhook_eventNames.indexOf(eventNames[j]) >= 0) {
  3738. elements[i][storageName + name] = elements[i][name];
  3739. elements[i][name] = onxxx;
  3740. } else {
  3741. elements[i][name] = null;
  3742. }
  3743. }
  3744. }
  3745. }
  3746. document.onmousedown = function() {
  3747. return true;
  3748. };
  3749. }
  3750. function returnTrue(e) {
  3751. return true;
  3752. }
  3753. function unhook_t(e) {
  3754. return unhook(e, this, storageName + e.type + "t");
  3755. }
  3756. function unhook_f(e) {
  3757. return unhook(e, this, storageName + e.type + "f");
  3758. }
  3759. function unhook(e, self, funcsName) {
  3760. var list = self[funcsName];
  3761. for (var i in list) {
  3762. list[i](e);
  3763. }
  3764. e.returnValue = true;
  3765. return true;
  3766. }
  3767. function onxxx(e) {
  3768. var name = storageName + "on" + e.type;
  3769. this[name](e);
  3770. e.returnValue = true;
  3771. return true;
  3772. }
  3773. function getElements() {
  3774. var elements = Array.prototype.slice.call(document.getElementsByTagName("*"));
  3775. elements.push(document);
  3776. var frames = document.querySelectorAll("frame");
  3777. if (frames) {
  3778. hasFrame = frames;
  3779. var frames_element;
  3780. for (let i = 0; i < frames.length; i++) {
  3781. frames_element = Array.prototype.slice.call(frames[i].contentWindow.document.querySelectorAll("*"));
  3782. elements.push(frames[i].contentWindow.document);
  3783. elements = elements.concat(frames_element);
  3784. }
  3785. }
  3786. return elements;
  3787. }
  3788. var settingData = {
  3789. status: 1,
  3790. version: .1,
  3791. message: "",
  3792. positionTop: "0",
  3793. positionLeft: "0",
  3794. positionRight: "auto",
  3795. addBtn: false,
  3796. connectToTheServer: false,
  3797. waitUpload: [],
  3798. currentURL: "null",
  3799. shortcut: 3,
  3800. rules: {},
  3801. data: []
  3802. };
  3803. var rwl_userData = null;
  3804. var rule = null;
  3805. var hasFrame = false;
  3806. var storageName = "storageName";
  3807. var hook_eventNames, unhook_eventNames, eventNames;
  3808. var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
  3809. var document_addEventListener = document.addEventListener;
  3810. var Event_preventDefault = Event.prototype.preventDefault;
  3811. rwl_userData = GM_getValue("rwl_userData");
  3812. if (!rwl_userData) {
  3813. rwl_userData = settingData;
  3814. }
  3815. for (let value in settingData) {
  3816. if (!rwl_userData.hasOwnProperty(value)) {
  3817. rwl_userData[value] = settingData[value];
  3818. GM_setValue("rwl_userData", rwl_userData);
  3819. }
  3820. }
  3821. // @thanks 特别感谢 wyn大佬 提供的 字典匹配表 原作者 wyn665817@163.com 开源地址 https://scriptcat.org/script-show-page/432/code
  3822. function removeF() {
  3823. var $tip = $("style:contains(font-cxsecret)");
  3824. if (!$tip.length) return;
  3825. var font = $tip.text().match(/base64,([\w\W]+?)'/)[1];
  3826. font = Typr.parse(base64ToUint8Array(font))[0];
  3827. var table = JSON.parse(GM_getResourceText("Table"));
  3828. var match = {};
  3829. for (var i = 19968; i < 40870; i++) {
  3830. $tip = Typr.U.codeToGlyph(font, i);
  3831. if (!$tip) continue;
  3832. $tip = Typr.U.glyphToPath(font, $tip);
  3833. $tip = MD5(JSON.stringify($tip)).slice(24);
  3834. match[i] = table[$tip];
  3835. }
  3836. $(".font-cxsecret").html(function(index, html) {
  3837. $.each(match, function(key, value) {
  3838. key = String.fromCharCode(key);
  3839. key = new RegExp(key, "g");
  3840. value = String.fromCharCode(value);
  3841. html = html.replace(key, value);
  3842. });
  3843. return html;
  3844. }).removeClass("font-cxsecret");
  3845. function base64ToUint8Array(base64) {
  3846. var data = window.atob(base64);
  3847. var buffer = new Uint8Array(data.length);
  3848. for (var i = 0; i < data.length; ++i) {
  3849. buffer[i] = data.charCodeAt(i);
  3850. }
  3851. return buffer;
  3852. }
  3853. }
  3854. function start() {
  3855. try {
  3856. removeF();
  3857. } catch (e) {}
  3858. try {
  3859. init();
  3860. } catch (e) {}
  3861. }
  3862. WorkerJSPlus({
  3863. name: "学习通作业",
  3864. match: location.pathname === "/mooc2/work/dowork" || location.pathname === "/mooc-ans/mooc2/work/dowork",
  3865. root: ".questionLi",
  3866. elements: {
  3867. question: "h3",
  3868. options: ".stem_answer .answerBg .answer_p, .textDIV, .eidtDiv",
  3869. $options: ".stem_answer .answerBg, .textDIV, .eidtDiv",
  3870. type: "input[type^=hidden]:eq(0)"
  3871. },
  3872. wrap: obj => {
  3873. obj.question = obj.question.replace(obj.$item.find(".colorShallow").text(), "").replace(/^(\d+\.\s)/, "");
  3874. },
  3875. ignore_click: $item => {
  3876. return Boolean($item.find(".check_answer,.check_answer_dx").length);
  3877. },
  3878. fill: (type, answer, $option) => {
  3879. if (type === 4 || type === 2 || type === 5) {
  3880. UE$1.getEditor($option.find("textarea").attr("name")).setContent(answer);
  3881. }
  3882. }
  3883. });
  3884. WorkerJSPlus({
  3885. name: "超星旧版考试",
  3886. match: (location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew") && !location.href.includes("newMooc=true"),
  3887. root: ".TiMu",
  3888. elements: {
  3889. question: ".Cy_TItle .clearfix",
  3890. options: ".Cy_ulTop .clearfix",
  3891. $options: ":radio, :checkbox, .Cy_ulTk textarea",
  3892. type: "[name^=type]:not([id])"
  3893. },
  3894. ignore_click: $item => {
  3895. return $item.get(0).checked;
  3896. },
  3897. fill: (type, answer, $option) => {
  3898. if (type === 4 || type === 2 || type === 5) {
  3899. UE$1.getEditor($option.attr("name")).setContent(answer);
  3900. }
  3901. },
  3902. finished: auto_jump => {
  3903. auto_jump && setInterval(function() {
  3904. const btn = $(".saveYl:contains(下一题)").offset();
  3905. var mouse = document.createEvent("MouseEvents"), arr = [ btn.left + Math.ceil(Math.random() * 80), btn.top + Math.ceil(Math.random() * 26) ];
  3906. mouse.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, arr[0], arr[1], false, false, false, false, 0, null);
  3907. _self.event = $.extend(true, {}, mouse);
  3908. delete _self.event.isTrusted;
  3909. _self.getTheNextQuestion(1);
  3910. }, Math.ceil(GLOBAL.fillAnswerDelay * Math.random()) * 2);
  3911. }
  3912. });
  3913. WorkerJSPlus({
  3914. name: "超星章节测验",
  3915. match: location.pathname === "/work/doHomeWorkNew" || location.pathname === "/mooc-ans/work/doHomeWorkNew",
  3916. init: start,
  3917. root: ".clearfix .TiMu",
  3918. elements: {
  3919. question: ".Zy_TItle .clearfix",
  3920. options: "ul:eq(0) li .after",
  3921. $options: "ul:eq(0) li :radio,:checkbox,textarea,.num_option_dx,.num_option",
  3922. type: "input[name^=answertype]"
  3923. },
  3924. ignore_click: $item => {
  3925. if ($item.is("input")) {
  3926. return $item.get(0).checked;
  3927. }
  3928. return $item.attr("class").includes("check_answer");
  3929. },
  3930. fill: async (type, answer, $option) => {
  3931. if (type === 4 || type === 2 || type === 5) {
  3932. UE$1.getEditor($option.attr("name")).setContent(answer);
  3933. }
  3934. }
  3935. });
  3936. WorkerJSPlus({
  3937. name: "超星新版考试",
  3938. match: () => {
  3939. const cxSinglePage = (location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew" || location.pathname === "/mooc-ans/exam/test/reVersionTestStartNew") && location.href.includes("newMooc=true");
  3940. const cxAll = location.pathname === "/mooc2/exam/preview" || location.pathname === "/exam-ans/mooc2/exam/preview" || location.pathname === "/mooc-ans/mooc2/exam/preview";
  3941. return cxSinglePage || cxAll;
  3942. },
  3943. root: ".questionLi",
  3944. elements: {
  3945. question: "h3 div",
  3946. options: ".answerBg .answer_p, .textDIV, .eidtDiv",
  3947. $options: ".answerBg, .textDIV, .eidtDiv",
  3948. type: "input[name^=type]:eq(" + GLOBAL.i + ")"
  3949. },
  3950. ignore_click: $item => {
  3951. return Boolean($item.find(".check_answer,.check_answer_dx").length);
  3952. },
  3953. hook: () => {
  3954. GLOBAL.i = Number((location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew" || location.pathname === "/mooc-ans/exam/test/reVersionTestStartNew") && location.href.includes("newMooc=true"));
  3955. },
  3956. wrap: obj => {
  3957. if (obj.type === 6) {
  3958. obj.type = 4;
  3959. }
  3960. },
  3961. fill: (type, answer, $option) => {
  3962. if (type === 4 || type === 2 || type === 5) {
  3963. const name = $option.find("textarea").attr("name");
  3964. UE$1.getEditor(name).setContent(answer);
  3965. if (GLOBAL.i === 0) {
  3966. console.log("#" + name.replace("answerEditor", "save_"));
  3967. $("#" + name.replace("answerEditor", "save_")).click();
  3968. }
  3969. }
  3970. },
  3971. finished: a => {
  3972. a && $('.nextDiv .jb_btn:contains("下一题")').click();
  3973. }
  3974. });
  3975. WorkerJSPlus({
  3976. name: "超星随堂测验",
  3977. match: location.pathname.includes("/page/quiz/stu/answerQuestion"),
  3978. root: ".question-item",
  3979. elements: {
  3980. question: ".topic-txt",
  3981. options: ".topic-option-list",
  3982. $options: ".topic-option-list input",
  3983. type: "input[class^=que-type]"
  3984. },
  3985. ignore_click: $item => {
  3986. return Boolean($item.find(".check_answer,.check_answer_dx").length);
  3987. },
  3988. wrap: obj => {
  3989. if (obj.type === 16) {
  3990. obj.type = 3;
  3991. }
  3992. },
  3993. fill: (type, answer, $option) => {
  3994. if (type === 4 || type === 2) {
  3995. $option.val(answer);
  3996. }
  3997. }
  3998. });
  3999. function JSONParseHook(func) {
  4000. if (location.host.includes("zhihuishu")) {
  4001. let oldSend = XMLHttpRequest.prototype.send;
  4002. XMLHttpRequest.prototype.send = function() {
  4003. this.addEventListener("readystatechange", function() {
  4004. if (this.readyState === 4 && this.response.includes("workExamParts")) {
  4005. try {
  4006. func(JSON.parse(this.response));
  4007. } catch (err) {}
  4008. }
  4009. }, false);
  4010. return oldSend.apply(this, arguments);
  4011. };
  4012. } else {
  4013. const parse = JSON.parse;
  4014. JSON.parse = function(...args) {
  4015. const o = parse.call(this, ...args);
  4016. func(o);
  4017. return o;
  4018. };
  4019. }
  4020. }
  4021. function hookZhiHuiShuWork(o, arr) {
  4022. function format(item) {
  4023. let options = [];
  4024. let options_id;
  4025. if (item.questionOptions && item.questionOptions.length) {
  4026. options = item.questionOptions.map(o => {
  4027. return formatString(o.content);
  4028. });
  4029. options_id = item.questionOptions.map(o => {
  4030. return o.id;
  4031. });
  4032. }
  4033. return {
  4034. qid: item.id,
  4035. question: formatString(item.name),
  4036. type: getQuestionType(item.questionType.name),
  4037. options_id: options_id,
  4038. options: options
  4039. };
  4040. }
  4041. if (o.rt && o.rt.examBase && o.rt.examBase.workExamParts.length > 0) {
  4042. GLOBAL.content = o.rt;
  4043. GLOBAL.json = o.rt.examBase.workExamParts.map(part => {
  4044. return part.questionDtos.map(item => {
  4045. if ("阅读理解(选择)/完型填空" === item.questionType.name || "听力训练" === item.questionType.name || !(item.questionType.name.includes("填空") || item.questionType.name.includes("问答")) && item.questionChildrens && item.questionChildrens.length > 0) {
  4046. return item.questionChildrens.map(i => {
  4047. console.log(format(i));
  4048. return format(i);
  4049. }).flat();
  4050. } else {
  4051. return format(item);
  4052. }
  4053. });
  4054. }).flat();
  4055. } else if (o.rt && Object.keys(o.rt).length > 0 && !isNaN(Object.keys(o.rt)[0])) {
  4056. GLOBAL.img = o.rt;
  4057. }
  4058. }
  4059. WorkerJSPlus({
  4060. name: "智慧树作业/考试",
  4061. match: !location.href.includes("checkHomework") && location.host.includes("zhihuishu") && (location.pathname === "/stuExamWeb.html" || location.href.includes("/webExamList/dohomework/") || location.href.includes("/webExamList/doexamination/")),
  4062. root: ".examPaper_subject",
  4063. elements: {
  4064. question: ".subject_describe div,.smallStem_describe p",
  4065. options: ".subject_node .nodeLab .node_detail",
  4066. $options: ".subject_node .nodeLab .node_detail",
  4067. type: ".subject_type span:first-child"
  4068. },
  4069. hook: () => {
  4070. JSONParseHook(hookZhiHuiShuWork);
  4071. },
  4072. intv: () => {
  4073. return $(".answerCard").length;
  4074. },
  4075. wrap: obj => {
  4076. Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
  4077. console.log(obj);
  4078. if ($(".yidun_popup").hasClass("yidun_popup--light")) {
  4079. iframeMsg("tip", {
  4080. type: "stop",
  4081. tip: "答题暂停,请自行通过验证"
  4082. });
  4083. GLOBAL.stop = true;
  4084. }
  4085. },
  4086. ignore_click: $item => {
  4087. return $item.hasClass("onChecked");
  4088. },
  4089. fill: (type, answer, $option) => {
  4090. if (type === 4 || type === 2) {
  4091. UE$1.getEditor($option.find("textarea").attr("name")).setContent(answer);
  4092. }
  4093. },
  4094. finished: async () => {
  4095. vm.zhihuishuSaveTip();
  4096. const len = $(".answerCard_list li").length;
  4097. for (let i = 0; i < len; i++) {
  4098. await sleep(500);
  4099. try {
  4100. $(".answerCard_list1 li").eq(i).click();
  4101. await sleep(1e3 * 3);
  4102. $(".el-button:contains(下一题)").click();
  4103. } catch (e) {
  4104. $(".el-button:contains(保存)").click();
  4105. }
  4106. const process = ((i + 1) / len * 100).toFixed(0);
  4107. $("#gs_p").val(process);
  4108. $("#gs_text").text(process + "%");
  4109. }
  4110. if (top.document.querySelector("#gs_p").value == 100) {
  4111. top.document.querySelector("#zhihuishuSaveTip").remove();
  4112. }
  4113. },
  4114. fillFinish: () => {
  4115. $(".answerCard_list li").eq(GLOBAL.index - 1).click();
  4116. $(".el-button:contains(下一题)").click();
  4117. }
  4118. });
  4119. WorkerJSPlus({
  4120. name: "智慧树学分课作业",
  4121. match: location.href.includes("/atHomeworkExam/stu/homeworkQ/exerciseList") || location.href.includes("atHomeworkExam/stu/examQ/examexercise"),
  4122. root: ".questionBox:eq(0)",
  4123. elements: {
  4124. question: ".questionContent",
  4125. options: ".optionUl label .el-radio__label,.el-checkbox__label",
  4126. $options: ".optionUl label",
  4127. type: ".questionTit"
  4128. },
  4129. intv: () => {
  4130. return $(".answerCard").length || $(".questionTit").length;
  4131. },
  4132. wrap: async obj => {
  4133. obj.options = obj.options.map(item => {
  4134. return formatString(item.replaceAll(/^[a-zA-Z][.|\s+]/g, ""));
  4135. });
  4136. if ($(".yidun_popup").hasClass("yidun_popup--light")) {
  4137. iframeMsg("tip", {
  4138. type: "stop",
  4139. tip: "答题暂停,请自行通过验证"
  4140. });
  4141. GLOBAL.stop = true;
  4142. }
  4143. },
  4144. ignore_click: $item => {
  4145. return $item.hasClass("is-checked");
  4146. },
  4147. finished: () => {
  4148. if ($(".Nextbtndiv .Topicswitchingbtn-gray:contains(下一题)").hasClass("Topicswitchingbtn-gray")) return false;
  4149. $(".Topicswitchingbtn:contains(下一题)").click();
  4150. return true;
  4151. }
  4152. });
  4153. WorkerJSPlus({
  4154. name: "智慧树学分课考试",
  4155. match: location.host === "studentexambaseh5.zhihuishu.com",
  4156. root: ".ques-detail",
  4157. elements: {
  4158. question: ".questionName .centent-pre",
  4159. options: ".radio-view li .preStyle,.checkbox-views label .preStyle",
  4160. $options: ".radio-view li,.checkbox-views label",
  4161. type: ".letterSortNum"
  4162. },
  4163. intv: () => {
  4164. return $(".questionContent").length;
  4165. },
  4166. ignore_click: $item => {
  4167. return $item.hasClass("is-checked");
  4168. },
  4169. wrap: obj => {
  4170. obj.options = obj.options.map(item => {
  4171. return formatString(item.replaceAll(/^[a-zA-Z][.|\s+]/g, ""));
  4172. });
  4173. if ($(".yidun_popup").hasClass("yidun_popup--light")) {
  4174. iframeMsg("tip", {
  4175. type: "stop",
  4176. tip: "答题暂停,请自行通过验证"
  4177. });
  4178. GLOBAL.stop = true;
  4179. }
  4180. if (obj.type === 15) {
  4181. obj.question = formatString($(".centent-son-pre").text());
  4182. obj.type = 1;
  4183. }
  4184. },
  4185. finished: auto_jump => {
  4186. if (auto_jump) {
  4187. const btn = $(".next-topic:contains(下一题)");
  4188. btn.click();
  4189. return !btn.hasClass("noNext");
  4190. }
  4191. }
  4192. });
  4193. WorkerJSPlus({
  4194. match: location.href.includes("checkHomework") && location.host.includes("zhihuishu"),
  4195. hook: () => {
  4196. JSONParseHook(hookZhiHuiShuWork);
  4197. },
  4198. init: () => {
  4199. R({
  4200. type: 2,
  4201. content: GLOBAL.content,
  4202. img: GLOBAL.img
  4203. });
  4204. }
  4205. });
  4206. GLOBAL.timeout = 10 * 1e3;
  4207. function uploadAnswer(data) {
  4208. const arr2 = division(data, 100);
  4209. for (let arr2Element of arr2) {
  4210. GM_xmlhttpRequest({
  4211. method: "POST",
  4212. url: "https://lyck6.cn/pcService/api/uploadAnswer",
  4213. headers: {
  4214. "Content-Type": "application/json;charset=utf-8"
  4215. },
  4216. data: JSON.stringify(arr2Element),
  4217. timeout: GLOBAL.timeout
  4218. });
  4219. }
  4220. }
  4221. function uploadAnswerToPlat(data, plat) {
  4222. const arr2 = division(data, 100);
  4223. for (let arr2Element of arr2) {
  4224. GM_xmlhttpRequest({
  4225. method: "POST",
  4226. url: "https://lyck6.cn/collect-service/v1/uploadAnswerToPlat?plat=" + plat,
  4227. headers: {
  4228. "Content-Type": "application/json;charset=utf-8"
  4229. },
  4230. data: JSON.stringify(arr2Element),
  4231. timeout: GLOBAL.timeout
  4232. });
  4233. }
  4234. }
  4235. WorkerJSPlus({
  4236. name: "职教云考试",
  4237. match: location.pathname === "/exam/examflow_index.action",
  4238. intv: () => {
  4239. return $(".divQuestionTitle").length;
  4240. },
  4241. root: ".q_content",
  4242. elements: {
  4243. question: ".divQuestionTitle",
  4244. options: ".questionOptions .q_option",
  4245. $options: ".questionOptions .q_option div,div[id^=_baidu_editor_]"
  4246. },
  4247. ignore_click: $item => {
  4248. return $($item).attr("class") === "checkbox_on";
  4249. },
  4250. wrap: obj => {
  4251. const type = getQuestionType(obj.$item.next().attr("answertype"));
  4252. obj.type = type === undefined ? defaultWorkTypeResolver(obj.$options) : type;
  4253. },
  4254. fill: (type, answer, $option) => {
  4255. if (type === 4 || type === 2 || type === 5) {
  4256. UE$1.getEditor($option.attr("id")).setContent(answer);
  4257. }
  4258. },
  4259. finished: async () => {
  4260. if ($(".paging_next").attr("style").includes("block") || !$(".paging_next").attr("style").includes("none")) {
  4261. $(".paging_next").click();
  4262. await sleep(1e3);
  4263. return true;
  4264. }
  4265. }
  4266. });
  4267. WorkerJSPlus({
  4268. name: "职教云测验",
  4269. match: location.pathname === "/study/directory/dir_course.html",
  4270. intv: () => {
  4271. return $(".panel_item").length;
  4272. },
  4273. root: ".panel_item .panel_item",
  4274. elements: {
  4275. question: ".preview_cm .preview_stem",
  4276. options: ".preview_cm ul li span:last-child",
  4277. $options: ".preview_cm ul li input"
  4278. },
  4279. wrap: obj => {
  4280. obj.type = getQuestionType(obj.$item.parent().find(".panel_title").text());
  4281. obj.options = obj.options.map(i => {
  4282. return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim();
  4283. });
  4284. },
  4285. ignore_click: $item => {
  4286. return $item.attr("checked") === "checked";
  4287. }
  4288. });
  4289. WorkerJSPlus({
  4290. name: "职教云MOOC",
  4291. match: location.pathname === "/study/homework/do.html" || location.pathname === "/study/workExam/testWork/preview.html" || location.pathname === "/study/onlineExam/preview.html" || location.pathname === "/study/workExam/homeWork/preview.html" || location.pathname === "/study/workExam/onlineExam/preview.html",
  4292. root: ".e-q-r",
  4293. elements: {
  4294. question: ".e-q-q .ErichText",
  4295. options: ".e-a-g li",
  4296. $options: ".e-a-g li",
  4297. type: ".quiz-type"
  4298. },
  4299. ignore_click: $item => {
  4300. return $item.hasClass("checked");
  4301. },
  4302. wrap: obj => {
  4303. if (obj.type === "A1A2题") {
  4304. obj.type = 1;
  4305. }
  4306. obj.question = obj.question.replace(/<img src="https:\/\/cdn-zjy.icve.com.cn\/common\/images\/question_button\/blankspace(\d+).gif">/gi, "");
  4307. obj.options = obj.options.map(i => {
  4308. return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim();
  4309. });
  4310. }
  4311. });
  4312. function parseIcve(questions) {
  4313. return questions.map(item => {
  4314. const options = item.Selects.map(opt => {
  4315. return formatString(opt);
  4316. });
  4317. const type = getQuestionType(item.ACHType.QuestionTypeName);
  4318. const answer = item.Answers.map(key => {
  4319. if (type === 0 || type === 1) {
  4320. return options[key.charCodeAt() - 65];
  4321. } else if (type === 3) {
  4322. return key === "1" ? "正确" : "错误";
  4323. }
  4324. });
  4325. const answerKey = type === 0 || type === 1 ? item.Answers : answer;
  4326. return {
  4327. id: item.Id,
  4328. question: item.ContentText,
  4329. answerKey: answerKey,
  4330. options: type === 3 ? [ "正确", "错误" ] : options,
  4331. answer: answer,
  4332. type: type
  4333. };
  4334. });
  4335. }
  4336. WorkerJSPlus({
  4337. name: "资源库 新版",
  4338. match: location.pathname === "/icve-study/jobTest" || location.pathname === "/icve-study/coursePreview/jobTest" || location.pathname === "/icve-study/coursePreview/test",
  4339. root: ".subjectDet",
  4340. elements: {
  4341. question: "h5,.titleTest span:last",
  4342. options: ".optionList label",
  4343. $options: ".optionList input",
  4344. type: ".title,.titleTest .xvhao"
  4345. },
  4346. ignore_click: $item => {
  4347. return $item.prop("checked");
  4348. },
  4349. wrap: obj => {
  4350. console.log(obj);
  4351. },
  4352. fill: (type, answer, $option) => {
  4353. if (type === 4 || type === 2) {
  4354. UE$1.getEditor($option.attr("name")).setContent(answer);
  4355. }
  4356. }
  4357. });
  4358. WorkerJSPlus({
  4359. name: "资源库 WWW开头",
  4360. match: location.pathname === "/study/works/works.html" || location.pathname === "/study/exam/exam.html",
  4361. root: ".questions",
  4362. elements: {
  4363. question: ".preview_stem",
  4364. options: "li .preview_cont",
  4365. $options: "li input",
  4366. type: "input:hidden"
  4367. },
  4368. hook: () => {
  4369. JSONParseHook(o => {
  4370. if (location.pathname === "/study/works/works.html") {
  4371. if (o.paper) {
  4372. GLOBAL.json = parseIcve(o.paper.PaperQuestions);
  4373. uploadAnswer(GLOBAL.json);
  4374. }
  4375. } else if (location.pathname === "/study/exam/exam.html") {
  4376. if (o.array) {
  4377. GLOBAL.json = parseIcve(o.array.map(item => {
  4378. return item.Questions;
  4379. }).flat());
  4380. uploadAnswer(GLOBAL.json);
  4381. }
  4382. }
  4383. });
  4384. },
  4385. ignore_click: $item => {
  4386. return $item.prop("checked");
  4387. },
  4388. wrap: obj => {
  4389. function get_element(id) {
  4390. for (let jsonElement of GLOBAL.json) {
  4391. if (jsonElement.id === id) {
  4392. return jsonElement;
  4393. }
  4394. }
  4395. }
  4396. const ele = get_element(obj.$item.find("input:hidden").val());
  4397. obj.question = ele.question;
  4398. obj.answer = ele.answerKey ? ele.answerKey : ele.answer;
  4399. obj.type = ele.type;
  4400. obj.options = ele.options;
  4401. console.log(obj);
  4402. },
  4403. fill: (type, answer, $option) => {
  4404. if (type === 4 || type === 2) {
  4405. UE$1.getEditor($option.attr("name")).setContent(answer);
  4406. }
  4407. }
  4408. });
  4409. WorkerJSPlus({
  4410. name: "智慧职教 作业/考试",
  4411. match: location.host.includes("zjy2.icve.com.cn"),
  4412. intv: () => {
  4413. return $(".subjectDet").length;
  4414. },
  4415. root: ".subjectDet",
  4416. elements: {
  4417. question: "h5,.titleT .htmlP",
  4418. options: ".optionList .el-radio__label,.el-checkbox__label",
  4419. $options: ".optionList input",
  4420. type: ".titleTwo,.xvhao"
  4421. },
  4422. hook: () => {
  4423. const parse = ques => {
  4424. return ques.map(i => {
  4425. const options = [];
  4426. const answer = [];
  4427. if (i.typeId === "3") {
  4428. answer.push(i.optionAnswer === "1" ? "正确" : "错误");
  4429. } else if (/[12]/.test(i.typeId)) {
  4430. options.push(...JSON.parse(i.dataJson).map(i => {
  4431. if (i.IsAnswer) {
  4432. answer.push(formatString(i.Content));
  4433. }
  4434. return formatString(i.Content);
  4435. }));
  4436. }
  4437. return {
  4438. options: options,
  4439. qid: i.id,
  4440. answer: answer
  4441. };
  4442. });
  4443. };
  4444. JSONParseHook(o => {
  4445. if (o.name && o.questions && o.totalScore) {
  4446. GLOBAL.json = parse(o.questions);
  4447. } else if (o.data && o.data.questions) {
  4448. GLOBAL.json = parse(o.data.questions);
  4449. }
  4450. });
  4451. },
  4452. ignore_click: $item => {
  4453. return $($item).parent().attr("class") === "is-checked";
  4454. },
  4455. wrap: obj => {
  4456. function findAnswer(id) {
  4457. for (let jsonElement of GLOBAL.json) {
  4458. if (jsonElement.qid === id) {
  4459. return jsonElement.answer;
  4460. }
  4461. }
  4462. }
  4463. obj.answer = findAnswer(obj.$item.attr("id"));
  4464. }
  4465. });
  4466. function parseYkt(problems) {
  4467. return problems.map(item => {
  4468. const question = formatString(item.Body);
  4469. const type = getQuestionType(item.TypeText);
  4470. const options = [];
  4471. const answer = [];
  4472. if (type <= 1) {
  4473. options.push(...item.Options.sort((a, b) => {
  4474. return a.key.charCodeAt(0) - b.key.charCodeAt(0);
  4475. }).map(item => {
  4476. return formatString(item.value);
  4477. }));
  4478. if (item.Answer) {
  4479. if (Array.isArray(item.Answer)) {
  4480. answer.push(...item.Answer);
  4481. } else {
  4482. answer.push(...item.Answer.split(""));
  4483. }
  4484. }
  4485. } else if (type === 3 && item.Answer && item.Answer.length === 1) {
  4486. answer.push(item.Answer[0].replace("true", "正确").replace("false", "错误"));
  4487. }
  4488. return {
  4489. answer: answer,
  4490. options: options,
  4491. type: type,
  4492. qid: item.problem_id,
  4493. question: question
  4494. };
  4495. });
  4496. }
  4497. function parsehnzkwText(problems) {
  4498. return problems.map(item => {
  4499. const type = item.flag === 1 ? 2 : item.flag === 0 ? 0 : item.flag === 4 ? 1 : item.flag === 3 ? 3 : undefined;
  4500. let answer = [];
  4501. let options = [];
  4502. if (type === 2) {
  4503. answer.push(item.answer);
  4504. return {
  4505. question: formatString(item.content),
  4506. options: options,
  4507. type: type,
  4508. answer: answer
  4509. };
  4510. } else if (type === 0) {
  4511. for (let subjectOption of item.optionss) {
  4512. const opt = formatString(subjectOption);
  4513. options.push(opt);
  4514. }
  4515. if (type === 1) {
  4516. item.answer.split("|").map(i => {
  4517. answer.push(options[i.toUpperCase().charCodeAt(0) - 65]);
  4518. });
  4519. } else {
  4520. answer.push(options[item.answer.toUpperCase().charCodeAt(0) - 65]);
  4521. }
  4522. return {
  4523. question: formatString(item.content),
  4524. options: options,
  4525. type: type,
  4526. answer: answer
  4527. };
  4528. } else if (type === 3) {
  4529. for (let subjectOption of item.selectOption) {
  4530. const opt = formatString(subjectOption);
  4531. options.push(opt);
  4532. }
  4533. answer.push(item.answer);
  4534. return {
  4535. question: formatString(item.content),
  4536. options: options,
  4537. type: type,
  4538. answer: answer
  4539. };
  4540. }
  4541. });
  4542. }
  4543. function parseDanWei(pro) {
  4544. return pro.map(i => {
  4545. const type = getQuestionType(i.ttop010);
  4546. const question = i.ttop011;
  4547. const options = [];
  4548. const answer = [];
  4549. if (type === 0 || type === 1 || type === 3) {
  4550. options.push(...i.ttop018.length > 0 ? i.ttop018.split("$$") : [ "正确", "错误" ]);
  4551. answer.push(...i.ttop022.split("").map(item => {
  4552. return options[item.charCodeAt(0) - 65];
  4553. }));
  4554. } else if (type === 2 || type === 4) {
  4555. answer.push(...i.ttop021.split("$$"));
  4556. }
  4557. return {
  4558. question: question,
  4559. type: type,
  4560. answer: answer,
  4561. options: options
  4562. };
  4563. }).filter(i => i);
  4564. }
  4565. function parseYxbyunExam(problems) {
  4566. return problems.map(item => {
  4567. const type = getQuestionType(item.bigName);
  4568. return item.smallContent.map(item => {
  4569. let answer = [];
  4570. let options = [];
  4571. if (type === 2) {
  4572. answer.push(item.answer);
  4573. return {
  4574. question: formatString(item.content),
  4575. options: options,
  4576. type: type,
  4577. answer: answer
  4578. };
  4579. } else if (type === 0 || type === 3 || type === 1) {
  4580. let answer = [];
  4581. let options = [];
  4582. for (let subjectOption of item.question.optionList) {
  4583. const opt = formatString(subjectOption.questionContent);
  4584. options.push(opt);
  4585. }
  4586. if (type === 1) {
  4587. item.question.questionAnswer.split(",").map(i => {
  4588. answer.push(options[i.toUpperCase().charCodeAt(0) - 65]);
  4589. });
  4590. } else {
  4591. answer.push(options[item.question.questionAnswer.toUpperCase().charCodeAt(0) - 65]);
  4592. }
  4593. return {
  4594. question: formatString(item.question.questionTitle),
  4595. options: options,
  4596. type: type,
  4597. answer: answer
  4598. };
  4599. }
  4600. });
  4601. });
  4602. }
  4603. WorkerJSPlus({
  4604. name: "雨课堂旧版考试",
  4605. match: location.pathname.includes("/v/quiz/quiz_result"),
  4606. intv: () => {
  4607. return $("#cover").attr("style").includes("display: none;");
  4608. },
  4609. root: ".problem_item",
  4610. elements: {
  4611. question: ".notBullet:eq(0)",
  4612. options: ".notBullet:gt(0)",
  4613. $options: ".problembullet"
  4614. },
  4615. ignore_click: $item => {
  4616. return $item.hasClass("is-checked");
  4617. },
  4618. wrap: async obj => {
  4619. const $item = obj.$item;
  4620. const tmp = $item.find(".ptype").clone();
  4621. tmp.children().remove();
  4622. obj.type = getQuestionType(tmp.text());
  4623. obj.question = await yuketangOcr(obj.question.attr("data-background"));
  4624. if (obj.$options.length === 2) {
  4625. obj.options = [ "正确", "错误" ];
  4626. } else {
  4627. const opt = [];
  4628. for (const tmpElement of $item.find(".notBullet:gt(0)")) {
  4629. opt.push(await yuketangOcr(jQuery(tmpElement).attr("data-background")));
  4630. }
  4631. obj.options = opt;
  4632. }
  4633. }
  4634. });
  4635. WorkerJSPlus({
  4636. name: "学堂在线",
  4637. match: location.host === "www.xuetangx.com" && location.pathname.includes("/exercise/"),
  4638. intv: () => {
  4639. return $(".answer").length;
  4640. },
  4641. root: ".content:eq(0)",
  4642. elements: {
  4643. question: ".question .fuwenben",
  4644. options: ".question .leftQuestion .leftradio > span:last-child",
  4645. $options: ".question .leftradio",
  4646. type: ".question .title"
  4647. },
  4648. ignore_click: $item => {
  4649. return $item.find(".radio_jqq").hasClass("active");
  4650. },
  4651. wrap: obj => {
  4652. if (obj.type === 3) {
  4653. obj.$options = $(".answerList .radio_jqq");
  4654. }
  4655. },
  4656. fill: (type, answer, $option) => {
  4657. if (type === 4 || type === 2) {
  4658. UE.getEditor($option.find("textarea")).setContent(answer);
  4659. }
  4660. },
  4661. finished: () => {
  4662. const $right = $(".tabbar").find(".right");
  4663. $right.click();
  4664. return !$right.hasClass("unselect");
  4665. }
  4666. });
  4667. WorkerJSPlus({
  4668. name: "雨课堂新版考试",
  4669. match: location.host.includes("yuketang.cn") && location.pathname.includes("/result/"),
  4670. hook: () => {
  4671. JSONParseHook(async o => {
  4672. if (o.data && o.data.problems && o.data.problems.length > 0) {
  4673. uploadAnswerToPlat(parseYkt(o.data.problems), 50);
  4674. }
  4675. });
  4676. }
  4677. });
  4678. WorkerJSPlus({
  4679. name: "雨课堂新版考试",
  4680. match: (location.host === "examination.xuetangx.com" || location.host === "changjiang-exam.yuketang.cn") && (location.pathname.includes("/exam/") || location.pathname.includes("/cover/")),
  4681. hook: () => {
  4682. JSONParseHook(async o => {
  4683. if (o.data && o.data.problems && o.data.problems.length > 0) {
  4684. GLOBAL.json = parseYkt(o.data.problems);
  4685. }
  4686. });
  4687. const intv = setInterval(() => {
  4688. try {
  4689. top.document.querySelector(".exam").__vue__.handleHangUpTip = function() {};
  4690. const querySelector = top.document.querySelector;
  4691. top.document.querySelector = function(...args) {
  4692. if (args[0] === "#model-id" || args[0].includes("hcSearcheModal")) return false;
  4693. return querySelector.call(this, ...args);
  4694. };
  4695. const getElementById = top.document.getElementById;
  4696. top.document.getElementById = function(...args) {
  4697. if (args[0] === "model-id" || args[0].includes("hcSearcheModal")) return false;
  4698. return getElementById.call(this, ...args);
  4699. };
  4700. clearInterval(intv);
  4701. } catch (e) {}
  4702. }, 100);
  4703. },
  4704. intv: () => {
  4705. return jQuery(".subject-item").length;
  4706. },
  4707. root: ".exam-main--body .subject-item",
  4708. elements: {
  4709. question: ".item-body h4,.item-body span:eq(0)",
  4710. options: ".item-body ul li",
  4711. $options: ".item-body ul label, .blank-item-dynamic, .edui-editor-iframeholder",
  4712. type: ".item-type"
  4713. },
  4714. ignore_click: $item => {
  4715. return $item.hasClass("is-checked");
  4716. },
  4717. wrap: obj => {
  4718. obj.options = obj.type === 3 ? [ "正确", "错误" ] : obj.options.map(i => {
  4719. return i.replace(/^[A-G]\s/, "");
  4720. });
  4721. try {
  4722. obj.qid = GLOBAL.json[GLOBAL.index - 1].qid;
  4723. obj.plat = 50;
  4724. } catch (e) {
  4725. console.log(e);
  4726. }
  4727. }
  4728. });
  4729. WorkerJSPlus({
  4730. name: "雨课堂新版作业,需要一个一个点下一题的",
  4731. match: location.pathname.includes("/v2/web/cloud/student/exercise/"),
  4732. hook: () => {
  4733. async function parseYkt(problems, font) {
  4734. const res = problems.map(i => {
  4735. const type = getQuestionType(i.content.TypeText);
  4736. const question = i.content.Body;
  4737. let options = [];
  4738. if (type <= 1) {
  4739. options = i.content.Options;
  4740. } else if (type === 3) {
  4741. options = i.content.Options.map(item => {
  4742. return item.key.replace("true", "正确").replace("false", "错误");
  4743. });
  4744. }
  4745. return {
  4746. qid: i.problem_id,
  4747. question: question,
  4748. type: type,
  4749. options: options,
  4750. user: i.user
  4751. };
  4752. }).filter(i => i);
  4753. for (const item of res) {
  4754. item.question = await getEncryptString(item.question, font);
  4755. const answerArray = [];
  4756. if (item.type <= 1) {
  4757. const optionsArray = [];
  4758. for (const itemElement of item.options) {
  4759. const opt = await getEncryptString(itemElement.value, font);
  4760. if (item.user && item.user.is_show_answer && item.user.answer.includes(itemElement.key)) {
  4761. answerArray.push(opt);
  4762. }
  4763. optionsArray.push(opt);
  4764. }
  4765. item.options = optionsArray;
  4766. } else if (item.type === 3) {
  4767. if (item.user && item.user.is_show_answer && item.user.answer.length === 1) {
  4768. answerArray.push(item.user.answer[0].replace("true", "正确").replace("false", "错误"));
  4769. }
  4770. }
  4771. delete item.user;
  4772. item.answer = answerArray;
  4773. }
  4774. return res;
  4775. }
  4776. JSONParseHook(async o => {
  4777. if (o.data && o.data.problems) {
  4778. GLOBAL.json = await parseYkt(o.data.problems, o.data.font);
  4779. uploadAnswerToPlat(GLOBAL.json, 50);
  4780. }
  4781. });
  4782. },
  4783. intv: () => {
  4784. return jQuery(".subject-item").length;
  4785. },
  4786. root: ".container-problem .subject-item",
  4787. elements: {
  4788. question: ".problem-body",
  4789. options: "label .radioText,.checkboxText",
  4790. $options: "ul input"
  4791. },
  4792. ignore_click: $item => {
  4793. return $item.prop("checked");
  4794. },
  4795. wrap: async obj => {
  4796. const index = jQuery(".item-type").text().match(/(\d+)\./)[1];
  4797. Object.assign(obj, GLOBAL.json[parseInt(index) - 1]);
  4798. obj.plat = 50;
  4799. },
  4800. finished: need_jump => {
  4801. if ($(".el-button--text:contains(下一题)").hasClass("is-disabled")) return false;
  4802. need_jump && setTimeout(() => {
  4803. $(".el-button--text:contains(下一题)").click();
  4804. }, GLOBAL.fillAnswerDelay);
  4805. return need_jump;
  4806. }
  4807. });
  4808. WorkerJSPlus({
  4809. name: "云班课",
  4810. match: location.pathname === "/web/index.php" && location.href.includes("m=reply"),
  4811. root: ".topic-item",
  4812. elements: {
  4813. question: ".t-con .t-subject",
  4814. options: ".t-option label .option-content",
  4815. $options: ".el-radio__input,.el-checkbox__input",
  4816. type: ".t-info .t-type"
  4817. },
  4818. ignore_click: $item => {
  4819. return $item.hasClass("is-checked");
  4820. },
  4821. wrap: obj => {
  4822. if (obj.type === "A1A2题") {
  4823. obj.type = 1;
  4824. }
  4825. obj.question = obj.question.replace(/<img src="https:\/\/cdn-zjy.icve.com.cn\/common\/images\/question_button\/blankspace(\d+).gif">/gi, "");
  4826. obj.options = obj.options.map(i => {
  4827. return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim();
  4828. });
  4829. }
  4830. });
  4831. WorkerJSPlus({
  4832. name: "中国地质大学",
  4833. match: location.pathname.includes("/Exam/OnlineExamV2/"),
  4834. root: ".stViewItem",
  4835. elements: {
  4836. question: ".stViewHead div",
  4837. options: ".stViewCont .stViewOption a",
  4838. $options: ".stViewCont .stViewOption a,input"
  4839. },
  4840. intv: () => {
  4841. return $(".ExamTime").length;
  4842. },
  4843. wrap: obj => {
  4844. obj.type = getQuestionType(obj.$item.parent().parent().prev().find(".E_E_L_I_C_R_C_T_SubType").text());
  4845. obj.question = obj.question.replace(/\(\d+分\)/, "");
  4846. obj.options = obj.options.map(i => {
  4847. return i.replace(/\([A-Za-z]\)/, "").trim();
  4848. });
  4849. },
  4850. fill: (type, answer, $option) => {
  4851. if (type === 4 || type === 2) {
  4852. $option.val(answer);
  4853. }
  4854. }
  4855. });
  4856. WorkerJSPlus({
  4857. name: "单位",
  4858. match: (location.host === "61.183.163.9:8089" || location.host === "zjpt.nnjjtgs.com:8081") && (location.href.includes("ksnr") || location.href.includes("lxnr")),
  4859. hook: () => {
  4860. JSONParseHook(o => {
  4861. if (o.topicList && o.topicList.length > 0) {
  4862. GLOBAL.json = parseDanWei(o.topicList);
  4863. uploadAnswer(GLOBAL.json);
  4864. }
  4865. });
  4866. },
  4867. root: ".tm",
  4868. elements: {
  4869. question: ".tmnrbj span:last-child",
  4870. options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label",
  4871. $options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label,.van-field__control",
  4872. type: ".tmnrbj span"
  4873. },
  4874. intv: () => {
  4875. return $(".ExamTime").length || document.getElementById("pup-b");
  4876. },
  4877. wrap: obj => {
  4878. obj.answer = GLOBAL.json[jQuery(".tmnrbj span:last-child").text().match(/^(\d+)、/)[1] - 1].answer;
  4879. },
  4880. finished: () => {
  4881. jQuery(".xyt").click();
  4882. return true;
  4883. }
  4884. });
  4885. WorkerJSPlus({
  4886. name: "小鹅通",
  4887. match: location.pathname.includes("/evaluation_wechat/examination/detail/"),
  4888. root: ".question-title,.title__text",
  4889. elements: {
  4890. question: "#detail_div",
  4891. options: "label .image-text-box p",
  4892. $options: "label,.simulation_inp"
  4893. },
  4894. ignore_click: ($item, type) => {
  4895. if (type === 0) {
  4896. return $item.html().includes("single-exam-radio-active");
  4897. } else if (type === 1) {
  4898. return $item.html().includes("check-i-active");
  4899. }
  4900. },
  4901. wrap: obj => {
  4902. const $item = obj.$item;
  4903. obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank");
  4904. obj.type = getQuestionType($item.next().text());
  4905. if (obj.type === 2) {
  4906. obj.$options = $item.parent().parent();
  4907. }
  4908. if (obj.type === 3) {
  4909. obj.options = [ "正确", "错误" ];
  4910. } else {
  4911. obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) {
  4912. return formatString(filterImg(val));
  4913. });
  4914. }
  4915. },
  4916. fill: (type, answer, $option) => {
  4917. if (type === 2) {
  4918. const vue = $option.get(0).__vue__;
  4919. vue.content[0] = answer;
  4920. vue.emitAnswer();
  4921. $option.find(".simulation_inp").text(answer);
  4922. }
  4923. }
  4924. });
  4925. WorkerJSPlus({
  4926. name: "小饿通H5",
  4927. match: location.host.includes("h5.xiaoeknow") || location.href.includes("/exam/h5_evaluation/"),
  4928. root: ".practice-detail__body",
  4929. elements: {
  4930. question: ".question-wrap__title #detail_div",
  4931. options: ".question-option #detail_div",
  4932. $options: ".question-option #detail_div",
  4933. type: ".question-wrap__title-tag"
  4934. },
  4935. wrap: obj => {
  4936. const $item = obj.$item;
  4937. obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank");
  4938. obj.type = TYPE[$item.next().text().replace(/\s+/, "").replace("(", "").replace(")", "")];
  4939. if (obj.type === 2) {
  4940. obj.$options = $item.parent().parent();
  4941. }
  4942. if (obj.type === 3) {
  4943. obj.options = [ "正确", "错误" ];
  4944. } else {
  4945. obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) {
  4946. return formatString(filterImg(val));
  4947. });
  4948. }
  4949. },
  4950. finished: () => {
  4951. $(".practice-detail__bottom-item:last-child").click();
  4952. return $(".next").text() === "下一题";
  4953. }
  4954. });
  4955. WorkerJSPlus({
  4956. name: "人卫慕课测验",
  4957. match: location.pathname.includes("/memberFront/paper.zhtml"),
  4958. intv: () => {
  4959. return $("#question_").attr("style").length === 0;
  4960. },
  4961. root: ".quesinfo",
  4962. elements: {
  4963. question: "dl dt",
  4964. options: "dd label",
  4965. $options: "dd input"
  4966. },
  4967. wrap: obj => {
  4968. if (obj.$options.length === 2) {
  4969. obj.type = 3;
  4970. obj.options = [ "正确", "错误" ];
  4971. } else {
  4972. obj.type = 0;
  4973. }
  4974. }
  4975. });
  4976. WorkerJSPlus({
  4977. name: "青书学堂考试",
  4978. match: location.host.includes("qingshuxuetang") && (location.pathname.includes("/Student/MakeupExamPaper") || location.pathname.includes("Student/ExamPaper")),
  4979. intv: () => {
  4980. return $(".paper-container .question-detail-container").length;
  4981. },
  4982. root: ".paper-container .question-detail-container",
  4983. elements: {
  4984. question: ".question-detail-description .detail-description-content",
  4985. options: ".question-detail-options label .option-description",
  4986. $options: ".question-detail-options label input",
  4987. type: ".question-detail-type .question-detail-type-desc"
  4988. },
  4989. ignore_click: $item => {
  4990. return $item.prop("checked");
  4991. }
  4992. });
  4993. WorkerJSPlus({
  4994. name: "青书学堂测验",
  4995. match: location.host.includes("qingshuxuetang") && location.pathname.includes("/Student/ExercisePaper") || location.host === "quiz.qingshuxuetang.com" && location.pathname.includes("/Student/Quiz/Detail"),
  4996. intv: () => {
  4997. return $(".question-detail-container").length;
  4998. },
  4999. root: ".question-detail-container",
  5000. elements: {
  5001. question: ".question-detail-description span",
  5002. options: ".question-detail-options label .option-description",
  5003. $options: ".question-detail-options div input,.question-detail-solution-textarea",
  5004. type: ".question-detail-type"
  5005. },
  5006. wrap: obj => {
  5007. obj.options = obj.options.map(i => {
  5008. return i.replace(/\([A-Za-z]\)/, "").trim();
  5009. });
  5010. },
  5011. ignore_click: ($item, type) => {
  5012. if (type === 1) {
  5013. return $item.prop("checked");
  5014. }
  5015. },
  5016. fill: (type, answer, $option) => {
  5017. if (type === 4 || type === 2) {
  5018. $option.parents().find(".question-controller-wrapper .next").click();
  5019. }
  5020. }
  5021. });
  5022. WorkerJSPlus({
  5023. name: "优学院测验",
  5024. match: location.pathname === "/learnCourse/learnCourse.html",
  5025. intv: () => {
  5026. return $(".question-setting-panel").length;
  5027. },
  5028. root: ".split-screen-wrapper",
  5029. elements: {
  5030. question: ".question-title-scroller .question-title-html",
  5031. options: ".choice-list .content-wrapper .text",
  5032. $options: ".choice-list .checkbox ,.question-body-wrapper .choice-btn",
  5033. type: ".question-title-scroller .question-type-tag"
  5034. },
  5035. wrap: obj => {
  5036. obj.options = obj.options.map(i => {
  5037. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  5038. });
  5039. },
  5040. ignore_click: $item => {
  5041. return $item.hasClass("selected");
  5042. }
  5043. });
  5044. WorkerJSPlus({
  5045. name: "优学院作业",
  5046. match: location.pathname === "/quiz/pc.html",
  5047. intv: () => {
  5048. return $(".questions").length;
  5049. },
  5050. root: ".question-item",
  5051. elements: {
  5052. question: ".question-title",
  5053. options: "ul label .choice-title",
  5054. $options: "ul label input",
  5055. type: ".title"
  5056. },
  5057. wrap: obj => {
  5058. obj.options = obj.options.map(i => {
  5059. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  5060. });
  5061. },
  5062. ignore_click: $item => {
  5063. return $item.prop("checked");
  5064. }
  5065. });
  5066. WorkerJSPlus({
  5067. name: "优学院考试",
  5068. match: location.host === "utest.ulearning.cn" && location.pathname === "/",
  5069. intv: () => {
  5070. return $(".section-area").length;
  5071. },
  5072. root: ".question-area .question-item",
  5073. elements: {
  5074. question: ".base-question .title .rich-text",
  5075. options: ".choice-list label .rich-text",
  5076. $options: ".choice-list label, .iconfont",
  5077. type: ".base-question .title .tip"
  5078. },
  5079. wrap: obj => {
  5080. obj.options = obj.options.map(i => {
  5081. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  5082. });
  5083. },
  5084. ignore_click: $item => {
  5085. return $item.hasClass("is-checked");
  5086. },
  5087. finished: () => {
  5088. if ($(".next-part:contains(下个部分)").length) {
  5089. $(".next-part").click();
  5090. return true;
  5091. } else {
  5092. return false;
  5093. }
  5094. }
  5095. });
  5096. WorkerJSPlus({
  5097. name: "优学院作业",
  5098. match: location.pathname === "/umooc/learner/homework.do",
  5099. intv: () => {
  5100. return $(".multiple-choices").length;
  5101. },
  5102. root: ".multiple-choices,.judge",
  5103. elements: {
  5104. question: "h5 .position-rltv span:last-child",
  5105. options: "ul label span:last-child",
  5106. $options: "ul label input,.radios .radio input",
  5107. type: "h5 .typeName"
  5108. },
  5109. wrap: obj => {
  5110. obj.options = obj.options.map(i => {
  5111. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  5112. });
  5113. },
  5114. ignore_click: $item => {
  5115. return $item.prev().hasClass("checkbox-checked");
  5116. }
  5117. });
  5118. WorkerJSPlus({
  5119. name: "万学",
  5120. match: location.pathname.includes("/sls/N2014_StudyController/next"),
  5121. root: ".question",
  5122. elements: {
  5123. question: "tr .nm2",
  5124. options: ".grey td p",
  5125. $options: ".option li label",
  5126. type: "tr .nm2"
  5127. },
  5128. wrap: obj => {
  5129. obj.question = obj.question.parent().find("td p").text();
  5130. }
  5131. });
  5132. WorkerJSPlus({
  5133. name: "wenJuanAutoFill",
  5134. match: location.host.includes("wenjuan.com") && location.pathname === "/s/",
  5135. root: "questionContent",
  5136. elements: {
  5137. question: ".title",
  5138. options: ".icheckbox_div .option_label",
  5139. $options: ".icheckbox_div label",
  5140. type: ".question_num"
  5141. },
  5142. ignore_click: $item => {
  5143. return $item.attr("class").includes("checked");
  5144. }
  5145. });
  5146. WorkerJSPlus({
  5147. name: "学起(考试)",
  5148. match: location.pathname.includes("/oxer/page/ots/examIndex.html"),
  5149. intv: () => {
  5150. return $(".tika_topline").length;
  5151. },
  5152. root: ".queItemClass",
  5153. elements: {
  5154. question: "dt .din:eq(1)",
  5155. options: ".clearfix div",
  5156. $options: ".clearfix .xuan,input"
  5157. },
  5158. ignore_click: $item => {
  5159. return $item.parent().hasClass("cur");
  5160. },
  5161. wrap: obj => {
  5162. obj.plat = 66;
  5163. obj.qid = obj.$item.attr("id");
  5164. obj.type = getQuestionType(obj.$item.parent().find("div .fb:eq(0)").text());
  5165. if (obj.type === 3) {
  5166. obj.options = [ "正确", "错误" ];
  5167. }
  5168. }
  5169. });
  5170. WorkerJSPlus({
  5171. name: "学起(测试)",
  5172. match: location.pathname.includes("/oxer/page/ots/UniversityStart.html"),
  5173. intv: () => {
  5174. return $(".uniQueList").length;
  5175. },
  5176. root: ".uniQueItem",
  5177. elements: {
  5178. question: ".QueStem",
  5179. options: "ul li span",
  5180. $options: "ul li"
  5181. },
  5182. ignore_click: $item => {
  5183. return $item.parent().hasClass("lichecked");
  5184. },
  5185. wrap: obj => {
  5186. obj.type = getQuestionType(obj.$item.parents(".uniQueList").find(".fir").text());
  5187. if (obj.type === 3) {
  5188. obj.options = [ "正确", "错误" ];
  5189. }
  5190. console.log(obj);
  5191. }
  5192. });
  5193. WorkerJSPlus({
  5194. name: "易班考试",
  5195. match: location.host === "exam.yooc.me" && location.pathname.includes("/group"),
  5196. intv: () => {
  5197. return $(".jsx-3527395752").length;
  5198. },
  5199. root: "main:last",
  5200. elements: {
  5201. question: "h3 div",
  5202. options: ".mb ul li .flex-auto",
  5203. $options: ".mb ul li",
  5204. type: ".mb-s"
  5205. },
  5206. ignore_click: $item => {
  5207. return $item.hasClass("_c");
  5208. },
  5209. fill: (type, answer, $option) => {
  5210. if (type === 4 || type === 2) {
  5211. $(".exam-input").val("answer");
  5212. }
  5213. },
  5214. finished: need_jump => {
  5215. if ($('.round:contains("下一题")').hasClass("ghost")) return false;
  5216. $('.round:contains("下一题")').click();
  5217. return true;
  5218. }
  5219. });
  5220. WorkerJSPlus({
  5221. name: "英华学堂",
  5222. match: () => {
  5223. const pathMatch = location.pathname.includes("/user/work") || location.pathname.includes("/user/exam");
  5224. const matchHostArr = [ "mooc.kdcnu.com", "mooc.yncjxy.com", "mooc.cdcas.com", "mooc.cqcst.edu.cn", "mooc.kmcc.edu.cn", "mooc.wuhues.com" ];
  5225. return pathMatch && matchHostArr.includes(location.host);
  5226. },
  5227. intv: () => {
  5228. return $("#stateName").text().trim() === "进行中";
  5229. },
  5230. root: ".courseexamcon-main",
  5231. elements: {
  5232. question: ".name",
  5233. options: ".list li .txt",
  5234. $options: ".list li .exam-inp",
  5235. type: ".type"
  5236. },
  5237. ignore_click: $item => {
  5238. return $item.prop("checked");
  5239. },
  5240. fill: (type, answer, $option) => {},
  5241. finished: auto_jump => {
  5242. if ($(".next_exam").eq(3).prop("style")[0] == "display") return false;
  5243. $(".next_exam").click();
  5244. }
  5245. });
  5246. WorkerJSPlus({
  5247. name: "厦门在线教育测验",
  5248. match: location.pathname.includes("/nec/student/exam/exam-paper!test"),
  5249. root: "#paper_form > div:nth-child(4) > table:nth-child(1) > tbody:nth-child(2)>tr:even",
  5250. elements: {
  5251. question: "td:eq(1)",
  5252. options: ".optionUl label .el-radio__label,.el-checkbox__label",
  5253. $options: ".optionUl label"
  5254. },
  5255. wrap: obj => {
  5256. obj.options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => {
  5257. return $(y).find("td:eq(1)").text();
  5258. }).toArray();
  5259. obj.$options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => {
  5260. return $(y).find("input");
  5261. });
  5262. obj.type = 0;
  5263. }
  5264. });
  5265. WorkerJSPlus({
  5266. name: "金牌学堂",
  5267. match: location.host === "www.goldgame.com.cn" && location.href.includes("/TestPage"),
  5268. intv: () => {
  5269. return $(".tab-btn-box li").length;
  5270. },
  5271. root: ".test-type-box ul .white-bg",
  5272. elements: {
  5273. question: ".position-relative h3",
  5274. options: ".test-option label p:last-child",
  5275. $options: ".test-option label input"
  5276. },
  5277. wrap: obj => {
  5278. obj.question = obj.question.replace(/题目\d+\:/, "").trim().replace(/^\d+./, "");
  5279. obj.type = getQuestionType(obj.$item.parent().parent().find(".test-type-tips").text());
  5280. if (obj.$options.length > 2 && obj.$options.eq(0).hasClass("radiobox")) {
  5281. obj.type = 0;
  5282. }
  5283. },
  5284. fillFinish: data => {
  5285. $(".answer-sheet li").eq(GLOBAL.index).click();
  5286. }
  5287. });
  5288. WorkerJSPlus({
  5289. name: "青岛开放大学",
  5290. match: location.pathname.includes("/pages/exam/exam.html"),
  5291. intv: () => {
  5292. return $(".exam-content-block .exam-content-topic").length;
  5293. },
  5294. root: ".exam-content-block .exam-content-topic",
  5295. elements: {
  5296. question: ".exam-topic-title",
  5297. options: ".exam-topic-answer .layui-unselect span",
  5298. $options: ".exam-topic-answer .layui-unselect"
  5299. },
  5300. wrap: obj => {
  5301. obj.type = getQuestionType(obj.$item.parent().find(".exam-content-title .exam-content-num").text());
  5302. }
  5303. });
  5304. WorkerJSPlus({
  5305. name: "点墨考试",
  5306. match: location.pathname.includes("/Exam/StartExam"),
  5307. root: "#question div div:first",
  5308. elements: {
  5309. question: "div:first",
  5310. options: "div:first ~ div",
  5311. $options: "div:first ~ div input"
  5312. },
  5313. wrap: obj => {
  5314. obj.type = getQuestionType($(".alert #groupNameSpan").text());
  5315. },
  5316. finished: () => {
  5317. $(".w-100 .btn-light:eq(1)").click();
  5318. return true;
  5319. }
  5320. });
  5321. WorkerJSPlus({
  5322. name: "点墨测验",
  5323. match: location.pathname.includes("/Course/TestPaper"),
  5324. root: ".question",
  5325. elements: {
  5326. question: " div div:first div:first",
  5327. options: " div div:first div:first ~ div",
  5328. $options: " div div:first div:first ~ div input"
  5329. },
  5330. wrap: obj => {
  5331. obj.type = getQuestionType($("h3").text());
  5332. obj.question = obj.question.replace(/^\d+\./, "");
  5333. }
  5334. });
  5335. WorkerJSPlus({
  5336. name: "警官学院",
  5337. match: location.pathname.includes("/bsmytest/startTi.do"),
  5338. root: ".wrapper > div",
  5339. elements: {
  5340. question: ".dx",
  5341. options: "p",
  5342. $options: "p input"
  5343. },
  5344. wrap: obj => {
  5345. if ($(".wrapper .cl").length > 0) {
  5346. obj.question = obj.$item.text().replace(/[0-9]、/, "").replace(/\(.*?\)/g, "").trim().split("$")[0].replace(/\(.*?\)/g, "").trim();
  5347. } else {
  5348. obj.question = obj.question.replace(/[0-9]、/, "").replace(/\(.*?\)/g, "").trim();
  5349. }
  5350. obj.type = getQuestionType(obj.$item.parent().find("h2").text());
  5351. obj.options = obj.options.map(item => {
  5352. return item.replace(/[A-Za-z][\:]/, "").replace(/[A-Za-z][\:,\:]/, "").replace(/\;/, "").trim();
  5353. });
  5354. }
  5355. });
  5356. WorkerJSPlus({
  5357. name: "exam2_euibe_com_exam",
  5358. match: location.hostname === "exam2.euibe.com" && location.pathname === "/KaoShi/ShiTiYe.aspx",
  5359. root: ".question",
  5360. elements: {
  5361. question: ".wenti",
  5362. options: "li label span",
  5363. $options: "li label"
  5364. },
  5365. wrap: obj => {
  5366. obj.type = getQuestionType($(".question_head").text());
  5367. },
  5368. finished: need_jump => {
  5369. $(".paginationjs-next").click();
  5370. return true;
  5371. }
  5372. });
  5373. WorkerJSPlus({
  5374. name: "lzwyedu_jijiaool_com_exam",
  5375. match: () => {
  5376. const pathMatch = location.pathname.includes("/learnspace/course/test/") || location.pathname.includes("/Student/ExamManage/CourseOnlineExamination");
  5377. const matchHostArr = [ "lzwyedu.jijiaool.com", "cgjx.jsnu.edu.cn", "learn-cs.icve.com.cn", "nwnu.jijiaool.com", "lut.jijiaool.com", "learn.courshare.cn", "cj1027-kfkc.webtrn.cn" ];
  5378. return pathMatch && matchHostArr.includes(location.host);
  5379. },
  5380. root: ".test_item",
  5381. elements: {
  5382. question: ".test_item_tit",
  5383. options: ".test_item_theme label .zdh_op_con",
  5384. $options: "label input"
  5385. },
  5386. wrap: obj => {
  5387. obj.question = obj.question.replace(/该题未做$/, "").replace(/^\d+\./, "").replace(/^\d+、/, "").replace(/[((](\d+\s?(\.\d+)?分)[))]$/, "").replace(/^((\d+.(\s+)?)?)[\[((【](.*?)[】))\]]/, "").trim();
  5388. obj.type = getQuestionType(obj.$item.prevAll(".test_item_type:first").text());
  5389. if (obj.type === 3) {
  5390. obj.options = [ "对", "错" ];
  5391. }
  5392. }
  5393. });
  5394. WorkerJSPlus({
  5395. name: "zzx_ouchn_edu_cn_exam",
  5396. match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"),
  5397. root: ".subject",
  5398. elements: {
  5399. question: ".question span",
  5400. options: ".answer>span>p:first-child",
  5401. $options: ".answer>span>p:first-child"
  5402. },
  5403. wrap: obj => {
  5404. if (obj.$options.length > 1) {
  5405. obj.type = 0;
  5406. }
  5407. }
  5408. });
  5409. WorkerJSPlus({
  5410. name: "zzx_ouchn_edu_cn_exam",
  5411. match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"),
  5412. root: ".subject",
  5413. elements: {
  5414. question: ".question span",
  5415. options: ".answer>span>p:first-child",
  5416. $options: ".answer>span>p:first-child"
  5417. },
  5418. wrap: obj => {
  5419. if (obj.$options.length > 1) {
  5420. obj.type = 0;
  5421. }
  5422. }
  5423. });
  5424. WorkerJSPlus({
  5425. name: "havust_hnscen_cn_exam",
  5426. match: location.hostname === "havust.hnscen.cn" && location.pathname.includes("/stuExam/examing/"),
  5427. root: ".main .mt_2 > div",
  5428. elements: {
  5429. question: ".flex_row+div",
  5430. options: ".flex_row+div+div .el-radio__label,.el-checkbox__label",
  5431. $options: ".flex_row+div+div .el-radio__label,.el-checkbox__label",
  5432. type: ".flex_row .mr_2"
  5433. }
  5434. });
  5435. WorkerJSPlus({
  5436. name: "www_zygbxxpt_com_exam",
  5437. match: location.hostname === "www.zygbxxpt.com" && location.pathname.includes("/exam"),
  5438. root: ".Body",
  5439. elements: {
  5440. question: ".QName",
  5441. options: ".QuestinXuanXiang p:parent",
  5442. $options: ".QuestinXuanXiang p:parent",
  5443. type: ".QName span"
  5444. },
  5445. wrap: obj => {
  5446. obj.question = obj.question.replace(/\([^\)]*\)/g, "").replace(/\【.*?\】/g, "");
  5447. obj.options = obj.options.map(item => {
  5448. return item.split(">").pop().trim();
  5449. });
  5450. }
  5451. });
  5452. WorkerJSPlus({
  5453. name: "xuexi_jsou_cn_work",
  5454. match: location.hostname === "xuexi.jsou.cn" && location.pathname.includes("/jxpt-web/student/newHomework/showHomeworkByStatus"),
  5455. root: ".insert",
  5456. elements: {
  5457. question: ".window-title",
  5458. options: ".questionId-option .option-title div[style^=display]",
  5459. $options: ".questionId-option .option-title .numberCover"
  5460. },
  5461. wrap: obj => {
  5462. obj.type = {
  5463. 1: 0,
  5464. 2: 1,
  5465. 7: 3
  5466. }[obj.$item.find(".question-type").val()];
  5467. if (obj.options.length == 2) {
  5468. obj.type = 3;
  5469. }
  5470. }
  5471. });
  5472. WorkerJSPlus({
  5473. name: "czvtc_cjEdu_com_exam",
  5474. match: () => {
  5475. const pathMatch = location.pathname.includes("/ExamInfo") || location.pathname.includes("/Examination");
  5476. const matchHostArr = [ "czvtc.cj-edu.com", "hbkjxy.cj-edu.com", "bhlgxy.cj-edu.com", "hbsi.cj-edu.com", "czys.cj-edu.com", "hbjd.cj-edu.com", "xttc.cj-edu.com", "bvtc.cj-edu.com", "caztc.cj-edu.com" ];
  5477. return pathMatch && matchHostArr.includes(location.host);
  5478. },
  5479. intv: () => {
  5480. return $(".el-container .all_subject>.el-row").length;
  5481. },
  5482. root: ".el-container .all_subject>.el-row",
  5483. elements: {
  5484. question: ".stem div:last-child",
  5485. options: ".el-radio-group .el-radio__label,.el-checkbox-group .el-checkbox__label",
  5486. $options: ".el-radio-group .el-radio__original,.el-checkbox-group .el-checkbox__original"
  5487. },
  5488. wrap: obj => {
  5489. if (obj.$options.length < 3 && obj.$options.eq(0).attr("type") === "radio") {
  5490. obj.type = 3;
  5491. } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") {
  5492. obj.type = 0;
  5493. } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "checkbox") {
  5494. obj.type = 1;
  5495. }
  5496. }
  5497. });
  5498. WorkerJSPlus({
  5499. name: "learning_mhtall_com_exam",
  5500. match: location.host.includes("learning.mhtall.com") && location.pathname.includes("/rest/course/exercise/item"),
  5501. root: "#div_item",
  5502. elements: {
  5503. question: ".item_title",
  5504. options: ".opt div label",
  5505. $options: ".opt div input:not(.button_short)",
  5506. type: "h4"
  5507. },
  5508. ignore_click: $item => {
  5509. return $item.prop("checked");
  5510. },
  5511. wrap: obj => {
  5512. if (obj.type === 0 || obj.type === 3) {
  5513. obj.answer = $(".div_answer").text().match(/[a-zA-Z]/).map(i => {
  5514. return obj.options[i.charCodeAt(0) - 65];
  5515. });
  5516. } else if (obj.type === 2) {
  5517. obj.answer = $(".div_answer").text().replace("参考答案:", "").split(",");
  5518. }
  5519. },
  5520. fill: (type, answer, $option) => {
  5521. if (type === 2 || type === 4) {
  5522. $option.val(answer);
  5523. $(".DIV_TYPE_BLANK .button_short").click();
  5524. }
  5525. },
  5526. fillFinish: () => {
  5527. if ($(".opt+div+div input:eq(1)").val() === "下一题") {
  5528. $(".opt+div+div input:eq(1)").click();
  5529. } else {
  5530. $(".button_short:eq(2)").click();
  5531. }
  5532. }
  5533. });
  5534. WorkerJSPlus({
  5535. name: "168网校(测验)",
  5536. match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/learningCenter/details/"),
  5537. intv: () => {
  5538. return $(".ret-answer").length === 0 && $(".info-container").length;
  5539. },
  5540. root: ".question-item-container",
  5541. elements: {
  5542. question: ".title-content",
  5543. options: ".options .opt-content",
  5544. $options: ".options label",
  5545. type: ".top .type"
  5546. }
  5547. });
  5548. WorkerJSPlus({
  5549. name: "168网校(考试)",
  5550. match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/examination/answer"),
  5551. intv: () => {
  5552. return $(".Answer-area").length;
  5553. },
  5554. root: ".Answer-area",
  5555. elements: {
  5556. question: ".listTit",
  5557. options: ".el-radio__label span:last-child,.el-checkbox__label span:last-child",
  5558. $options: ".el-radio__input,.el-checkbox__input input,.ql-editor p"
  5559. },
  5560. ignore_click: $item => {
  5561. return $item.prop("checked");
  5562. },
  5563. wrap: obj => {
  5564. if (obj.options.length === 0) {
  5565. obj.type = 2;
  5566. }
  5567. console.log(obj);
  5568. },
  5569. fill: (type, answer, $option) => {
  5570. if (type === 2 || type === 4) {
  5571. console.log(answer);
  5572. document.querySelector(".ql-editor p").textContent = answer;
  5573. }
  5574. },
  5575. finished: () => {
  5576. if ($(".ctrl .el-button:contains(下一题)").length != 0) {
  5577. $(".ctrl .el-button:contains(下一题)").click();
  5578. return true;
  5579. } else if ($(".ctrl .el-button:contains(上一题)").length && $(".ctrl button").length === 1) {
  5580. return false;
  5581. }
  5582. }
  5583. });
  5584. WorkerJSPlus({
  5585. name: "法宣在线",
  5586. match: location.host.includes("faxuanyun.com") && location.pathname.includes("/bps/examination"),
  5587. intv: () => {
  5588. return $("#timucontent").length;
  5589. },
  5590. root: "#timucontent",
  5591. elements: {
  5592. question: "h2",
  5593. options: "ul li",
  5594. $options: "ul input"
  5595. },
  5596. ignore_click: $item => {
  5597. return $item.prop("checked");
  5598. },
  5599. wrap: obj => {
  5600. obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
  5601. if ($(".layui-layer-content").length) {
  5602. iframeMsg("tip", {
  5603. type: "stop",
  5604. tip: "答题暂停,请自行通过验证"
  5605. });
  5606. $("#lastButton").click();
  5607. GLOBAL.stop = true;
  5608. return false;
  5609. }
  5610. },
  5611. finished: need_jump => {
  5612. if ($("#nextButton").length) {
  5613. $("#nextButton").click();
  5614. return true;
  5615. } else {
  5616. return false;
  5617. }
  5618. }
  5619. });
  5620. WorkerJSPlus({
  5621. name: "山财培训网 (补考)",
  5622. match: location.host.includes("training.sdufe.edu.cn") && location.pathname.includes("/Exam/OnlineExam/"),
  5623. intv: () => {
  5624. return $(".exam_r_m").length;
  5625. },
  5626. root: ".exam_r_m",
  5627. elements: {
  5628. question: ".bt",
  5629. options: ".btm",
  5630. $options: ".btm input"
  5631. },
  5632. ignore_click: $item => {
  5633. return $item.prop("checked");
  5634. },
  5635. wrap: obj => {
  5636. obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
  5637. obj.options = $("br").parent().text().split(/[A-Z]\./).slice(1).map(item => {
  5638. return item.trim();
  5639. });
  5640. if (obj.type === 3) {
  5641. obj.answer = $("#answerDiv").text().replace("正确答案:", "").split();
  5642. } else {
  5643. obj.answer = $("#answerDiv").text().match(/[A-Z]/g).map(item => {
  5644. return obj.options[item.charCodeAt(0) - 65];
  5645. });
  5646. }
  5647. },
  5648. finished: () => {
  5649. document.querySelector("#next").click();
  5650. if (document.querySelector("#noAskCount").textContent == "0") {
  5651. return false;
  5652. }
  5653. return true;
  5654. }
  5655. });
  5656. WorkerJSPlus({
  5657. name: "和学在线",
  5658. match: (location.host.includes("student.hexuezx") || location.host.includes("student.jxjyzx")) && location.hash.includes("homework-questions"),
  5659. intv: () => {
  5660. return $(".el-card__body").length;
  5661. },
  5662. root: ".el-card__body",
  5663. elements: {
  5664. question: ".stem",
  5665. options: ".el-radio__label,.el-checkbox__label span",
  5666. $options: ".el-radio__input,.el-checkbox__input input"
  5667. },
  5668. ignore_click: $item => {
  5669. return $item.prop("checked");
  5670. },
  5671. wrap: obj => {
  5672. obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
  5673. console.log(obj);
  5674. }
  5675. });
  5676. WorkerJSPlus({
  5677. name: "高教在线",
  5678. match: location.host === "www.cqooc.com" && (location.href.includes("/learn/mooc/exam/do") || location.href.includes("/learn/mooc/testing/do")),
  5679. intv: () => {
  5680. return $("#test-form").length;
  5681. },
  5682. root: "#test-form .cat",
  5683. elements: {
  5684. question: ".stem",
  5685. options: ".option label",
  5686. $options: ".option input"
  5687. },
  5688. ignore_click: $item => {
  5689. return $item.prop("checked");
  5690. },
  5691. wrap: obj => {
  5692. obj.question = obj.question.replace(/\(\d+分\)\d+\.\d+/, "");
  5693. console.log(obj);
  5694. }
  5695. });
  5696. WorkerJSPlus({
  5697. name: "柠檬文才(考试)",
  5698. match: () => {
  5699. const pathMatch = location.pathname.includes("/separation/exam/");
  5700. const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net", "www.wencaischool.net" ];
  5701. return pathMatch && matchHostArr.includes(location.host);
  5702. },
  5703. intv: () => {
  5704. return $("#paperExam").css("display") != "none";
  5705. },
  5706. root: ".paperWrapper .tmList",
  5707. elements: {
  5708. question: ".tmTitleTxt",
  5709. options: ".ansbox .opCont",
  5710. $options: ".ansbox input"
  5711. },
  5712. ignore_click: $item => {
  5713. return $item.prop("checked");
  5714. },
  5715. wrap: obj => {
  5716. if (obj.options.length === 0) {
  5717. obj.type = 2;
  5718. }
  5719. console.log(obj);
  5720. },
  5721. fill: (type, answer, $option) => {
  5722. if (type === 4 || type === 2) {
  5723. $option.val(answer);
  5724. }
  5725. }
  5726. });
  5727. WorkerJSPlus({
  5728. name: "柠檬文才(作业)",
  5729. match: () => {
  5730. const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net" ];
  5731. return (location.pathname.includes("/hblearning/exam/") || location.pathname.includes("/xbsflearning/exam/") || location.pathname.includes("/openlearning/exam/") || location.pathname.includes("/jxlearning/exam/") || location.pathname.includes("/shandonglearning/exam")) && matchHostArr.includes(location.host);
  5732. },
  5733. intv: () => {
  5734. return $("#paperExam").css("display") !== "none";
  5735. },
  5736. root: "#_block_content_exam #tblDataList>tbody>tr",
  5737. elements: {
  5738. question: "tbody:first>tr>td:last table",
  5739. options: ".ansbox .opCont",
  5740. $options: ".ansbox input"
  5741. },
  5742. ignore_click: $item => {
  5743. return $item.prop("checked");
  5744. },
  5745. wrap: obj => {
  5746. obj.question = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").text();
  5747. obj.options = [];
  5748. $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("label").map((i, y) => {
  5749. obj.options.push($(y).text());
  5750. });
  5751. obj.$options = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("input").map((i, y) => {
  5752. return y;
  5753. });
  5754. obj.type = 0;
  5755. if (obj.options.length == 2) {
  5756. obj.type = 3;
  5757. } else if (obj.$options.eq(0).attr("type") != "radio") {
  5758. obj.type = 1;
  5759. }
  5760. console.log(obj);
  5761. }
  5762. });
  5763. WorkerJSPlus({
  5764. name: "福建师范",
  5765. match: location.host === "neo.fjnu.cn" && location.pathname.includes("/resource/index"),
  5766. intv: () => {
  5767. return $(".content").length && !$(".answer-content").length;
  5768. },
  5769. root: ".content",
  5770. elements: {
  5771. question: ".title",
  5772. options: "label .el-radio__label,.el-checkbox__label",
  5773. $options: "label input"
  5774. },
  5775. ignore_click: $item => {
  5776. return $item.prop("checked");
  5777. },
  5778. wrap: obj => {
  5779. console.log(obj);
  5780. }
  5781. });
  5782. WorkerJSPlus({
  5783. name: "优课学堂",
  5784. match: location.host.includes("youkexuetang.cn") && location.pathname.includes("/student/"),
  5785. intv: () => {
  5786. return $(".paperItemBox").length;
  5787. },
  5788. root: ".paperItemBox",
  5789. elements: {
  5790. question: ".stem",
  5791. options: ".el-radio__label,.el-checkbox__label",
  5792. $options: ".el-radio__input,.el-checkbox__input input"
  5793. },
  5794. ignore_click: $item => {
  5795. return $item.prop("checked");
  5796. },
  5797. wrap: obj => {
  5798. obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
  5799. console.log(obj);
  5800. }
  5801. });
  5802. WorkerJSPlus({
  5803. name: "亿学宝云",
  5804. match: location.host.includes("yxbyun.com") && location.pathname.includes("/yxbstudent/"),
  5805. intv: () => {
  5806. return $(".time_header").length || $(".pager_wrap").length;
  5807. },
  5808. hook: () => {
  5809. JSONParseHook(o => {
  5810. if (o.data && o.data.bigContent) {
  5811. GLOBAL.json = parseYxbyunExam(o.data.bigContent).reduce((acc, cur) => {
  5812. return acc.concat(cur);
  5813. }, []);
  5814. console.log(GLOBAL.json);
  5815. }
  5816. });
  5817. },
  5818. root: ".test",
  5819. elements: {
  5820. question: ".type",
  5821. options: ".el-radio-group,.el-checkbox-group label",
  5822. $options: ".el-radio__input,.el-checkbox__input input",
  5823. type: ".el-tag"
  5824. },
  5825. wrap: obj => {
  5826. Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
  5827. },
  5828. ignore_click: $item => {
  5829. return $item.prop("checked");
  5830. }
  5831. });
  5832. WorkerJSPlus({
  5833. name: "考试星(单题)",
  5834. match: Boolean(location.host === "exam.kaoshixing.com" && location.pathname.includes("/exam/exam_start")),
  5835. intv: () => {
  5836. return $("#nextQuestions").length;
  5837. },
  5838. root: ".questions .questions-content",
  5839. elements: {
  5840. question: ".question-name",
  5841. options: ".answers label .words",
  5842. $options: ".answers label"
  5843. },
  5844. ignore_click: $item => {
  5845. return $item.parent().find("input").prop("checked");
  5846. },
  5847. wrap: obj => {
  5848. obj.question = obj.question.replace(/[\((].+?[)\)]/g, "");
  5849. console.log(obj);
  5850. },
  5851. finished: () => {
  5852. if ($("#nextQuestions:contains(下一题)").length && $("#nextQuestions").css("display") !== "none") {
  5853. $("#nextQuestions:contains(下一题)").click();
  5854. return true;
  5855. } else {
  5856. return false;
  5857. }
  5858. }
  5859. });
  5860. WorkerJSPlus({
  5861. name: "易考云",
  5862. match: location.host === "exam.beeouc.com" && location.pathname.includes("/client"),
  5863. intv: () => {
  5864. return $(".question-body").length;
  5865. },
  5866. root: ".question-body",
  5867. elements: {
  5868. question: ".question-stem",
  5869. options: ".question-option label",
  5870. $options: ".question-option input",
  5871. type: ".question-type"
  5872. },
  5873. ignore_click: $item => {
  5874. return $item.prop("checked");
  5875. },
  5876. wrap: obj => {
  5877. console.log(obj);
  5878. },
  5879. finished: () => {
  5880. if ($(".question-footer button:contains(下一题)").length) {
  5881. $(".question-footer button:contains(下一题)").click();
  5882. return true;
  5883. } else {
  5884. return false;
  5885. }
  5886. }
  5887. });
  5888. WorkerJSPlus({
  5889. name: "伊犁师范成人教育",
  5890. match: location.host === "exam.weirenzheng.cn" && (location.pathname.includes("//GeneralTestPaper/Testing/") || location.pathname.includes("//GeneralTestPaper/SNTesting")),
  5891. intv: () => {
  5892. return $(".topic").length;
  5893. },
  5894. root: ".topic",
  5895. elements: {
  5896. question: ".qsctt",
  5897. options: ".xuan li",
  5898. $options: ".choice input"
  5899. },
  5900. ignore_click: $item => {
  5901. return $item.prop("checked");
  5902. },
  5903. wrap: obj => {
  5904. obj.options = obj.options.map(i => {
  5905. return i.replace(/^[A-Z] \. /, "");
  5906. });
  5907. if (obj.$options.length == 2) {
  5908. obj.options = [ "正确", "错误" ];
  5909. obj.type = 3;
  5910. }
  5911. }
  5912. });
  5913. WorkerJSPlus({
  5914. name: "绎通云课堂 (作业)",
  5915. match: location.host.includes("ytccr.com") && (location.hash.includes("#/learning-work") || location.hash.includes("#/learning-details")),
  5916. intv: () => {
  5917. return $(".left-question").length;
  5918. },
  5919. root: ".border-item",
  5920. elements: {
  5921. question: ".qa-title",
  5922. options: "label .opt-title-cnt",
  5923. $options: "label input"
  5924. },
  5925. ignore_click: $item => {
  5926. return $item.prop("checked");
  5927. }
  5928. });
  5929. WorkerJSPlus({
  5930. name: "重庆大学网络教育学院 (作业)",
  5931. match: location.host === "exercise.5any.com" && location.pathname.includes("/Exercise/WebUI/Test/Answer"),
  5932. intv: () => {
  5933. return $(".examtime-content").length;
  5934. },
  5935. root: ".subject .font-16",
  5936. elements: {
  5937. question: ".stem .richtextcontent",
  5938. options: ".option .richtextcontent",
  5939. $options: ".option label input"
  5940. },
  5941. ignore_click: $item => {
  5942. return $item.prop("checked");
  5943. }
  5944. });
  5945. WorkerJSPlus({
  5946. name: "毕节幼儿师范",
  5947. match: location.host === "px.gzbjyzjxjy.cn" || location.host === "px.ggcjxjy.cn" && location.pathname.includes("/exam/shiti/dopapers"),
  5948. intv: () => {
  5949. return $(".panel-body").length;
  5950. },
  5951. root: ".panel-body>div",
  5952. elements: {
  5953. question: ".testpaper-question-stem",
  5954. options: ".testpaper-question-choices li",
  5955. $options: ".testpaper-question-footer input"
  5956. },
  5957. ignore_click: $item => {
  5958. return $item.prop("checked");
  5959. },
  5960. wrap: obj => {
  5961. console.log(obj);
  5962. }
  5963. });
  5964. WorkerJSPlus({
  5965. name: "贵州继续教育",
  5966. match: location.host === "www.gzjxjy.gzsrs.cn" && location.pathname.includes("/personback/"),
  5967. intv: () => {
  5968. return $(".question-title").length;
  5969. },
  5970. root: ".question-title",
  5971. elements: {
  5972. question: ".show-text",
  5973. options: "label",
  5974. $options: "label input"
  5975. },
  5976. ignore_click: $item => {
  5977. return $item.prop("checked");
  5978. },
  5979. wrap: obj => {
  5980. console.log(obj);
  5981. }
  5982. });
  5983. WorkerJSPlus({
  5984. name: "和学自考",
  5985. match: location.host === "zkpt.qdu.edu.cn" && location.pathname.includes("/examStu/exam/examPaper"),
  5986. intv: () => {
  5987. return $(".ant-spin-container").length;
  5988. },
  5989. root: ".ant-row",
  5990. elements: {
  5991. options: "label",
  5992. $options: "label input"
  5993. },
  5994. ignore_click: $item => {
  5995. return $item.prop("checked");
  5996. },
  5997. wrap: obj => {
  5998. obj.question = obj.$item.parent().parent().prev().text();
  5999. console.log(obj);
  6000. }
  6001. });
  6002. WorkerJSPlus({
  6003. name: "专技天下",
  6004. match: location.host.includes("zgzjzj.com") && location.pathname.includes("/examination/perpar.html"),
  6005. intv: () => {
  6006. return $(".question_index").length;
  6007. },
  6008. root: ".question_index",
  6009. elements: {
  6010. question: "p",
  6011. options: ".options li p,li>span:last-child",
  6012. $options: ".options li",
  6013. type: "p span"
  6014. },
  6015. ignore_click: $item => {
  6016. return $item.hasClass("active");
  6017. }
  6018. });
  6019. WorkerJSPlus({
  6020. name: "睿学补考",
  6021. match: location.href.includes("exam-app-exam-paper") && location.host.includes("ks.hustsnde.com"),
  6022. intv: () => {
  6023. return $("#paper").length;
  6024. },
  6025. root: "#paper .content-box",
  6026. elements: {
  6027. question: "ul li:eq(0) .desc",
  6028. options: "ul li:eq(1)",
  6029. $options: "ul label input",
  6030. type: ".title"
  6031. },
  6032. ignore_click: $item => {
  6033. return $item.prop("checked");
  6034. },
  6035. wrap: obj => {
  6036. const options = obj.options[0].trim().split(/\[[A-Z]:?\]/).splice(1).map(i => {
  6037. return i.trim();
  6038. }).filter(i => i);
  6039. if (options.length === 0) {
  6040. obj.options = obj.options[0].trim().split(/\(?[A-Z\.?]\)?/).splice(1).map(i => {
  6041. return i.trim();
  6042. }).filter(i => i);
  6043. } else {
  6044. obj.options = options;
  6045. }
  6046. if (obj.type === 3) {
  6047. obj.options = [ "正确", "错误" ];
  6048. }
  6049. }
  6050. });
  6051. WorkerJSPlus({
  6052. name: "云上河开",
  6053. match: location.host === "jx.open.ha.cn" && location.pathname.includes("/jxpt-web/student/homework/showHomeworkByStatus"),
  6054. intv: () => {
  6055. return $("#shiti-content").length;
  6056. },
  6057. root: ".insert",
  6058. elements: {
  6059. question: ".window-title",
  6060. options: "ul li div:last-child",
  6061. $options: "ul li .numberCover"
  6062. },
  6063. ignore_click: $item => {
  6064. return $item.parent().hasClass("answer-title");
  6065. },
  6066. wrap: obj => {
  6067. obj.type = getQuestionType(obj.$item.parents(".layui-colla-item").find(".titleType").text());
  6068. }
  6069. });
  6070. WorkerJSPlus({
  6071. name: "ycjy.lut.edu.cn",
  6072. match: location.host === "ycjy.lut.edu.cn" && location.pathname.includes("/learnspace/course/test/coursewareTest_intoTestPage.action"),
  6073. intv: () => {
  6074. return $(".bank_cont").length;
  6075. },
  6076. root: ".test_item",
  6077. elements: {
  6078. options: "label",
  6079. $options: "label input"
  6080. },
  6081. ignore_click: $item => {
  6082. return $item.prop("checked");
  6083. },
  6084. wrap: obj => {
  6085. obj.type = getQuestionType(obj.$item.parent().find(".test_item_type").text());
  6086. obj.question = obj.$item.find(".test_item_tit").contents()[0].nodeValue.trim();
  6087. }
  6088. });
  6089. WorkerJSPlus({
  6090. name: "exam.euibe.com",
  6091. match: location.host === "exam.euibe.com" && location.pathname.includes("/KaoShi/ShiTiYe.aspx"),
  6092. intv: () => {
  6093. return $(".question_list").length;
  6094. },
  6095. root: ".question",
  6096. elements: {
  6097. question: ".wenti .stem",
  6098. options: "label span",
  6099. $options: "label input"
  6100. },
  6101. ignore_click: $item => {
  6102. return $item.prop("checked");
  6103. },
  6104. wrap: obj => {
  6105. obj.type = getQuestionType(obj.$item.parents(".question_list").find(".question_head").text());
  6106. },
  6107. finished: need_jump => {
  6108. if ($(".paginationjs-next").hasClass("disabled")) {
  6109. return false;
  6110. }
  6111. $(".paginationjs-next").click();
  6112. return true;
  6113. }
  6114. });
  6115. WorkerJSPlus({
  6116. name: "学晖教育",
  6117. match: location.host === "xhjy.ldzxjy.com" && location.pathname.includes("tikuUserBatch/keepTopic"),
  6118. intv: () => {
  6119. return $(".radio").length;
  6120. },
  6121. root: ".radio",
  6122. elements: {
  6123. question: ".issueTitle",
  6124. options: "ul li span",
  6125. $options: "ul li",
  6126. type: ".issueTypes"
  6127. },
  6128. ignore_click: $item => {
  6129. return $item.prop("checked");
  6130. },
  6131. finished: need_jump => {
  6132. if ($(".next").text().includes("交卷")) {
  6133. return false;
  6134. }
  6135. $(".next").click();
  6136. return true;
  6137. }
  6138. });
  6139. WorkerJSPlus({
  6140. name: "东财在线",
  6141. match: location.host === "classroom.edufe.com.cn" && (location.pathname.includes("/PracticePaper") || location.pathname.includes("/HomeWorkPaper")),
  6142. intv: () => {
  6143. return $(".TK-main").length;
  6144. },
  6145. root: ".CBTPaperMain-trunk",
  6146. elements: {
  6147. question: ".CBTPaperMain-divInline",
  6148. options: "ul li label",
  6149. $options: "ul li label"
  6150. },
  6151. ignore_click: $item => {
  6152. return $item.hasClass("_CheckBox_checked");
  6153. }
  6154. });
  6155. WorkerJSPlus({
  6156. name: "北华大学在线教育",
  6157. match: () => {
  6158. const pathnameArr = [ "cj1026-kfkc.webtrn.cn", "beihua.peishenjy.com" ];
  6159. return pathnameArr.includes(location.pathname) && location.pathname.includes("/Learning/CourseOnlineExamination") || location.pathname.includes("/learnspace/course/test");
  6160. },
  6161. intv: () => {
  6162. return $(".s_mi").length;
  6163. },
  6164. root: ".test_item",
  6165. elements: {
  6166. question: ".test_item_tit",
  6167. options: " label",
  6168. $options: "label input"
  6169. },
  6170. ignore_click: $item => {
  6171. return $item.prop("checked");
  6172. },
  6173. wrap: obj => {
  6174. console.log(obj);
  6175. }
  6176. });
  6177. WorkerJSPlus({
  6178. name: "上海立达学院",
  6179. match: location.host === "kkzxsx.lidapoly.edu.cn" && location.pathname.includes("/exam/"),
  6180. intv: () => {
  6181. return $(".exam-question").length;
  6182. },
  6183. root: ".main .item",
  6184. elements: {
  6185. question: ".text",
  6186. options: ".options label .el-radio__label,.el-checkbox__label",
  6187. $options: ".options label"
  6188. },
  6189. ignore_click: $item => {
  6190. return $item.hasClass("is-checked");
  6191. },
  6192. wrap: obj => {
  6193. obj.type = getQuestionType(obj.$item.parent().find(".text").text());
  6194. console.log(obj);
  6195. }
  6196. });
  6197. WorkerJSPlus({
  6198. name: "石家庄科技继续教育",
  6199. match: location.host.includes("kc.jxjypt.cn") && location.pathname.includes("/paper/start"),
  6200. intv: () => {
  6201. return $(".sub-content").length;
  6202. },
  6203. root: ".sub-content",
  6204. elements: {
  6205. question: ".sub-dotitle",
  6206. options: ".sub-answer dd",
  6207. $options: ".sub-answer dd,.mater-respond textarea",
  6208. type: ".sub-dotitle i"
  6209. },
  6210. ignore_click: $item => {
  6211. return $item.hasClass("cho-this");
  6212. },
  6213. wrap: obj => {
  6214. console.log(obj);
  6215. },
  6216. fill: (type, answer, $option) => {
  6217. if (type === 4) {
  6218. $option.val(answer);
  6219. }
  6220. }
  6221. });
  6222. WorkerJSPlus({
  6223. name: "石家庄理工职业学院",
  6224. match: location.host.includes("edu.tianzerencai.com") && location.pathname.includes("/examinationDetail"),
  6225. intv: () => {
  6226. return $(".topic").length;
  6227. },
  6228. root: ".topic",
  6229. elements: {
  6230. question: ".title",
  6231. options: ".main",
  6232. $options: ".main",
  6233. type: ".title"
  6234. },
  6235. ignore_click: $item => {
  6236. return $item.hasClass("cho-this");
  6237. },
  6238. wrap: obj => {
  6239. if (obj.type === 3) {
  6240. obj.options = [ "正确", "错误" ];
  6241. obj.$options = obj.$item.find(".judge button");
  6242. } else if (obj.type === 1) {
  6243. obj.options = obj.$item.find(".checkbox .option_text").map((i, y) => {
  6244. return $(y).text();
  6245. }).toArray();
  6246. obj.$options = obj.$item.find(".checkbox button");
  6247. } else if (obj.type === 0) {
  6248. obj.options = obj.$item.find(".radio .option_text").map((i, y) => {
  6249. return $(y).text();
  6250. }).toArray();
  6251. obj.$options = obj.$item.find(".radio button");
  6252. }
  6253. console.log(obj);
  6254. }
  6255. });
  6256. WorkerJSPlus({
  6257. name: "国开军盾",
  6258. match: location.host.includes("s.jundunxueyuan.com") && location.hash.includes("#/exam/"),
  6259. intv: () => {
  6260. return $(".the-paper .section-item-question-item").length;
  6261. },
  6262. root: ".section-item-question-item",
  6263. elements: {
  6264. plat: 43,
  6265. question: ".question-tit",
  6266. options: ".el-radio-group label,.el-checkbox-group label",
  6267. $options: ".el-radio-group input,.el-checkbox-group input",
  6268. type: ".sub-dotitle i"
  6269. },
  6270. ignore_click: $item => {
  6271. return $item.prop("checked");
  6272. },
  6273. wrap: obj => {
  6274. obj.type = getQuestionType(obj.$item.parents(".section-item").find(".section-item-tit").text());
  6275. console.log(obj);
  6276. }
  6277. });
  6278. WorkerJSPlus({
  6279. name: "博学bx",
  6280. match: location.host.includes("bx.bossyun.com") && location.pathname.includes("/bx/study/examine"),
  6281. intv: () => {
  6282. return $(".question-list").length;
  6283. },
  6284. root: ".question-list",
  6285. elements: {
  6286. question: ".title",
  6287. options: ".ant-radio-group label,.ant-checkbox-group label",
  6288. $options: ".ant-radio-group input,.ant-checkbox-group input",
  6289. type: ".tag"
  6290. },
  6291. ignore_click: $item => {
  6292. return $item.prop("checked");
  6293. }
  6294. });
  6295. WorkerJSPlus({
  6296. name: "博学bx",
  6297. match: location.host.includes("bx.bossyun.com") && location.pathname.includes("/bx/study/examine"),
  6298. intv: () => {
  6299. return $(".question-list").length;
  6300. },
  6301. root: ".question-list",
  6302. elements: {
  6303. question: ".title",
  6304. options: ".ant-radio-group label,.ant-checkbox-group label",
  6305. $options: ".ant-radio-group input,.ant-checkbox-group input",
  6306. type: ".tag"
  6307. },
  6308. ignore_click: $item => {
  6309. return $item.prop("checked");
  6310. }
  6311. });
  6312. WorkerJSPlus({
  6313. name: "电中在线",
  6314. match: location.host.includes("old-zzx.ouchn.edu.cn") && location.pathname.includes("/edu/public/student/"),
  6315. intv: () => {
  6316. return $(".subject").length;
  6317. },
  6318. root: ".subject",
  6319. elements: {
  6320. question: ".question",
  6321. options: ".answer .option-name",
  6322. $options: ".answer"
  6323. },
  6324. wrap: obj => {
  6325. obj.type = 0;
  6326. console.log(obj);
  6327. }
  6328. });
  6329. WorkerJSPlus({
  6330. name: "爱学",
  6331. match: () => {
  6332. const pathMatch = location.pathname.includes("/Web/Test/doing");
  6333. const matchHostArr = [ "ai.ztbu.edu.cn", "www.51ixuejiao.com" ];
  6334. return pathMatch && matchHostArr.includes(location.host);
  6335. },
  6336. intv: () => {
  6337. return $("card-title").length;
  6338. },
  6339. root: ".exam dd",
  6340. elements: {
  6341. question: "card-title",
  6342. options: ".ans_area div",
  6343. $options: ".ans_area div",
  6344. type: "info"
  6345. },
  6346. ignore_click: $item => {
  6347. return $item.attr("selected") === "selected";
  6348. },
  6349. wrap: obj => {
  6350. console.log(obj);
  6351. },
  6352. fillFinish: data => {
  6353. if (data.ans.includes("span") || data.type === 1) {
  6354. $(".move_btn span:last").click();
  6355. }
  6356. }
  6357. });
  6358. WorkerJSPlus({
  6359. name: "人卫智网",
  6360. match: location.host.includes("exam.ipmph.com") && location.pathname.includes("/front/myschool/index.html"),
  6361. intv: () => {
  6362. return $(".body").length;
  6363. },
  6364. root: ".body",
  6365. elements: {
  6366. question: ".fch2 font",
  6367. options: ".selet .el-radio__label",
  6368. $options: ".selet input"
  6369. },
  6370. wrap: obj => {
  6371. obj.type = 0;
  6372. console.log(obj);
  6373. },
  6374. finished: () => {
  6375. document.querySelector(".next-btn .text-right a:last-child").click();
  6376. }
  6377. });
  6378. WorkerJSPlus({
  6379. name: "卫生人力资源系统",
  6380. match: location.host.includes("vgos.zbwsrc.cn") && location.pathname.includes("/TESExamClient/"),
  6381. intv: () => {
  6382. return $(".testitem").length;
  6383. },
  6384. root: ".testitem",
  6385. elements: {
  6386. question: ".stem",
  6387. options: ".inputitem li",
  6388. $options: ".inputitem input"
  6389. },
  6390. wrap: obj => {
  6391. obj.type = 0;
  6392. console.log(obj);
  6393. }
  6394. });
  6395. WorkerJSPlus({
  6396. name: "继教在线(考试)",
  6397. match: location.pathname.includes("/Student/ExamManage/CourseOnlineExamination"),
  6398. intv: () => {
  6399. return $(".test_item").length;
  6400. },
  6401. root: ".test_item",
  6402. elements: {
  6403. question: ".test_item_tit",
  6404. options: ".test_item_theme label",
  6405. $options: ".test_item_theme input"
  6406. },
  6407. ignore_click: $item => {
  6408. return $item.prop("checked");
  6409. },
  6410. wrap: obj => {
  6411. const $item = obj.$item;
  6412. obj.type = getQuestionType($item.prevAll(".test_item_type").text());
  6413. if (obj.type === 3) {
  6414. obj.options = [ "正确", "错误" ];
  6415. }
  6416. }
  6417. });
  6418. WorkerJSPlus({
  6419. name: "国开",
  6420. match: location.host === "lms.ouchn.cn" && location.pathname.includes("/exam/"),
  6421. intv: () => {
  6422. return $(".loading-gif").hasClass("ng-hide") && $(".hd .examinee .submit-label").eq(0).text() === "";
  6423. },
  6424. root: ".card ol .single_selection,.multiple_selection,.true_or_false,.short_answer",
  6425. elements: {
  6426. question: ".summary-title .subject-description",
  6427. options: ".subject-options li .option-content",
  6428. $options: ".subject-options label .left",
  6429. type: ".summary-sub-title span:eq(0)"
  6430. },
  6431. ignore_click: ($item, type) => {
  6432. return type === 1 && $item.find("input").hasClass("ng-not-empty");
  6433. }
  6434. });
  6435. WorkerJSPlus({
  6436. name: "广开",
  6437. match: () => {
  6438. const pathMatch = location.pathname.includes("/mod/quiz/attempt.php");
  6439. const matchHostArr = [ "moodle.syxy.ouchn.cn", "xczxzdbf.moodle.qwbx.ouchn.cn", "elearning.bjou.edu.cn", "whkpc.hnqtyq.cn:5678", "course.ougd.cn", "study.ouchn.cn" ];
  6440. return pathMatch && matchHostArr.includes(location.host);
  6441. },
  6442. root: ".que",
  6443. elements: {
  6444. question: ".qtext",
  6445. options: ".answer div label,.flex-fill",
  6446. $options: ".answer div input:visible"
  6447. },
  6448. wrap: data => {
  6449. if (data.type === undefined) {
  6450. try {
  6451. data.type = 4;
  6452. data.$item.find(".qtext .accesshide").remove();
  6453. data.question = formatString(data.$item.find(".qtext").html());
  6454. data.$options = data.$item.find("input[id$=_answer]");
  6455. } catch (e) {}
  6456. }
  6457. },
  6458. ignore_click: $item => {
  6459. return Boolean($item.parent().find("input").eq(-1).prop("checked"));
  6460. },
  6461. finished: () => {
  6462. $(".submitbtns .btn-primary").click();
  6463. },
  6464. fill: (type, answer, $option) => {
  6465. if (type === 4) {
  6466. console.log(type, answer, $option);
  6467. console.log($option.attr("id"));
  6468. $option.val(answer);
  6469. }
  6470. }
  6471. });
  6472. WorkerJSPlus({
  6473. name: "保定继续教育",
  6474. match: location.pathname.includes("/exam/answer.html"),
  6475. root: ".stem-container",
  6476. elements: {
  6477. question: ".stem span",
  6478. options: ".option div .optStem",
  6479. $options: ".option div input"
  6480. },
  6481. intv: () => {
  6482. return $("#question").length;
  6483. },
  6484. wrap: obj => {
  6485. obj.type = getQuestionType(obj.$item.parent().parent().find(".description").text());
  6486. }
  6487. });
  6488. WorkerJSPlus({
  6489. name: "noNiExam.js",
  6490. match: location.pathname === "/app-afstudy/self_test.html",
  6491. root: ".lineClass .b-papp-root",
  6492. elements: {
  6493. question: ".b-exam-top .b-exam-tit",
  6494. options: ".b-exam-box li label",
  6495. $options: ".b-exam-box li input",
  6496. type: ".b-exam-top .b-exam-type"
  6497. },
  6498. ignore_click($item) {
  6499. return $item.prop("checked");
  6500. },
  6501. wrap(obj) {
  6502. obj.options = obj.options.map(i => {
  6503. return i.replace(/[A-Za-z][\:]/, "").replace(/[A-Za-z][\:,\:]/, "").replace(/\;/, "").trim();
  6504. });
  6505. }
  6506. });
  6507. WorkerJSPlus({
  6508. name: "www_pbaqks_com_text",
  6509. match: location.host === "www.pbaqks.com" && location.pathname.includes("/P_ExamDetail/OnlineStuday"),
  6510. root: ".main-container .single-box",
  6511. elements: {
  6512. question: ".single-main:first",
  6513. options: ".choose-box label",
  6514. $options: ".choose-box label",
  6515. type: ".single-container .font-title",
  6516. answer: "input:eq(1)"
  6517. },
  6518. ignore_click: $i => {
  6519. return $i.find("input").is(":checked");
  6520. },
  6521. wrap: obj => {
  6522. obj.question = obj.question.replace("标准答案", "").replace(/^\d+\./, "").replace(/\[.+?\]/g, "").trim();
  6523. },
  6524. fillFinish: () => {
  6525. if ($(".main-container .single-box").find("input:eq(1)").eq(GLOBAL.index - 1).attr("value").split("").length > 1) {
  6526. jQuery(".main-container .confirm a:last-child").click();
  6527. }
  6528. }
  6529. });
  6530. WorkerJSPlus({
  6531. name: "安徽继续教育",
  6532. match: location.pathname.includes("/study/html/content/studying/") || (location.pathname === "/study/html/content/tkOnline/" || location.pathname === "/study/html/content/sxsk/" || location.pathname === "/study/html/content/bkExam/"),
  6533. intv: () => {
  6534. return ($(".e-save-b").length || $(".e-b-g").length) && $(".totalscore").length === 0;
  6535. },
  6536. root: ".e-q",
  6537. elements: {
  6538. question: ".e-q-q .ErichText",
  6539. options: ".e-a-g li",
  6540. $options: ".e-a-g li"
  6541. },
  6542. ignore_click: $item => {
  6543. return $item.attr("class").includes("checked");
  6544. },
  6545. wrap: obj => {
  6546. obj.type = getQuestionType(obj.$item.parent().prev().find(".e-text").text());
  6547. obj.options = obj.options.map(i => {
  6548. return formatString(i.replaceAll(/^[ab]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  6549. });
  6550. }
  6551. });
  6552. WorkerJSPlus({
  6553. name: "大连/九江",
  6554. match: location.href.includes("/onlineclass/exam/"),
  6555. intv: () => {
  6556. return $(".excer_list_view___2Ahg9") || $(".excer_list_view___YOSCa");
  6557. },
  6558. root: ".single_excer_item___lFMCm,.single_excer_item___2lGB8",
  6559. elements: {
  6560. plat: 40,
  6561. question: ".title_content___1Qagx .title_content_text___27NIL, .title_content___24J6D .title_content_text___8ruL4",
  6562. options: ".options_content___nXSwG label .option_text___udjiE, .options_content___2YgyG label .option_text___1mfcu",
  6563. $options: ".options_content___nXSwG label input,.options_content___2YgyG label input",
  6564. type: ".title_content___1Qagx span:eq(1),.title_content___24J6D span:eq(1)"
  6565. },
  6566. ignore_click: $item => {
  6567. return $($item).parent().hasClass("ant-checkbox-checked");
  6568. },
  6569. wrap: obj => {
  6570. console.log(obj);
  6571. },
  6572. fill: (type, answer, $option) => {
  6573. if (type === 4 || type === 2) {
  6574. $option.val(answer);
  6575. }
  6576. }
  6577. });
  6578. WorkerJSPlus({
  6579. name: "新疆继续教育",
  6580. hook: () => {
  6581. function parseXinJiangAgain(questions) {
  6582. return questions.map(item => {
  6583. const answer = [];
  6584. const options = item.answers.map(opt => {
  6585. if (opt.isAnswer === "0") answer.push(formatString(opt.name));
  6586. return formatString(opt.name);
  6587. });
  6588. const type = item.types === "2" ? 3 : parseInt(item.types);
  6589. return {
  6590. question: item.name,
  6591. options: options,
  6592. answer: answer,
  6593. type: type
  6594. };
  6595. });
  6596. }
  6597. JSONParseHook(o => {
  6598. if (o.success && o.data.exam) {
  6599. const arr = o.data.exam.assessList.map(i => {
  6600. return i.questionList;
  6601. }).flat();
  6602. GLOBAL.json = parseXinJiangAgain(arr);
  6603. }
  6604. });
  6605. },
  6606. match: location.host === "www.ttcdw.cn" && location.pathname.includes("/p/uExam/goExam/"),
  6607. root: ".question-item",
  6608. elements: {
  6609. question: ".question-item-title span",
  6610. options: ".question-item-option label .el-checkbox__label,.el-radio__label",
  6611. $options: ".question-item-option label"
  6612. },
  6613. wrap: obj => {
  6614. Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
  6615. },
  6616. intv: () => {
  6617. return !$("div").hasClass("entrying-wrap");
  6618. },
  6619. ignore_click: $item => {
  6620. return $item.hasClass("is-checked");
  6621. },
  6622. fill: (type, answer, $option) => {
  6623. if (type === 4 || type === 2) {
  6624. $option.val(answer);
  6625. }
  6626. }
  6627. });
  6628. WorkerJSPlus({
  6629. name: "华侨继续教育",
  6630. match: location.pathname.includes("/exam/student/exam/resource/paper_card2"),
  6631. intv: () => {
  6632. return $(".ui-question-answer-right").length === 0;
  6633. },
  6634. root: ".ui-question-group .ui-question",
  6635. elements: {
  6636. question: ".ui-question-title div",
  6637. options: ".ui-question-options div",
  6638. $options: ".ui-question-options .ui-question-options-order,.ke-container"
  6639. },
  6640. wrap: obj => {
  6641. obj.type = getQuestionType(obj.$item.parent().find("h2").text());
  6642. },
  6643. ignore_click: $item => {
  6644. return $item.parent().hasClass("ui-option-selected");
  6645. },
  6646. fill: (type, answer) => {
  6647. if (type === 4 || type === 2 || type === 6) {
  6648. const x = GLOBAL.index - $(".ui-question-options ").length - 1;
  6649. KindEditor.instances[x].html(answer);
  6650. }
  6651. }
  6652. });
  6653. WorkerJSPlus({
  6654. name: "上海开放大学",
  6655. match: location.pathname.includes("/study/assignment/preview.aspx") || location.pathname.includes("/study/assignment/continuation.aspx"),
  6656. hook: () => {
  6657. if (GLOBAL.finish || $("a:contains(已完成批阅)").length === 1) {
  6658. iframeMsg("tip", {
  6659. type: "hidden",
  6660. tip: "本页面已做完,无需自动答题"
  6661. });
  6662. return true;
  6663. }
  6664. },
  6665. root: ".e-q",
  6666. elements: {
  6667. question: ".e-q-q .ErichText",
  6668. options: ".e-a-g li",
  6669. $options: ".e-a-g li"
  6670. },
  6671. wrap: obj => {
  6672. obj.type = getQuestionType(obj.$item.parent().parent().parent().find(".e-text").eq(0).text());
  6673. obj.options = obj.options.map(i => {
  6674. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  6675. });
  6676. },
  6677. ignore_click: $item => {
  6678. return $item.attr("class").includes("checked");
  6679. }
  6680. });
  6681. WorkerJSPlus({
  6682. name: "浙江考试",
  6683. match: location.pathname === "/web-qz/moni/exam/exam_toExam.action",
  6684. root: ".dt_tmcon",
  6685. elements: {
  6686. question: "div:eq(0) span:eq(1)",
  6687. options: "div:eq(1) p",
  6688. $options: "div:eq(1) p input"
  6689. },
  6690. ignore_click: $item => {
  6691. return $item.prop("checked");
  6692. },
  6693. wrap: obj => {
  6694. obj.type = getQuestionType(obj.$item.parents().find(".dt_rtitle1").eq(0).text());
  6695. obj.options = obj.options.map(i => {
  6696. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  6697. });
  6698. if (obj.type === 0) {
  6699. obj.answer = [ JSON.parse($("#quesSSForm #userAnssStr_0").val()).rightAnswer ];
  6700. uploadAnswer([ obj ]);
  6701. }
  6702. },
  6703. finished: () => {
  6704. return $(".page li input:eq(2)").attr("disabled") !== "disabled";
  6705. },
  6706. fillFinish: () => {
  6707. $(".page li input:eq(2)").click();
  6708. }
  6709. });
  6710. WorkerJSPlus({
  6711. name: "在浙学考试",
  6712. match: location.host === "www.zjooc.cn" && (location.pathname.includes("/homework/") || location.pathname.includes("/test/") || location.pathname.includes("/exam/")),
  6713. hook: () => {
  6714. function parseZaiZheXue(problems) {
  6715. return problems.map(item => {
  6716. if (!item.rightAnswer) return undefined;
  6717. const subjectType = item.subjectType;
  6718. let type = -1;
  6719. const question = formatString(item.subjectName);
  6720. const answer = [];
  6721. const options = [];
  6722. if (subjectType === 1 || subjectType === 2) {
  6723. type = subjectType - 1;
  6724. for (let subjectOption of item.subjectOptions) {
  6725. const opt = formatString(subjectOption.optionContent);
  6726. options.push(opt);
  6727. if (item.rightAnswer.includes(subjectOption.optionHead)) {
  6728. answer.push(opt);
  6729. }
  6730. }
  6731. } else if (subjectType === 3) {
  6732. type = 3;
  6733. answer.push(item.rightAnswer === "yes" ? "正确" : "错误");
  6734. } else {
  6735. return undefined;
  6736. }
  6737. return {
  6738. question: question,
  6739. options: options,
  6740. type: type,
  6741. answer: answer
  6742. };
  6743. }).filter(i => i && i.answer.length > 0);
  6744. }
  6745. if (!(location.pathname.includes("/homework/do") || location.pathname.includes("/test/do") || location.pathname.includes("/exam/do"))) {
  6746. JSONParseHook(o => {
  6747. if (o.data && o.data.paperName && o.data.clazzIds && o.data.paperSubjectList) {
  6748. const data = parseZaiZheXue(o.data.paperSubjectList);
  6749. console.log(data);
  6750. }
  6751. });
  6752. return true;
  6753. }
  6754. },
  6755. root: ".questiono-item",
  6756. elements: {
  6757. question: "h6 .processing_img",
  6758. options: ".questiono-main label .el-radio__label,.el-checkbox__label",
  6759. $options: ".questiono-main label"
  6760. },
  6761. wrap: obj => {
  6762. obj.type = getQuestionType(obj.$item.parent().prev().text());
  6763. obj.options = obj.options.map(i => {
  6764. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  6765. });
  6766. },
  6767. ignore_click: $item => {
  6768. return $item.hasClass("is-checked");
  6769. }
  6770. });
  6771. WorkerJSPlus({
  6772. name: "在浙学(测验/考试)",
  6773. match: location.host === "www.zjooc.cn" && location.pathname.includes("/singleQuestion/do/"),
  6774. intv: () => {
  6775. return $(".settingsel-dialog").css("display") === "none";
  6776. },
  6777. root: ".question_content:first",
  6778. elements: {
  6779. question: ".question_title",
  6780. options: ".question_content .radio_content div",
  6781. $options: ".question_content label"
  6782. },
  6783. wrap: obj => {
  6784. obj.type = getQuestionType(obj.$item.parent().find(".question_title p").eq(0).text());
  6785. obj.options = obj.options.map(i => {
  6786. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").replace(".", "").trim());
  6787. });
  6788. },
  6789. ignore_click: $item => {
  6790. return $item.hasClass("is-checked");
  6791. },
  6792. finished: () => {
  6793. if ($(".question_btn .el-button:contains(下一题)").hasClass("is-disabled")) return false;
  6794. $(".el-button:contains(下一题)").click();
  6795. return true;
  6796. }
  6797. });
  6798. WorkerJSPlus({
  6799. name: "福建继续教育测验|作业",
  6800. match: location.pathname === "/Web_Study/Student/Center/MyWorkOnView" || location.pathname === "/Web_Study/Student/Center/MyExamOnView",
  6801. intv: () => {
  6802. return $(".samllTopicNav").length;
  6803. },
  6804. root: ".topic-cont",
  6805. elements: {
  6806. question: "p",
  6807. options: ".options li span",
  6808. $options: ".options li"
  6809. },
  6810. wrap: obj => {
  6811. obj.options = obj.options.map(i => {
  6812. return i.replace(/选项[A-Za-z]/, "").trim();
  6813. });
  6814. obj.type = {
  6815. 1: 0,
  6816. 2: 1,
  6817. 3: 3,
  6818. 6: 4
  6819. }[obj.$item.attr("itemtype")];
  6820. if (obj.type === undefined) obj.type = 4;
  6821. },
  6822. ignore_click: $item => {
  6823. return $item.hasClass("correct");
  6824. },
  6825. fill: (type, answer, $option) => {}
  6826. });
  6827. WorkerJSPlus({
  6828. name: "湖南继续教育",
  6829. match: () => {
  6830. const pathMatch = location.pathname.includes("/User/Student/myhomework.aspx") || location.pathname.includes("/examing.aspx");
  6831. const matchHostArr = [ "www.jwstudy.cn", "hdjt.wuxuekeji.com", "csjs.ynlhxy.com" ];
  6832. return pathMatch && (matchHostArr.includes(location.host) || location.host.includes("ls365.net") || location.host.includes("ls365.com"));
  6833. },
  6834. root: ".exam_question",
  6835. elements: {
  6836. question: ".exam_question_title div",
  6837. options: ".question_select .select_detail",
  6838. $options: ".question_select li",
  6839. type: ".exam_question_title div strong"
  6840. },
  6841. ignore_click: $item => {
  6842. return $item.hasClass("cur");
  6843. }
  6844. });
  6845. WorkerJSPlus({
  6846. name: "德阳继续教育",
  6847. match: location.href.includes("/dypx/OnlineExam/Exam.aspx"),
  6848. root: "#divProblemArea",
  6849. elements: {
  6850. question: "#ulProblems li:first",
  6851. options: "#ulProblems .answer",
  6852. $options: "#ulProblems .answer input"
  6853. },
  6854. ignore_click: $item => {
  6855. return $item.prop("checked");
  6856. },
  6857. wrap: obj => {
  6858. if ($("#ulProblems .answer input").length < 3 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") {
  6859. obj.type = 3;
  6860. obj.options = [ "正确", "错误" ];
  6861. } else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") {
  6862. obj.type = 0;
  6863. } else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "checkbox") {
  6864. obj.type = 1;
  6865. }
  6866. },
  6867. finished: () => {
  6868. if ($(".dlg").length) return false;
  6869. $("#divBtns input:eq(1)").click();
  6870. return true;
  6871. }
  6872. });
  6873. WorkerJSPlus({
  6874. name: "淄博继续教育",
  6875. match: location.pathname.includes("/practice/start"),
  6876. root: ".header-left .trueorfalse .sub",
  6877. elements: {
  6878. question: ".mb10",
  6879. options: ".options li",
  6880. $options: ".options li"
  6881. },
  6882. ignore_click: $item => {
  6883. return $item.hasClass("active");
  6884. },
  6885. wrap: obj => {
  6886. obj.type = getQuestionType(obj.$item.parent().prev().text());
  6887. obj.options = obj.options.map(i => {
  6888. return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim());
  6889. });
  6890. }
  6891. });
  6892. WorkerJSPlus({
  6893. name: "河北继续教育",
  6894. match: location.pathname.includes("paperid"),
  6895. root: ".examItem",
  6896. elements: {
  6897. question: ".examItemRight .question",
  6898. options: ".examItemRight ul li span",
  6899. $options: ".examItemRight ul li"
  6900. },
  6901. ignore_click: $item => {
  6902. return $item.hasClass("cur");
  6903. },
  6904. wrap: obj => {
  6905. obj.type = getQuestionType(obj.$item.parent().find(".questTitle b").text());
  6906. }
  6907. });
  6908. WorkerJSPlus({
  6909. name: "保定继续教育",
  6910. match: () => {
  6911. const pathnameArr = [ "/cuggw/rs/olex_exam", "/hebic/rs/olex_exam", "/sjzkjxy/rs/olex_exam", "/hbfsh/rs/olex_exam", "/jxycu/rs/olex_exam", "/jlufe/rs/olex_exam", "/hbun/rs/olex_exam" ];
  6912. return pathnameArr.includes(location.pathname);
  6913. },
  6914. intv: () => {
  6915. return $(".paper_body").length;
  6916. },
  6917. root: ".item_li",
  6918. elements: {
  6919. question: ".item_title",
  6920. options: "ul li label",
  6921. $options: "ul li input"
  6922. },
  6923. ignore_click($item) {
  6924. return $item.prop("checked");
  6925. },
  6926. wrap: obj => {
  6927. if (obj.$options.length === 2) {
  6928. obj.type = 3;
  6929. } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") {
  6930. obj.type = 0;
  6931. } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") !== "radio") {
  6932. obj.type = 1;
  6933. } else {
  6934. obj.type = 4;
  6935. }
  6936. }
  6937. });
  6938. WorkerJSPlus({
  6939. name: "唐山继续教育",
  6940. match: location.pathname.includes("/exam/student/exam/"),
  6941. intv: () => {
  6942. return $(".ui-question-group").length;
  6943. },
  6944. root: ".ui-question-group .ui-question",
  6945. elements: {
  6946. question: ".ui-question-title .ui-question-content-wrapper",
  6947. options: ".ui-question-options .ui-question-content-wrapper",
  6948. $options: ".ui-question-options .ui-question-options-order"
  6949. },
  6950. wrap: obj => {
  6951. obj.type = getQuestionType(obj.$item.parent().find("h2").text());
  6952. }
  6953. });
  6954. WorkerJSPlus({
  6955. name: "zzcjxy.hnzkw.org.cn",
  6956. match: location.host.includes("hnzkw.org.cn"),
  6957. intv: () => {
  6958. return $(".answer").length;
  6959. },
  6960. hook: () => {
  6961. JSONParseHook(o => {
  6962. if (o.data && o.data.bookdatas) {
  6963. GLOBAL.json = parsehnzkwText(o.data.bookdatas);
  6964. }
  6965. });
  6966. },
  6967. root: ".examList",
  6968. elements: {
  6969. question: ".text",
  6970. options: ".el-radio-group label,.el-checkbox-group label",
  6971. $options: ".el-radio-group input,.el-checkbox-group input",
  6972. type: ".status"
  6973. },
  6974. wrap: obj => {
  6975. Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]);
  6976. },
  6977. fill: (type, answer, $option) => {}
  6978. });
  6979. WorkerJSPlus({
  6980. name: "问卷星考试",
  6981. match: location.pathname.includes("/exam/ExamRd/Answer"),
  6982. root: ".g-mn",
  6983. elements: {
  6984. question: ".m-question .tigan",
  6985. options: ".question-block .xuanxiang",
  6986. $options: ".question-block .xuanxiang",
  6987. type: ".tixing"
  6988. },
  6989. ignore_click: ($item, type) => {
  6990. if (type === 1) {
  6991. return $item.parent().find(".icheckbox_square-green").hasClass("checked");
  6992. } else {
  6993. const isIgnore = $item.parent().find(".iradio_square-green").hasClass("checked");
  6994. return isIgnore;
  6995. }
  6996. },
  6997. wrap: obj => {
  6998. if ($(".layui-layer-content").length) {
  6999. iframeMsg("tip", {
  7000. type: "stop",
  7001. tip: "答题暂停,请自行通过验证"
  7002. });
  7003. GLOBAL.stop = true;
  7004. return true;
  7005. }
  7006. },
  7007. fillFinish: data => {
  7008. if (data.style === "warning-row" || $(".g-mn").parent().find(".iradio_square-green").hasClass("checked") || data.type === 1) {
  7009. $('.u-btn-next:contains("下一题")').click();
  7010. }
  7011. },
  7012. finished: () => {
  7013. return parseInt($(".num-dangqian:last").attr("qindex")) !== $(".num-item").length;
  7014. }
  7015. });
  7016. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址