// ==UserScript== // @name 小说下载器 // @version 4.1.3.1635575722777 // @author bgme // @description 一个可扩展的通用型小说下载器。 // @supportURL https://github.com/yingziwu/novel-downloader // @match *://www.ciweimao.com/chapter-list/* // @match *://book.sfacg.com/Novel/*/MainIndex/ // @match *://book.qidian.com/info/* // @match *://www.jjwxc.net/onebook.php?novelid=* // @match *://www.gongzicp.com/novel-*.html // @match *://gongzicp.com/novel-*.html // @match *://book.zongheng.com/showchapter/*.html // @match *://huayu.zongheng.com/showchapter/*.html // @match *://www.linovel.net/book/*.html // @match *://www.17k.com/list/*.html // @match *://www.shuhai.com/book/*.htm // @match *://mm.shuhai.com/book/*.htm // @match *://www.tadu.com/book/* // @match *://www.qimao.com/shuku/*/ // @match *://sosad.fun/threads/*/profile* // @match *://wenzhan.org/threads/*/profile* // @match *://sosadfun.com/threads/*/profile* // @match *://xn--pxtr7m5ny.com/threads/*/profile* // @match *://xn--pxtr7m.com/threads/*/profile* // @match *://xn--pxtr7m5ny.net/threads/*/profile* // @match *://xn--pxtr7m.net/threads/*/profile* // @match *://sosadfun.link/threads/*/profile* // @match *://www.sosad.fun/threads/*/profile* // @match *://www.wenzhan.org/threads/*/profile* // @match *://www.sosadfun.com/threads/*/profile* // @match *://www.xn--pxtr7m5ny.com/threads/*/profile* // @match *://www.xn--pxtr7m.com/threads/*/profile* // @match *://www.xn--pxtr7m5ny.net/threads/*/profile* // @match *://www.xn--pxtr7m.net/threads/*/profile* // @match *://www.sosadfun.link/threads/*/profile* // @match *://www.uukanshu.com/b/*/ // @match *://www.yruan.com/article/*.html // @match *://www.biquwoo.com/bqw*/ // @match *://www.biquwo.org/bqw*/ // @match *://www.shuquge.com/txt/*/index.html // @match *://www.sizhicn.com/txt/*/index.html // @match *://www.dingdiann.net/ddk*/ // @match *://www.xkzw.org/xkzw*/ // @match *://www.lewenn.com/lw*/ // @match *://www.klxs.la/info-*/ // @match *://www.266ks.com/*_*/ // @match *://www.266ks.com/*_*/index*.html // @match *://www.hetushu.com/book/*/index.html // @match *://hetushu.com/book/*/index.html // @match *://www.shouda8.com/*/ // @match *://www.shouda88.com/*/ // @match *://www.gebiqu.com/biquge_*/ // @match *://www.meegoq.com/book*.html // @match *://www.viviyzw.com/book*.html // @match *://www.xiaoshuodaquan.com/*/ // @match *://www.1pwx.com/*/ // @match *://1pwx.com/*/ // @match *://www.81book.com/book/*/ // @match *://www.81zw.com/book/*/ // @match *://m.yuzhaige.cc/*/*/ // @match *://m.yushuge123.com/*/*/ // @match *://www.xinwanben.com/*/ // @match *://www.idejian.com/book/*/ // @match *://www.wenku8.net/novel/*/*/index.htm // @match *://www.dmzj.com/info/*.html // @match *://www.westnovel.com/*/*/ // @match *://www.mht.tw/*/ // @match *://www.mht99.com/*/ // @match *://www.dierbanzhu1.com/*_*/ // @match *://www.banzhuer.org/*_*/ // @match *://www.xbiquge.so/book/*/ // @match *://www.hongyeshuzhai.com/shuzhai/*/ // @match *://www.linovelib.com/novel/*/catalog // @match *://www.luoqiuzw.com/book/*/ // @match *://www.yibige.la/*/ // @match *://www.fushuwang.org/*/*/*/*.html // @match *://www.fushuwang.org/*/*/*/*.html?* // @match *://www.soxscc.net/*/ // @match *://www.soxscc.org/*/ // @match *://www.soxs.cc/*/ // @match *://www.soshuw.com/*/ // @match *://www.soshuwu.org/*/ // @match *://www.soxscc.cc/*/ // @match *://www.soshuwu.com/*/ // @match *://www.kubiji.net/*/ // @match *://www.shubaowa.org/*_*/ // @match *://www.fuguoduxs.com/*_*/ // @match *://www.xyqxs.cc/html/*/*/index.html // @match *://www.630shu.net/shu/*.html // @match *://www.qingoo.cn/details?bookId=* // @match *://www.trxs.cc/tongren/*.html // @match *://www.trxs123.com/tongren/*.html // @match *://www.jpxs123.com/*/*.html // @match *://trxs.cc/tongren/*.html // @match *://trxs123.com/tongren/*.html // @match *://jpxs123.com/*/*.html // @match *://www.tongrenquan.org/tongren/*.html // @match *://www.tongrenquan.me/tongren/*.html // @match *://tongrenquan.me/tongren/*.html // @match *://www.imiaobige.com/read/*/ // @match *://www.256wxc.com/read/*/index.html // @match *://www.256wxc.com/read/*/ // @match *://www.256wenku.com/read/*/index.html // @match *://www.256wenku.com/read/*/ // @match *://www.biquge66.com/biquge*/ // @match *://*.lofter.com/ // @match *://*.lofter.com/?page=* // @match *://www.lwxs9.org/*/*/ // @match *://www.shubl.com/book/book_detail/* // @match *://www.ujxs.net/read/*/ // @match *://m.haitangtxt.net/*/*/ // @match *://ebook.longmabook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.longmabookcn.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://ebook.lmbooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.lmebooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.haitbook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.htwhbook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.myhtebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.lovehtbooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.myhtebooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.myhtlmebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://jp.myhtebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://jp.myhtlmebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://ebook.urhtbooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.urhtbooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.newhtbook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.lvhtebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://jp.lvhtebook.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://www.htlvbooks.com/?act=showinfo&bookwritercode=*&bookid=* // @match *://dijiubook.net/*_*/ // @match *://www.biquwx.la/*_*/ // @match *://www.25zw.com/*/ // @name:en novel-downloader // @description:en An scalable universal novel downloader. // @namespace https://blog.bgme.me // @icon https://cdn.jsdelivr.net/gh/yingziwu/novel-downloader/assets/icon.png // @license AGPL-3.0 // @run-at document-idle // @noframes true // @compatible Firefox 77+ // @compatible Chrome 85+ // @compatible Edge 85+ // @compatible Opera 71+ // @compatible Safari 13.1+ // @incompatible Internet Explorer // @exclude *://www.jjwxc.net/onebook.php?novelid=*&chapterid=* // @exclude *://www.meegoq.com/book/*.html // @exclude *://www.viviyzw.com/book/*.html // @exclude *://www.yruan.com/article/*/*.html // @exclude *://m.yuzhaige.cc/tag/*/ // @exclude *://m.yuzhaige.cc/sort/*/ // @exclude *://m.yuzhaige.cc/top/*/ // @exclude *://m.yuzhaige.cc/full/*/ // @exclude *://m.yuzhaige.cc/book/*/ // @exclude *://m.yushuge123.com/tag/*/ // @exclude *://m.yushuge123.com/sort/*/ // @exclude *://m.yushuge123.com/top/*/ // @exclude *://m.yushuge123.com/full/*/ // @exclude *://m.yushuge123.com/book/*/ // @exclude *://www.linovel.net/book/*/*.html // @exclude *://www.qimao.com/shuku/*-*/ // @exclude *://www.trxs.cc/tongren/*/*.html // @exclude *://www.trxs123.com/tongren/*/*.html // @exclude *://www.tongrenquan.org/tongren/*/*.html // @exclude *://tongrenquan.org/tongren/*/*.html // @exclude *://www.jpxs123.com/*/*/*.html // @exclude *://m.haitangtxt.net/tag/*/ // @exclude *://m.haitangtxt.net/sort/*/ // @exclude *://m.haitangtxt.net/top/*/ // @exclude *://m.haitangtxt.net/full/*/ // @exclude *://m.haitangtxt.net/book/*/ // @exclude *://www.tadu.com/book/*/*/* // @exclude *://www.tadu.com/book/*/0* // @exclude *://www.tadu.com/book/*/1* // @exclude *://www.tadu.com/book/*/2* // @exclude *://www.tadu.com/book/*/3* // @exclude *://www.tadu.com/book/*/4* // @exclude *://www.tadu.com/book/*/5* // @exclude *://www.tadu.com/book/*/6* // @exclude *://www.tadu.com/book/*/7* // @exclude *://www.tadu.com/book/*/8* // @exclude *://www.tadu.com/book/*/9* // @exclude *://www.25zw.com/lastupdate/ // @exclude *://www.25zw.com/postdate/ // @exclude *://www.25zw.com/monthvisit/ // @exclude *://www.25zw.com/goodnum/ // @exclude *://www.25zw.com/goodnew/ // @grant unsafeWindow // @grant GM_info // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM.info // @grant GM.xmlHttpRequest // @grant GM.setValue // @grant GM.getValue // @grant GM.deleteValue // @connect self // @connect shouda8.com // @connect shouda88.com // @connect qidian.com // @connect yuewen.com // @connect kuangxiangit.com // @connect sinaimg.cn // @connect jjwxc.net // @connect image.gebiqu.com // @connect qpic.cn // @connect zongheng.com // @connect 17k.com // @connect img.uukanshu.com // @connect aliyuncs.com // @connect cdn.bcebos.com // @connect rs.sfacg.com // @connect shuhai.com // @connect ch-intel.com // @connect huluxia.com // @connect linovel.net // @connect ax1x.com // @connect tadu.com // @connect zhangyue01.com // @connect cdn.wtzw.com // @connect wenku8.com // @connect dmzj.com // @connect hongyeshuzhal.com // @connect hongyeshuzhai.com // @connect linovelib.com // @connect soxscc.net // @connect soxscc.org // @connect soxs.cc // @connect soshuw.com // @connect soxscc.cc // @connect soshuwu.com // @connect kubiji.net // @connect idejian.com // @connect img.imiaobige.com // @connect postimg.cc // @connect lofter.com // @connect lf127.net // @connect 126.net // @connect shubl.com // @connect loli.net // @connect alicdn.com // @connect toutiaoimg.com // @connect imgdb.cn // @connect meego.cn // @connect poco.cn // @connect dijiuzww.com // @connect 25zw.com // @connect * // @require https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.js#sha256-8L3yX9qPmvWSDIIHB3WGTH4RZusxVA0DDmuAo4LjnOE= // @require https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js#sha256-xoh0y6ov0WULfXcLMoaA6nZfszdgI8w2CEJ/3k8NBIE= // @downloadURL none // ==/UserScript== /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/loglevel/lib/loglevel.js": /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* * loglevel - https://github.com/pimterry/loglevel * * Copyright (c) 2013 Tim Perry * Licensed under the MIT license. */ (function (root, definition) { "use strict"; if (true) { !(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else {} }(this, function () { "use strict"; // Slightly dubious tricks to cut down minimized file size var noop = function() {}; var undefinedType = "undefined"; var isIE = (typeof window !== undefinedType) && (typeof window.navigator !== undefinedType) && ( /Trident\/|MSIE /.test(window.navigator.userAgent) ); var logMethods = [ "trace", "debug", "info", "warn", "error" ]; // Cross-browser bind equivalent that works at least back to IE6 function bindMethod(obj, methodName) { var method = obj[methodName]; if (typeof method.bind === 'function') { return method.bind(obj); } else { try { return Function.prototype.bind.call(method, obj); } catch (e) { // Missing bind shim or IE8 + Modernizr, fallback to wrapping return function() { return Function.prototype.apply.apply(method, [obj, arguments]); }; } } } // Trace() doesn't print the message in IE, so for that case we need to wrap it function traceForIE() { if (console.log) { if (console.log.apply) { console.log.apply(console, arguments); } else { // In old IE, native console methods themselves don't have apply(). Function.prototype.apply.apply(console.log, [console, arguments]); } } if (console.trace) console.trace(); } // Build the best logging method possible for this env // Wherever possible we want to bind, not wrap, to preserve stack traces function realMethod(methodName) { if (methodName === 'debug') { methodName = 'log'; } if (typeof console === undefinedType) { return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives } else if (methodName === 'trace' && isIE) { return traceForIE; } else if (console[methodName] !== undefined) { return bindMethod(console, methodName); } else if (console.log !== undefined) { return bindMethod(console, 'log'); } else { return noop; } } // These private functions always need `this` to be set properly function replaceLoggingMethods(level, loggerName) { /*jshint validthis:true */ for (var i = 0; i < logMethods.length; i++) { var methodName = logMethods[i]; this[methodName] = (i < level) ? noop : this.methodFactory(methodName, level, loggerName); } // Define log.log as an alias for log.debug this.log = this.debug; } // In old IE versions, the console isn't present until you first open it. // We build realMethod() replacements here that regenerate logging methods function enableLoggingWhenConsoleArrives(methodName, level, loggerName) { return function () { if (typeof console !== undefinedType) { replaceLoggingMethods.call(this, level, loggerName); this[methodName].apply(this, arguments); } }; } // By default, we use closely bound real methods wherever possible, and // otherwise we wait for a console to appear, and then try again. function defaultMethodFactory(methodName, level, loggerName) { /*jshint validthis:true */ return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments); } function Logger(name, defaultLevel, factory) { var self = this; var currentLevel; var storageKey = "loglevel"; if (typeof name === "string") { storageKey += ":" + name; } else if (typeof name === "symbol") { storageKey = undefined; } function persistLevelIfPossible(levelNum) { var levelName = (logMethods[levelNum] || 'silent').toUpperCase(); if (typeof window === undefinedType || !storageKey) return; // Use localStorage if available try { window.localStorage[storageKey] = levelName; return; } catch (ignore) {} // Use session cookie as fallback try { window.document.cookie = encodeURIComponent(storageKey) + "=" + levelName + ";"; } catch (ignore) {} } function getPersistedLevel() { var storedLevel; if (typeof window === undefinedType || !storageKey) return; try { storedLevel = window.localStorage[storageKey]; } catch (ignore) {} // Fallback to cookies if local storage gives us nothing if (typeof storedLevel === undefinedType) { try { var cookie = window.document.cookie; var location = cookie.indexOf( encodeURIComponent(storageKey) + "="); if (location !== -1) { storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1]; } } catch (ignore) {} } // If the stored level is not valid, treat it as if nothing was stored. if (self.levels[storedLevel] === undefined) { storedLevel = undefined; } return storedLevel; } /* * * Public logger API - see https://github.com/pimterry/loglevel for details * */ self.name = name; self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3, "ERROR": 4, "SILENT": 5}; self.methodFactory = factory || defaultMethodFactory; self.getLevel = function () { return currentLevel; }; self.setLevel = function (level, persist) { if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) { level = self.levels[level.toUpperCase()]; } if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) { currentLevel = level; if (persist !== false) { // defaults to true persistLevelIfPossible(level); } replaceLoggingMethods.call(self, level, name); if (typeof console === undefinedType && level < self.levels.SILENT) { return "No console available for logging"; } } else { throw "log.setLevel() called with invalid level: " + level; } }; self.setDefaultLevel = function (level) { if (!getPersistedLevel()) { self.setLevel(level, false); } }; self.enableAll = function(persist) { self.setLevel(self.levels.TRACE, persist); }; self.disableAll = function(persist) { self.setLevel(self.levels.SILENT, persist); }; // Initialize with the right level var initialLevel = getPersistedLevel(); if (initialLevel == null) { initialLevel = defaultLevel == null ? "WARN" : defaultLevel; } self.setLevel(initialLevel, false); } /* * * Top-level API * */ var defaultLogger = new Logger(); var _loggersByName = {}; defaultLogger.getLogger = function getLogger(name) { if ((typeof name !== "symbol" && typeof name !== "string") || name === "") { throw new TypeError("You must supply a name when creating a logger."); } var logger = _loggersByName[name]; if (!logger) { logger = _loggersByName[name] = new Logger( name, defaultLogger.getLevel(), defaultLogger.methodFactory); } return logger; }; // Grab the current global log variable in case of overwrite var _log = (typeof window !== undefinedType) ? window.log : undefined; defaultLogger.noConflict = function() { if (typeof window !== undefinedType && window.log === defaultLogger) { window.log = _log; } return defaultLogger; }; defaultLogger.getLoggers = function getLoggers() { return _loggersByName; }; // ES6 default export, for compatibility defaultLogger['default'] = defaultLogger; return defaultLogger; })); /***/ }), /***/ "./src/detect.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.environments = void 0; const GM_1 = __webpack_require__("./src/lib/GM.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); function check(name) { const target = window[name]; const targetLength = target.toString().length; const targetPrototype = target["prototype"]; const nativeFunctionRe = /function \w+\(\) {\n?(\s+)?\[native code\]\n?(\s+)?}/; try { if (targetPrototype === undefined || Boolean(target.toString().match(nativeFunctionRe))) { return [true, targetLength].join(", "); } } catch { return [true, targetLength].join(", "); } return [false, targetLength].join(", "); } exports.environments = { 当前时间: new Date().toISOString(), 当前页URL: document.location.href, 当前页Referrer: document.referrer, 浏览器UA: navigator.userAgent, 浏览器语言: navigator.languages, 设备运行平台: navigator.platform, 设备内存: navigator.deviceMemory ?? "", CPU核心数: navigator.hardwareConcurrency, eval: check("eval"), fetch: check("fetch"), XMLHttpRequest: check("XMLHttpRequest"), window: Object.keys(window).length, localStorage: (0, misc_1.storageAvailable)("localStorage"), sessionStorage: (0, misc_1.storageAvailable)("sessionStorage"), Cookie: navigator.cookieEnabled, doNotTrack: navigator.doNotTrack ?? 0, scriptHandler: GM_1._GM_info.scriptHandler, version: GM_1._GM_info.version, script: JSON.stringify(GM_1._GM_info.script), enaleDebug: setting_1.enaleDebug, }; /***/ }), /***/ "./src/global.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.init = void 0; const misc_1 = __webpack_require__("./src/lib/misc.ts"); class Progress { constructor() { this._totalChapterNumber = 0; this._finishedChapterNumber = 0; this._zipPercent = 0; this.progressStyleText = `#nd-progress { position: fixed; bottom: 8%; right: 3%; z-index: 2147483647; border-style: none; text-align: center; vertical-align: baseline; background-color: rgba(210, 210, 210, 0.2); padding: 6px; border-radius: 12px; display: none; } #chapter-progress{ --color:green; --position:0%; width:200px; height:10px; border-radius:30px; background-color:#ccc; background-image:radial-gradient(closest-side circle at var(--position),var(--color),var(--color) 100%,transparent),linear-gradient(var(--color),var(--color)); background-image:-webkit-radial-gradient(var(--position),circle closest-side,var(--color),var(--color) 100%,transparent),-webkit-linear-gradient(var(--color),var(--color)); background-size:100% ,var(--position); background-repeat: no-repeat; display: none; } #zip-progress{ --color:yellow; --position:0%; width:200px; height:10px; border-radius:30px; background-color:#ccc; background-image:radial-gradient(closest-side circle at var(--position),var(--color),var(--color) 100%,transparent),linear-gradient(var(--color),var(--color)); background-image:-webkit-radial-gradient(var(--position),circle closest-side,var(--color),var(--color) 100%,transparent),-webkit-linear-gradient(var(--color),var(--color)); background-size:100% ,var(--position); background-repeat: no-repeat; margin-top: 5px; display: none; }`; if (!document.getElementById("nd-progress")) { let progress = document.createElement("div"); progress.id = "nd-progress"; progress.innerHTML = `
`; let progressStyle = document.createElement("style"); progressStyle.innerHTML = this.progressStyleText; document.head.appendChild(progressStyle); document.body.appendChild(progress); } } set totalChapterNumber(newTotalChapterNumber) { this._totalChapterNumber = newTotalChapterNumber; const elem = document.getElementById("nd-progress"); if (elem) { if (newTotalChapterNumber === 0) { elem.style.cssText = ""; } else { elem.style.cssText = "display: block;"; } } } get totalChapterNumber() { return this._totalChapterNumber; } set finishedChapterNumber(newFinishedChapterNumber) { this._finishedChapterNumber = newFinishedChapterNumber; if (this._totalChapterNumber != 0) { const percent = (this._finishedChapterNumber / this._totalChapterNumber) * 100; const elem = document.getElementById("chapter-progress"); if (elem) { if (newFinishedChapterNumber === 0) { elem.style.cssText = ""; elem.title = ""; } else { elem.style.cssText = `--position:${percent}%; display: block;`; elem.title = `${this._finishedChapterNumber}/${this._totalChapterNumber}`; } } } } get finishedChapterNumber() { return this._finishedChapterNumber; } set zipPercent(newZipPercent) { this._zipPercent = newZipPercent; const elem = document.getElementById("zip-progress"); if (elem) { if (newZipPercent === 0) { elem.style.cssText = ""; } else { elem.style.cssText = `--position:${this._zipPercent}%; display: block;`; } } } get zipPercent() { return this._zipPercent; } reset() { const elem = document.getElementById("nd-progress"); if (elem) { elem.style.cssText = ""; } this.totalChapterNumber = 0; this.finishedChapterNumber = 0; this.zipPercent = 0; } } function init() { window.progress = new Progress(); window.downloading = false; window.customStorage = new misc_1.localStorageExpired(); window.stopFlag = false; } exports.init = init; /***/ }), /***/ "./src/lib/GM.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports._GM_deleteValue = exports._GM_getValue = exports._GM_setValue = exports._GM_xmlhttpRequest = exports._GM_info = void 0; const log_1 = __webpack_require__("./src/log.ts"); if (typeof GM_info === "undefined") { if (typeof GM === "undefined") { throw new Error("未发现 GM_info"); } else { if (typeof GM.info === "undefined") { throw new Error("未发现 GM_info"); } else { exports._GM_info = GM.info; } } } else { exports._GM_info = GM_info; } if (typeof GM_xmlhttpRequest === "undefined") { if (typeof GM === "undefined") { throw new Error("未发现 GM_xmlhttpRequest"); } else { if (typeof GM.xmlHttpRequest === "undefined") { throw new Error("未发现 GM_xmlhttpRequest"); } else { exports._GM_xmlhttpRequest = GM.xmlHttpRequest; } } } else { exports._GM_xmlhttpRequest = GM_xmlhttpRequest; } if (typeof GM_setValue === "undefined") { if (typeof GM === "undefined") { log_1.log.warn("未发现 GM_setValue"); } else { if (typeof GM.setValue === "undefined") { log_1.log.warn("未发现 GM_setValue"); } else { exports._GM_setValue = GM.setValue; } } } else { exports._GM_setValue = GM_setValue; } if (typeof GM_getValue === "undefined") { if (typeof GM === "undefined") { log_1.log.warn("未发现 GM_getValue"); } else { if (typeof GM.getValue === "undefined") { log_1.log.warn("未发现 GM_getValue"); } else { exports._GM_getValue = GM.getValue; } } } else { exports._GM_getValue = GM_getValue; } if (typeof GM_deleteValue === "undefined") { if (typeof GM === "undefined") { log_1.log.warn("未发现 GM_deleteValue"); } else { if (typeof GM.deleteValue === "undefined") { log_1.log.warn("未发现 GM_deleteValue"); } else { exports._GM_deleteValue = GM.deleteValue; } } } else { exports._GM_deleteValue = GM_deleteValue; } /***/ }), /***/ "./src/lib/attachments.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getImageAttachment = exports.clearAttachmentClassCache = exports.putAttachmentClassCache = exports.getAttachmentClassCache = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); let attachmentClassCache = []; function getAttachmentClassCache(url) { const found = attachmentClassCache.find((attachmentClass) => attachmentClass.url === url); return found; } exports.getAttachmentClassCache = getAttachmentClassCache; function putAttachmentClassCache(attachmentClass) { attachmentClassCache.push(attachmentClass); return true; } exports.putAttachmentClassCache = putAttachmentClassCache; function clearAttachmentClassCache() { attachmentClassCache = []; } exports.clearAttachmentClassCache = clearAttachmentClassCache; async function getImageAttachment(url, imgMode = "TM", prefix = "", noMD5 = false) { const tmpImageName = Math.random().toString().replace("0.", ""); let imgClass; const imgClassCache = getAttachmentClassCache(url); if (imgClassCache) { imgClass = imgClassCache; } else { imgClass = new main_1.attachmentClass(url, tmpImageName, imgMode); const blob = await imgClass.init(); if (blob) { const hash = await (0, misc_1.calculateMd5)(blob); const contentType = blob.type.split("/")[1]; const contentTypeBlackList = ["octet-stream"]; let ext = contentType; if (contentTypeBlackList.includes(contentType)) { const _ext = new URL(url).pathname .split(".") .slice(-1)[0] .match(/(^[\d|\w]+)/); if (_ext) { ext = _ext[0]; } else { ext = new URL(url).pathname.split(".").slice(-1)[0]; } } let imageName; if (noMD5) { let _imageName = new URL(url).pathname.split("/").slice(-1)[0]; if (attachmentClassCache.find((attachmentClass) => attachmentClass.name === _imageName && attachmentClass.url !== url)) { _imageName = new URL(url).pathname.split("/").slice(-2).join("_"); } imageName = [prefix, _imageName].join(""); } else { imageName = [prefix, hash, ".", ext].join(""); } imgClass.name = imageName; putAttachmentClassCache(imgClass); } else { throw new main_1.ExpectError("[getImageAttachment] Init Image failed!"); } } return imgClass; } exports.getImageAttachment = getImageAttachment; /***/ }), /***/ "./src/lib/cleanDOM.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.htmlTrim = exports.cleanDOM = void 0; const main_1 = __webpack_require__("./src/main.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const blockElements = [ "article", "aside", "footer", "form", "header", "main", "nav", "section", "figure", "div", "b", "strong", "i", "em", "dfn", "var", "cite", "span", "font", "u", "del", "sup", "sub", "strike", "small", "samp", "s", ]; const ignoreElements = [ "script", "meta", "link", "style", "#comment", "button", "input", "select", ]; function* findBase(dom, blockElements, ignoreElements) { const childNodes = Array.from(dom.childNodes); for (const node of childNodes) { const nodeName = node.nodeName.toLowerCase(); if (blockElements.includes(nodeName)) { yield* findBase(node, blockElements, ignoreElements); } else if (nodeName === "#text") { if (node.parentElement?.childNodes.length === 1 && blockElements.slice(9).includes(nodeName)) { yield node.parentElement; } else if (node.textContent?.trim()) { yield node; } } else if (!ignoreElements.includes(nodeName)) { yield node; } } } function getNextSibling(elem) { elem = elem.nextSibling; if (elem && elem.nodeName.toLowerCase() === "#text" && elem.textContent?.trim() === "") { return elem.nextSibling; } return elem; } function getPreviousSibling(elem) { elem = elem.previousSibling; if (elem && elem.nodeName.toLowerCase() === "#text" && elem.textContent?.trim() === "") { return elem.previousSibling; } return elem; } function getParentElement(elem) { const _elem = elem.parentElement; if (!_elem) { return null; } let nodename = _elem.nodeName.toLowerCase(); if (["div", "p"].includes(nodename)) { return _elem; } else { return getParentElement(_elem); } } async function formatImage(elem, builder) { function temp0() { const pI = document.createElement("p"); pI.appendChild(imgElem); builder.dom.appendChild(pI); builder.text = builder.text + imgText + "\n\n"; } if (!elem.src) { return; } let tfi = await _formatImage(elem, builder); if (!tfi) { return; } let [imgElem, imgText, imgClass] = tfi; if (elem.parentElement?.childElementCount === 1) { temp0(); return; } else { function temp1() { if (lastElement?.nodeName.toLowerCase() === "p") { lastElement.appendChild(imgElem); builder.text = builder.text + ` ${imgText} `; return; } else { const tpElem = document.createElement("p"); tpElem.appendChild(imgElem); builder.dom.appendChild(tpElem); builder.text = builder.text + ` ${imgText} `; return; } } const lastElement = builder.dom.lastElementChild; const nextSibling = getNextSibling(elem); const previousSibling = getPreviousSibling(elem); if (elem.parentElement?.nodeName.toLowerCase() === "p" && lastElement?.nodeName.toLowerCase() === "p") { if (previousSibling?.nodeName.toLowerCase() === "#text" || nextSibling?.nodeName.toLowerCase() === "#text") { temp1(); return; } if (previousSibling?.nodeName.toLowerCase() === "img" && lastElement.lastElementChild?.nodeName.toLowerCase() === "img" && lastElement.lastElementChild.alt === previousSibling.src) { temp1(); return; } } else { temp0(); return; } } } async function _formatImage(elem, builder) { if (!elem.src) { return; } const imgMode = builder.imgMode; const imageUrl = elem.src; try { let noMD5 = false; if (builder.option?.keepImageName) { noMD5 = true; } const imgClass = await (0, attachments_1.getImageAttachment)(imageUrl, imgMode, "", noMD5); const imageName = imgClass.name; const filterdImages = builder.images.find((imgClass) => imgClass.url === elem.src); if (!filterdImages) { builder.images.push(imgClass); } const imgElem = document.createElement("img"); imgElem.setAttribute("data-src-address", imageName); imgElem.alt = imageUrl; const imgText = `![${imageUrl}](${imageName})`; return [imgElem, imgText, imgClass]; } catch (error) { if (error instanceof main_1.ExpectError) { const imgElem = document.createElement("img"); imgElem.setAttribute("data-src-address", imageUrl); imgElem.alt = imageUrl; const imgText = `![${imageUrl}](${imageUrl})`; return [imgElem, imgText, null]; } else { throw error; } } } async function formatMisc(elem, builder) { if (elem.childElementCount === 0) { const lastElement = builder.dom.lastElementChild; const textContent = elem.innerText.trim(); if (lastElement?.nodeName.toLowerCase() === "p") { const textElem = document.createTextNode(textContent); lastElement.appendChild(textElem); builder.text = builder.text + textContent; } else { const pElem = document.createElement("p"); pElem.innerText = textContent; builder.dom.appendChild(pElem); builder.text = builder.text + "\n\n" + textContent; } } else { await walk(elem, builder); return; } } async function formatParagraph(elem, builder) { if (elem.childElementCount === 0) { const pElem = document.createElement("p"); pElem.innerText = elem.innerText.trim(); const pText = elem.innerText.trim() + "\n\n"; builder.dom.appendChild(pElem); builder.text = builder.text + pText; return; } else { await walk(elem, builder); return; } } function formatText(elems, builder) { function temp0() { const tPElem = document.createElement("p"); tPElem.innerText = textContent; builder.dom.appendChild(tPElem); } function temp1() { const lastElement = builder.dom.lastElementChild; if (lastElement?.nodeName.toLowerCase() === "p") { const textElem = document.createTextNode(textContent); lastElement.appendChild(textElem); const tPText = textContent + "\n".repeat(brCount); builder.text = builder.text + tPText; } else { temp0(); const tPText = textContent + "\n".repeat(brCount); builder.text = builder.text + tPText; } } const brCount = elems.filter((elem) => elem.nodeName.toLowerCase() === "br").length; const elem = elems[0]; const textContent = elem.textContent ? elem.textContent.trim() : ""; if (!textContent) { return; } const lastElement = builder.dom.lastElementChild; const previousSibling = getPreviousSibling(elem); if (elem.parentElement?.nodeName.toLowerCase() === "p" && lastElement?.nodeName.toLowerCase() === "p" && previousSibling?.nodeName.toLowerCase() === "img" && lastElement.lastElementChild?.nodeName.toLowerCase() === "img" && lastElement.lastElementChild.alt === previousSibling.src) { temp1(); return; } if (brCount === 0) { const nextSibling = getNextSibling(elem); const previousSibling = getPreviousSibling(elem); if (nextSibling === null) { if (previousSibling?.nodeName.toLowerCase() === "br") { temp0(); const tPText = textContent + "\n\n"; builder.text = builder.text + tPText; return; } else if (previousSibling === null && (() => { const parentElement = getParentElement(elem); if (parentElement?.childNodes.length === 1) { return true; } return false; })()) { temp0(); if (builder.text.endsWith("\n")) { builder.text = builder.text + textContent + "\n\n"; } else { builder.text = builder.text + "\n\n" + textContent + "\n\n"; } return; } else { temp1(); return; } } else { if (previousSibling === null) { temp0(); const tPText = textContent; if (builder.text.endsWith("\n")) { builder.text = builder.text + tPText; } else { builder.text = builder.text + "\n\n" + tPText; } return; } else { temp1(); return; } } } else if (brCount === 1) { const lastElement = builder.dom.lastElementChild; if (lastElement?.nodeName.toLowerCase() === "p") { const br = document.createElement("br"); const textElem = document.createTextNode(textContent); lastElement.appendChild(br); lastElement.appendChild(textElem); const tPText = textContent + "\n"; builder.text = builder.text + tPText; return; } else { temp0(); const tPText = textContent + "\n"; builder.text = builder.text + tPText; return; } } else if (brCount === 2 || brCount === 3) { temp0(); const tPText = textContent + "\n".repeat(brCount); builder.text = builder.text + tPText; return; } else if (brCount > 3) { temp0(); for (let i = Math.round((brCount - 2) / 3); i > 0; i--) { const tPBr = document.createElement("p"); const br = document.createElement("br"); tPBr.appendChild(br); builder.dom.appendChild(tPBr); } const tPText = textContent + "\n".repeat(brCount); builder.text = builder.text + tPText; return; } } function formatHr(elem, builder) { const hrElem = document.createElement("hr"); const hrText = "-".repeat(20); builder.dom.appendChild(hrElem); builder.text = builder.text + "\n\n" + hrText + "\n\n"; return; } async function formatA(elem, builder) { if (elem.childElementCount === 0) { if (elem.href) { const aElem = document.createElement("a"); aElem.href = elem.href; aElem.innerText = elem.innerText; aElem.rel = "noopener noreferrer"; const aText = `[${elem.innerText}](${elem.href})`; builder.dom.appendChild(aElem); builder.text = builder + "\n\n" + aText; return; } else { return; } } else { return await formatMisc(elem, builder); } } function formatVideo(elem, builder) { builder.dom.appendChild(elem.cloneNode(true)); builder.text = builder.text + "\n\n" + elem.outerHTML; } async function walk(dom, builder) { const childNodes = [...findBase(dom, blockElements, ignoreElements)].filter((b) => b); for (let i = 0; i < childNodes.length; i++) { const node = childNodes[i]; if (node === undefined) { continue; } const nodeName = node.nodeName.toLowerCase(); switch (nodeName) { case "u": case "del": case "sup": case "sub": case "strike": case "small": case "samp": case "s": case "b": case "strong": case "i": case "em": case "dfn": case "var": case "cite": case "span": case "font": { await formatMisc(node, builder); break; } case "div": case "p": { await formatParagraph(node, builder); break; } case "#text": { let elems = [node]; let j = i + 1; let jnodeName = nodeName; do { if (j >= childNodes.length) { break; } let jnode = childNodes[j]; jnodeName = jnode.nodeName.toLowerCase(); if (jnodeName === "br") { elems.push(jnode); delete childNodes[j]; j++; } } while (jnodeName === "br"); formatText(elems, builder); break; } case "img": { await formatImage(node, builder); break; } case "hr": { formatHr(node, builder); break; } case "a": { await formatA(node, builder); break; } case "video": { formatVideo(node, builder); break; } } } return builder; } async function cleanDOM(DOM, imgMode, option = null) { const builder = { dom: document.createElement("div"), text: "", images: [], imgMode: imgMode, option: option, }; await walk(DOM, builder); return { dom: builder.dom, text: builder.text.trim(), images: builder.images, }; } exports.cleanDOM = cleanDOM; function htmlTrim(dom) { const childNodesR = Array.from(dom.childNodes).reverse(); for (const node of childNodesR) { const ntype = node.nodeName.toLowerCase(); const ntypes = ["#text", "br"]; if (!ntypes.includes(ntype)) { return; } if (ntype === "#text") { if (node.textContent?.trim() === "") { node.remove(); } else { return; } } if (ntype === "br") { node.remove(); } } } exports.htmlTrim = htmlTrim; /***/ }), /***/ "./src/lib/http.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ggetHtmlDOM = exports.ggetText = exports.getHtmlDOM = exports.getText = exports.gfetch = void 0; const GM_1 = __webpack_require__("./src/lib/GM.ts"); function gfetch(url, { method = "GET", headers, data, cookie, binary, nocache, revalidate, timeout, context, responseType, overrideMimeType, anonymous, username, password, } = {}) { return new Promise((resolve, reject) => { if (GM_1._GM_xmlhttpRequest) { (0, GM_1._GM_xmlhttpRequest)({ url: url, method: method, headers: headers, data: data, cookie: cookie, binary: binary, nocache: nocache, revalidate: revalidate, timeout: timeout, context: context, responseType: responseType, overrideMimeType: overrideMimeType, anonymous: anonymous, username: username, password: password, onload: (obj) => { resolve(obj); }, onerror: (err) => { reject(err); }, }); } else { throw new Error("未发现 _GM_xmlhttpRequest API"); } }); } exports.gfetch = gfetch; async function getText(url, charset, init = undefined) { const _url = new URL(url); if (document.location.protocol === "https:" && _url.protocol === "http:") { _url.protocol = "https:"; url = _url.toString(); } if (charset === undefined) { return fetch(url, init).then((response) => { if (response.ok) { return response.text(); } else { throw new Error(`Bad response! ${url}`); } }); } else { return fetch(url, init) .then((response) => { if (response.ok) { return response.arrayBuffer(); } else { throw new Error(`Bad response! ${url}`); } }) .then((buffer) => { const decoder = new TextDecoder(charset); const text = decoder.decode(buffer); return text; }); } } exports.getText = getText; async function getHtmlDOM(url, charset, init = undefined) { const htmlText = await getText(url, charset, init); return new DOMParser().parseFromString(htmlText, "text/html"); } exports.getHtmlDOM = getHtmlDOM; async function ggetText(url, charset, init = undefined) { if (charset === undefined) { return gfetch(url, init).then((response) => { if (response.status >= 200 && response.status <= 299) { return response.responseText; } else { throw new Error(`Bad response! ${url}`); } }); } else { if (init) { init["responseType"] = "arraybuffer"; } else { init = { responseType: "arraybuffer" }; } return gfetch(url, init) .then((response) => { if (response.status >= 200 && response.status <= 299) { return response.response; } else { throw new Error(`Bad response! ${url}`); } }) .then((buffer) => { const decoder = new TextDecoder(charset); const text = decoder.decode(buffer); return text; }); } } exports.ggetText = ggetText; async function ggetHtmlDOM(url, charset, init = undefined) { const htmlText = await ggetText(url, charset, init); return new DOMParser().parseFromString(htmlText, "text/html"); } exports.ggetHtmlDOM = ggetHtmlDOM; /***/ }), /***/ "./src/lib/misc.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.localStorageExpired = exports.calculateMd5 = exports.storageAvailable = exports.sandboxed = exports.sleep = exports.concurrencyRun = exports.rm = void 0; function rm(selector, all = false, dom) { if (all) { let rs = dom.querySelectorAll(selector); rs.forEach((e) => e.remove()); } else { let r = dom.querySelector(selector); if (r) { r.remove(); } } } exports.rm = rm; function concurrencyRun(list, limit, asyncHandle) { async function recursion(arr) { const obj = await asyncHandle(arr.shift()); if (arr.length !== 0) { return recursion(arr); } else { return "finish!"; } } const listCopy = [...list]; let asyncList = []; while (limit--) { asyncList.push(recursion(listCopy)); } return Promise.all(asyncList); } exports.concurrencyRun = concurrencyRun; function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } exports.sleep = sleep; function sandboxed(code) { const frame = document.createElement("iframe"); document.body.appendChild(frame); if (frame.contentWindow) { const F = frame.contentWindow.Function; const args = Object.keys(frame.contentWindow).join(); document.body.removeChild(frame); return F(args, code)(); } } exports.sandboxed = sandboxed; function storageAvailable(type) { let storage; try { storage = window[type]; let x = "__storage_test__"; storage.setItem(x, x); storage.removeItem(x); return true; } catch (e) { return (e instanceof DOMException && (e.code === 22 || e.code === 1014 || e.name === "QuotaExceededError" || e.name === "NS_ERROR_DOM_QUOTA_REACHED") && storage && storage.length !== 0); } } exports.storageAvailable = storageAvailable; function calculateMd5(blob) { return new Promise((resolve, rejects) => { const reader = new FileReader(); reader.readAsArrayBuffer(blob); reader.onloadend = function () { if (reader.result) { const wordArray = CryptoJS.lib.WordArray.create(reader.result); const hash = CryptoJS.MD5(wordArray).toString(); resolve(hash); } else { rejects(Error("计算MD5值出错")); return; } }; }); } exports.calculateMd5 = calculateMd5; class localStorageExpired { constructor() { if (storageAvailable("localStorage")) { this.storage = window.localStorage; this.init(); } else { throw new Error("当前浏览器不支持 localStorage"); } } init() { const reg = new RegExp("__expires__$"); const storage = this.storage; const keys = Object.keys(storage); keys.forEach((key) => { if (!reg.test(key)) { this.get(key); } }); } set(key, value, expired) { const storage = this.storage; storage[key] = JSON.stringify(value); if (expired) { storage[`${key}__expires__`] = Date.now() + 1000 * expired; } } get(key) { const storage = this.storage; const expired = storage[`${key}__expires__`] ?? false; const now = Date.now(); if (expired && now >= expired) { this.remove(key); return; } if (expired) { try { const value = JSON.parse(storage[key]); return value; } catch (error) { return storage[key]; } } else { return storage[key]; } } remove(key) { const storage = this.storage; if (storage[key]) { delete storage[key]; if (storage[`${key}__expires__`]) { delete storage[`${key}__expires__`]; } } } } exports.localStorageExpired = localStorageExpired; /***/ }), /***/ "./src/lib/zip.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.fflateZip = void 0; const log_1 = __webpack_require__("./src/log.ts"); const fflate_1 = __webpack_require__("./node_modules/fflate/lib/index.cjs"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); class fflateZip { constructor(memlimit = false) { this.count = 0; this.zcount = 0; this.tcount = 0; this.memlimit = memlimit; this.filenameList = []; this.zipOut = []; const self = this; this.savedZip = new fflate_1.Zip((err, dat, final) => { if (err) { log_1.log.error(err); log_1.log.trace(err); throw err; } self.zipOut.push(dat); self.zcount++; if (final) { const zipBlob = new Blob(self.zipOut, { type: "application/zip" }); log_1.log.debug("[fflateZip][debug][zcount]" + self.zcount); log_1.log.debug("[fflateZip][debug][count]" + self.count); log_1.log.info("[fflateZip] ZIP生成完毕,文件大小:" + zipBlob.size); self.zipOut = []; if (typeof self.onFinal === "function") { if (typeof self.onUpdateId !== "undefined") { clearInterval(self.onUpdateId); } try { self.onFinal(zipBlob); } catch (error) { if (typeof self.onFinalError === "function") { self.onFinalError(error); } } } else { throw "[fflateZip] 完成函数出错"; } } }); } file(filename, file) { if (this.filenameList.includes(filename)) { log_1.log.error(`filename ${filename} has existed on zip.`); return; } this.count++; this.filenameList.push(filename); file .arrayBuffer() .then((buffer) => new Uint8Array(buffer)) .then((chunk) => { if (this.memlimit || file.type.includes("image/")) { const nonStreamingFile = new fflate_1.ZipPassThrough(filename); this.addToSavedZip(this.savedZip, nonStreamingFile, chunk); this.tcount++; } else { const nonStreamingFile = new fflate_1.AsyncZipDeflate(filename, { level: 6, }); this.addToSavedZip(this.savedZip, nonStreamingFile, chunk); this.tcount++; } }); } addToSavedZip(savedZip, nonStreamingFile, chunk) { savedZip.add(nonStreamingFile); nonStreamingFile.push(chunk, true); } async generateAsync(onUpdate = undefined) { while (this.tcount !== this.count) { await (0, misc_1.sleep)(500); } const self = this; this.onUpdateId = window.setInterval(() => { const percent = (self.zcount / 3 / self.count) * 100; if (typeof onUpdate === "function") { onUpdate(percent); } }, 100); this.savedZip.end(); } } exports.fflateZip = fflateZip; /***/ }), /***/ "./src/log.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.log = exports.saveLogTextToFile = exports.logText = void 0; const setting_1 = __webpack_require__("./src/setting.ts"); const loglevel_1 = __webpack_require__("./node_modules/loglevel/lib/loglevel.js"); exports.log = loglevel_1.default; if (setting_1.enaleDebug) { loglevel_1.default.setLevel("trace"); } else { loglevel_1.default.setLevel("info"); } exports.logText = ""; const originalFactory = loglevel_1.default.methodFactory; loglevel_1.default.methodFactory = function (methodName, logLevel, loggerName) { const rawMethod = originalFactory(methodName, logLevel, loggerName); return function (message) { try { if (typeof message === "object") { if (message instanceof Error) { exports.logText += message.stack; } else { exports.logText += JSON.stringify(message, undefined, 2) + "\n"; } } else { exports.logText += message + "\n"; } } catch (error) { } rawMethod(message); }; }; loglevel_1.default.setLevel(loglevel_1.default.getLevel()); function saveLogTextToFile() { saveAs(new Blob([exports.logText], { type: "text/plain; charset=UTF-8" }), `novel-downloader-${Date.now().toString()}.log`); } exports.saveLogTextToFile = saveLogTextToFile; /***/ }), /***/ "./src/main.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ExpectError = exports.attachmentClass = exports.Chapter = exports.Book = exports.Status = void 0; const setting_1 = __webpack_require__("./src/setting.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const log_1 = __webpack_require__("./src/log.ts"); var Status; (function (Status) { Status[Status["pending"] = 0] = "pending"; Status[Status["downloading"] = 1] = "downloading"; Status[Status["failed"] = 2] = "failed"; Status[Status["finished"] = 3] = "finished"; Status[Status["aborted"] = 4] = "aborted"; Status[Status["saved"] = 5] = "saved"; })(Status = exports.Status || (exports.Status = {})); class Book { constructor(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters) { this.bookUrl = bookUrl; this.bookname = bookname; this.author = author; this.introduction = introduction; this.introductionHTML = introductionHTML; this.additionalMetadate = additionalMetadate; this.chapters = chapters; log_1.log.debug("[Book]初始化完成"); } } exports.Book = Book; class Chapter { constructor(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, chapterParse, charset, options) { this.bookUrl = bookUrl; this.bookname = bookname; this.chapterUrl = chapterUrl; this.chapterNumber = chapterNumber; this.chapterName = chapterName; this.isVIP = isVIP; this.isPaid = isPaid; this.sectionName = sectionName; this.sectionNumber = sectionNumber; this.sectionChapterNumber = sectionChapterNumber; this.chapterParse = chapterParse; this.charset = charset; this.options = options; this.status = Status.pending; this.retryTime = 0; } async init() { const { chapterName, contentRaw, contentText, contentHTML, contentImages, additionalMetadate, } = await this.parse(); this.chapterName = chapterName; this.contentRaw = contentRaw; this.contentText = contentText; this.contentHTML = contentHTML; this.contentImages = contentImages; this.additionalMetadate = additionalMetadate; if (this.status === Status.failed) { log_1.log.error(`[Chapter]${this.chapterName}, URL:${this.chapterUrl}, \ VIP:${this.isVIP}, Paid:${this.isPaid}, \ isNull:${!Boolean(this.contentHTML)} 解析出错。`); } else { log_1.log.info(`[Chapter]${this.chapterName}, URL:${this.chapterUrl}, \ VIP:${this.isVIP}, Paid:${this.isPaid}, \ isNull:${!Boolean(this.contentHTML)} 解析成功。`); } return this; } async parse() { this.status = Status.downloading; return this.chapterParse(this.chapterUrl, this.chapterName, this.isVIP, this.isPaid, this.charset, this.options) .then(async (obj) => { const contentImages = obj.contentImages; if (contentImages) { let downloadingImages = contentImages.filter((imgObj) => imgObj.status === Status.downloading); while (downloadingImages.length) { await (0, misc_1.sleep)(500); downloadingImages = contentImages.filter((imgObj) => imgObj.status === Status.downloading); } } this.status = Status.finished; return obj; }) .catch(async (err) => { this.retryTime++; log_1.log.error(`[Chapter]${this.chapterName}解析出错,第${this.retryTime}次重试,章节地址:${this.chapterUrl}`); if (this.status !== Status.failed && this.retryTime < setting_1.retryLimit) { await (0, misc_1.sleep)(this.retryTime * 1500); return this.parse(); } else { this.status = Status.failed; log_1.log.error(err); log_1.log.trace(err); return { chapterName: this.chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } }); } } exports.Chapter = Chapter; class attachmentClass { constructor(imageUrl, name, mode) { this.url = imageUrl; this.name = name; this.mode = mode; this.status = Status.pending; this.retryTime = 0; this.defaultHeader = { Referer: document.location.origin, }; } async init() { if (this.mode === "naive") { this.imageBlob = await this.downloadImage(); } else { this.imageBlob = await this.tmDownloadImage(); } if (this.imageBlob) { log_1.log.info(`[attachment] ${this.url} 下载完成。`); } return this.imageBlob; } downloadImage() { const headers = Object.assign(this.defaultHeader, this.headers); const referer = headers.Referer; delete headers["Referer"]; this.status = Status.downloading; return fetch(this.url, { headers: { ...headers }, referrer: referer, }) .then((response) => { if (response.ok) { this.status = Status.finished; return response.blob(); } else { if (response.status === 404) { this.status = Status.failed; } throw new Error(`Image request response is not ok!\nImage url: ${this.url} .`); } }) .catch(async (err) => { this.retryTime++; log_1.log.error(`[attachment]下载 ${this.url} 出错,第${this.retryTime}次重试,下载模式:${this.mode}`); if (this.status !== Status.failed && this.retryTime < setting_1.retryLimit) { await (0, misc_1.sleep)(this.retryTime * 1500); return this.downloadImage(); } else { this.status = Status.failed; log_1.log.error(err); log_1.log.trace(err); return null; } }); } tmDownloadImage() { const headers = Object.assign(this.defaultHeader, this.headers); this.status = Status.downloading; return (0, http_1.gfetch)(this.url, { headers: { ...headers }, responseType: "blob", }) .then((response) => { if (response.status >= 200 && response.status <= 299) { this.status = Status.finished; return response.response; } else { if (response.status === 404) { this.status = Status.failed; } throw new Error(`Bad response!\nRequest url: ${this.url}`); } }) .catch(async (err) => { this.retryTime++; log_1.log.error(`[attachment]下载 ${this.url} 出错,第${this.retryTime}次重试,下载模式:${this.mode}`); if (this.status !== Status.failed && this.retryTime < setting_1.retryLimit) { await (0, misc_1.sleep)(this.retryTime * 1500); return this.tmDownloadImage(); } else { this.status = Status.failed; log_1.log.error(err); log_1.log.trace(err); return null; } }); } } exports.attachmentClass = attachmentClass; class ExpectError extends Error { } exports.ExpectError = ExpectError; /***/ }), /***/ "./src/routers.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getRule = void 0; async function getRule() { const host = document.location.host; let ruleClass; switch (host) { case "www.ciweimao.com": { const { ciweimao } = await Promise.resolve().then(() => __webpack_require__("./src/rules/ciweimao.ts")); ruleClass = ciweimao; break; } case "www.uukanshu.com": { const { uukanshu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/uukanshu.ts")); ruleClass = uukanshu; break; } case "www.yruan.com": { const { yrun } = await Promise.resolve().then(() => __webpack_require__("./src/rules/yruan.ts")); ruleClass = yrun; break; } case "www.shuquge.com": case "www.sizhicn.com": { const { shuquge } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = shuquge(); break; } case "www.dingdiann.net": { const { dingdiann } = await Promise.resolve().then(() => __webpack_require__("./src/rules/dingdiann.ts")); ruleClass = dingdiann; break; } case "www.biquge66.com": case "www.lewenn.com": case "www.klxs.la": case "www.xkzw.org": { const { xkzw } = await Promise.resolve().then(() => __webpack_require__("./src/rules/xkzw.ts")); ruleClass = xkzw; break; } case "www.266ks.com": { const { c226ks } = await Promise.resolve().then(() => __webpack_require__("./src/rules/226ks.ts")); ruleClass = c226ks; break; } case "book.sfacg.com": { const { sfacg } = await Promise.resolve().then(() => __webpack_require__("./src/rules/sfacg.ts")); ruleClass = sfacg; break; } case "www.hetushu.com": case "hetushu.com": { const { hetushu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/hetushu.ts")); ruleClass = hetushu; break; } case "www.shouda8.com": case "www.shouda88.com": { const { shouda8 } = await Promise.resolve().then(() => __webpack_require__("./src/rules/shouda8.ts")); ruleClass = shouda8; break; } case "www.gebiqu.com": { const { gebiqu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = gebiqu(); break; } case "www.meegoq.com": case "www.viviyzw.com": { const { meegoq } = await Promise.resolve().then(() => __webpack_require__("./src/rules/meegoq.ts")); ruleClass = meegoq; break; } case "www.xiaoshuodaquan.com": case "www.1pwx.com": case "1pwx.com": { const { xiaoshuodaquan } = await Promise.resolve().then(() => __webpack_require__("./src/rules/xiaoshuodaquan.ts")); ruleClass = xiaoshuodaquan; break; } case "book.qidian.com": { const { qidian } = await Promise.resolve().then(() => __webpack_require__("./src/rules/qidian.ts")); ruleClass = qidian; break; } case "www.jjwxc.net": { const { jjwxc } = await Promise.resolve().then(() => __webpack_require__("./src/rules/jjwxc.ts")); ruleClass = jjwxc; break; } case "www.biquwoo.com": case "www.biquwo.org": case "www.hongyeshuzhai.com": { const { common } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = common(); break; } case "www.81book.com": case "www.81zw.com": { const { c81book } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = c81book(); break; } case "book.zongheng.com": case "huayu.zongheng.com": { const { zongheng } = await Promise.resolve().then(() => __webpack_require__("./src/rules/zongheng.ts")); ruleClass = zongheng; break; } case "www.17k.com": { const { c17k } = await Promise.resolve().then(() => __webpack_require__("./src/rules/17k.ts")); ruleClass = c17k; break; } case "www.shuhai.com": case "mm.shuhai.com": { const { shuhai } = await Promise.resolve().then(() => __webpack_require__("./src/rules/shuhai.ts")); ruleClass = shuhai; break; } case "www.gongzicp.com": case "gongzicp.com": { const { gongzicp } = await Promise.resolve().then(() => __webpack_require__("./src/rules/gongzicp.ts")); ruleClass = gongzicp; break; } case "m.yuzhaige.cc": case "m.yushuge123.com": { const { yuzhaige } = await Promise.resolve().then(() => __webpack_require__("./src/rules/yuzhaige.ts")); ruleClass = yuzhaige; break; } case "www.linovel.net": { const { linovel } = await Promise.resolve().then(() => __webpack_require__("./src/rules/linovel.ts")); ruleClass = linovel; break; } case "www.xinwanben.com": { const { xinwanben } = await Promise.resolve().then(() => __webpack_require__("./src/rules/xinwanben.ts")); ruleClass = xinwanben; break; } case "www.tadu.com": { const { tadu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/tadu.ts")); ruleClass = tadu; break; } case "www.idejian.com": { const { idejian } = await Promise.resolve().then(() => __webpack_require__("./src/rules/idejian.ts")); ruleClass = idejian; break; } case "www.qimao.com": { const { qimao } = await Promise.resolve().then(() => __webpack_require__("./src/rules/qimao.ts")); ruleClass = qimao; break; } case "www.wenku8.net": { const { wenku8 } = await Promise.resolve().then(() => __webpack_require__("./src/rules/wenku8.ts")); ruleClass = wenku8; break; } case "www.dmzj.com": { const { dmzj } = await Promise.resolve().then(() => __webpack_require__("./src/rules/dmzj.ts")); ruleClass = dmzj; break; } case "sosad.fun": case "www.sosad.fun": case "wenzhan.org": case "www.wenzhan.org": case "sosadfun.com": case "www.sosadfun.com": case "xn--pxtr7m5ny.com": case "www.xn--pxtr7m5ny.com": case "xn--pxtr7m.com": case "www.xn--pxtr7m.com": case "xn--pxtr7m5ny.net": case "www.xn--pxtr7m5ny.net": case "xn--pxtr7m.net": case "www.xn--pxtr7m.net": case "sosadfun.link": case "www.sosadfun.link": { const { sosadfun } = await Promise.resolve().then(() => __webpack_require__("./src/rules/sosadfun.ts")); ruleClass = sosadfun; break; } case "www.westnovel.com": { const { westnovel } = await Promise.resolve().then(() => __webpack_require__("./src/rules/westnovel.ts")); ruleClass = westnovel; break; } case "www.mht.tw": case "www.mht99.com": { const { mht } = await Promise.resolve().then(() => __webpack_require__("./src/rules/mht.ts")); ruleClass = mht; break; } case "www.dierbanzhu1.com": case "www.banzhuer.org": { const { dierbanzhu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/dierbanzhu.ts")); ruleClass = dierbanzhu; break; } case "www.xbiquge.so": { const { xbiquge } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = xbiquge; break; } case "www.linovelib.com": { const { linovelib } = await Promise.resolve().then(() => __webpack_require__("./src/rules/linovelib.ts")); ruleClass = linovelib; break; } case "www.luoqiuzw.com": { const { luoqiuzw } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = luoqiuzw(); break; } case "www.yibige.la": { const { yibige } = await Promise.resolve().then(() => __webpack_require__("./src/rules/yibige.ts")); ruleClass = yibige; break; } case "www.fushuwang.org": { const { fushuwang } = await Promise.resolve().then(() => __webpack_require__("./src/rules/fushuwang.ts")); ruleClass = fushuwang; break; } case "www.soxscc.net": case "www.soxscc.org": case "www.soxs.cc": case "www.soshuw.com": case "www.soshuwu.org": case "www.soxscc.cc": case "www.soshuwu.com": case "www.kubiji.net": { const { soxscc } = await Promise.resolve().then(() => __webpack_require__("./src/rules/soxscc.ts")); ruleClass = soxscc; break; } case "www.fuguoduxs.com": case "www.shubaowa.org": { const { shubaowa } = await Promise.resolve().then(() => __webpack_require__("./src/rules/shubaowa.ts")); ruleClass = shubaowa; break; } case "www.xyqxs.cc": { const { xyqxs } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = xyqxs(); break; } case "www.630shu.net": { const { c630shu } = await Promise.resolve().then(() => __webpack_require__("./src/rules/simple/630shu.ts")); ruleClass = c630shu; break; } case "www.qingoo.cn": { const { qingoo } = await Promise.resolve().then(() => __webpack_require__("./src/rules/qingoo.ts")); ruleClass = qingoo; break; } case "www.trxs.cc": case "www.trxs123.com": case "www.jpxs123.com": case "trxs.cc": case "trxs123.com": case "jpxs123.com": { const { trxs } = await Promise.resolve().then(() => __webpack_require__("./src/rules/simple/trxs.ts")); ruleClass = trxs(); break; } case "www.tongrenquan.org": case "www.tongrenquan.me": case "tongrenquan.me": case "tongrenquan.org": { const { tongrenquan } = await Promise.resolve().then(() => __webpack_require__("./src/rules/simple/trxs.ts")); ruleClass = tongrenquan(); break; } case "www.imiaobige.com": { const { imiaobige } = await Promise.resolve().then(() => __webpack_require__("./src/rules/imiaobige.ts")); ruleClass = imiaobige; break; } case "www.256wxc.com": case "www.256wenku.com": { const { c256wxc } = await Promise.resolve().then(() => __webpack_require__("./src/rules/simple/256wxc.ts")); ruleClass = c256wxc; break; } case regExpMatch(/lofter\.com$/): { const { lofter } = await Promise.resolve().then(() => __webpack_require__("./src/rules/lofter.ts")); ruleClass = lofter; break; } case "www.lwxs9.org": { const { lwxs9 } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = lwxs9(); break; } case "www.shubl.com": { const { shubl } = await Promise.resolve().then(() => __webpack_require__("./src/rules/shubl.ts")); ruleClass = shubl; break; } case "www.ujxs.net": { const { ujxs } = await Promise.resolve().then(() => __webpack_require__("./src/rules/ujxs.ts")); ruleClass = ujxs; break; } case "m.haitangtxt.net": { const { haitangtxt } = await Promise.resolve().then(() => __webpack_require__("./src/rules/haitangtxt.ts")); ruleClass = haitangtxt; break; } case "ebook.longmabook.com": case "www.longmabookcn.com": case "ebook.lmbooks.com": case "www.lmebooks.com": case "www.haitbook.com": case "www.htwhbook.com": case "www.myhtebook.com": case "www.lovehtbooks.com": case "www.myhtebooks.com": case "www.myhtlmebook.com": case "jp.myhtebook.com": case "jp.myhtlmebook.com": case "ebook.urhtbooks.com": case "www.urhtbooks.com": case "www.newhtbook.com": case "www.lvhtebook.com": case "jp.lvhtebook.com": case "www.htlvbooks.com": { const { longmabook } = await Promise.resolve().then(() => __webpack_require__("./src/rules/longmabook.ts")); ruleClass = longmabook; break; } case "dijiubook.net": { const { dijiubook } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = dijiubook(); break; } case "www.biquwx.la": { const { biquwx } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = biquwx(); break; } case "www.25zw.com": { const { c25zw } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = c25zw; break; } default: { throw new Error("Not Found Rule!"); } } const rule = new ruleClass(); return rule; function regExpMatch(regexp) { if (regexp.test(host)) { return host; } } } exports.getRule = getRule; /***/ }), /***/ "./src/rules.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.BaseRuleClass = void 0; const save_1 = __webpack_require__("./src/save.ts"); const main_1 = __webpack_require__("./src/main.ts"); const log_1 = __webpack_require__("./src/log.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const stat_1 = __webpack_require__("./src/stat.ts"); const workStatusKeyName = "novel-downloader-EaraVl9TtSM2405L"; class BaseRuleClass { constructor() { this.imageMode = "TM"; this.charset = document.charset; this.concurrencyLimit = 10; } async run() { log_1.log.info(`[run]下载开始`); const self = this; try { if (!self.preHook()) return; self.book = await self.bookParse(); const saveBookObj = self.getSave(self.book); await self.initChapters(self.book, saveBookObj); log_1.log.debug("[run]开始保存文件"); saveBookObj.saveTxt(); await saveBookObj.saveZip(false); self.postHook(); self.postCallback(); (0, stat_1.successPlus)(); (0, stat_1.printStat)(); return self.book; } catch (error) { self.catchError(error); } } preTest() { const self = this; const storage = window.customStorage; let workStatus = storage.get(workStatusKeyName); if (workStatus) { const nowNumber = Object.keys(workStatus).length; if (self.maxRunLimit && nowNumber >= self.maxRunLimit) { return false; } } else { workStatus = {}; workStatus[document.location.href] = true; storage.set(workStatusKeyName, workStatus, 20); } return true; } preWarning() { return true; } preHook() { const self = this; if (!self.preTest()) { const alertText = `当前网站目前最多允许${self.maxRunLimit}个下载任务同时进行。\n请待其它下载任务完成后,再行尝试。`; alert(alertText); log_1.log.info(`[run]${alertText}`); return false; } if (!self.preWarning()) { return false; } self.audio = new Audio("data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcxLjEwMAAAAAAAAAAAAAAA/+M4wAAAAAAAAAAAAEluZm8AAAAPAAAAEAAABVgANTU1NTU1Q0NDQ0NDUFBQUFBQXl5eXl5ea2tra2tra3l5eXl5eYaGhoaGhpSUlJSUlKGhoaGhoaGvr6+vr6+8vLy8vLzKysrKysrX19fX19fX5eXl5eXl8vLy8vLy////////AAAAAExhdmM1Ny44OQAAAAAAAAAAAAAAACQCgAAAAAAAAAVY82AhbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+MYxAALACwAAP/AADwQKVE9YWDGPkQWpT66yk4+zIiYPoTUaT3tnU487uNhOvEmQDaCm1Yz1c6DPjbs6zdZVBk0pdGpMzxF/+MYxA8L0DU0AP+0ANkwmYaAMkOKDDjmYoMtwNMyDxMzDHE/MEsLow9AtDnBlQgDhTx+Eye0GgMHoCyDC8gUswJcMVMABBGj/+MYxBoK4DVpQP8iAtVmDk7LPgi8wvDzI4/MWAwK1T7rxOQwtsItMMQBazAowc4wZMC5MF4AeQAGDpruNuMEzyfjLBJhACU+/+MYxCkJ4DVcAP8MAO9J9THVg6oxRMGNMIqCCTAEwzwwBkINOPAs/iwjgBnMepYyId0PhWo+80PXMVsBFzD/AiwwfcKGMEJB/+MYxDwKKDVkAP8eAF8wMwIxMlpU/OaDPLpNKkEw4dRoBh6qP2FC8jCJQFcweQIPMHOBtTBoAVcwOoCNMYDI0u0Dd8ANTIsy/+MYxE4KUDVsAP8eAFBVpgVVPjdGeTEWQr0wdcDtMCeBgDBkgRgwFYB7Pv/zqx0yQQMCCgKNgonHKj6RRVkxM0GwML0AhDAN/+MYxF8KCDVwAP8MAIHZMDDA3DArAQo3K+TF5WOBDQw0lgcKQUJxhT5sxRcwQQI+EIPWMA7AVBoTABgTgzfBN+ajn3c0lZMe/+MYxHEJyDV0AP7MAA4eEwsqP/PDmzC/gNcwXUGaMBVBIwMEsmB6gaxhVuGkpoqMZMQjooTBwM0+S8FTMC0BcjBTgPwwOQDm/+MYxIQKKDV4AP8WADAzAKQwI4CGPhWOEwCFAiBAYQnQMT+uwXUeGzjBWQVkwTcENMBzA2zAGgFEJfSPkPSZzPXgqFy2h0xB/+MYxJYJCDV8AP7WAE0+7kK7MQrATDAvQRIwOADKMBuA9TAYQNM3AiOSPjGxowgHMKFGcBNMQU1FMy45OS41VVU/31eYM4sK/+MYxKwJaDV8AP7SAI4y1Yq0MmOIADGwBZwwlgIJMztCM0qU5TQPG/MSkn8yEROzCdAxECVMQU1FMy45OS41VTe7Ohk+Pqcx/+MYxMEJMDWAAP6MADVLDFUx+4J6Mq7NsjN2zXo8V5fjVJCXNOhwM0vTCDAxFpMYYQU+RlVMQU1FMy45OS41VVVVVVVVVVVV/+MYxNcJADWAAP7EAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxOsJwDWEAP7SAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxPMLoDV8AP+eAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxPQL0DVcAP+0AFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); self.audio.loop = true; self.audio.play(); const confirmExit = (e) => { e.preventDefault(); const confirmationText = "您正尝试离开本页面,当前页面有下载任务正在运行,是否确认离开?"; return (e.returnValue = confirmationText); }; window.onbeforeunload = confirmExit; window.downloading = true; return true; } postCallback() { if (setting_1.enableCustomFinishCallback && typeof unsafeWindow.customFinishCallback === "function") { const customFinishCallback = unsafeWindow .customFinishCallback; log_1.log.info(`发现自定义结束回调函数,内容如下:\n${customFinishCallback.toString()}`); customFinishCallback(); } } postHook() { const self = this; const storage = window.customStorage; const workStatus = storage.get(workStatusKeyName); if (workStatus) { delete workStatus[document.location.href]; } (0, attachments_1.clearAttachmentClassCache)(); self.audio?.pause(); self.audio?.remove(); window.onbeforeunload = null; window.downloading = false; const progress = window.progress; if (progress) { progress.reset(); } return true; } catchError(error) { const self = this; log_1.log.error(error); log_1.log.trace(error); self.postHook(); if (!(error instanceof main_1.ExpectError)) { document.getElementById("novel-downloader")?.remove(); log_1.log.error("运行过程出错,请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/yingziwu/novel-downloader"); (0, stat_1.failedPlus)(); alert("运行过程出错,请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/yingziwu/novel-downloader"); (0, log_1.saveLogTextToFile)(); } } getSave(book) { log_1.log.debug("[run]保存数据"); if (setting_1.enableCustomSaveOptions && typeof unsafeWindow.saveOptions === "object" && (0, save_1.saveOptionsValidate)(unsafeWindow.saveOptions)) { const saveOptions = unsafeWindow.saveOptions; log_1.log.info("[run]发现自定义保存参数,内容如下\n", saveOptions); return (0, save_1.getSaveBookObj)(book, saveOptions); } else { return (0, save_1.getSaveBookObj)(book, {}); } } getChapters(book) { function isEnable() { if (setting_1.enableCustomChapterFilter && typeof unsafeWindow.chapterFilter === "function") { let text = "[initChapters]发现自定义筛选函数,自定义筛选函数内容如下:\n"; text += unsafeWindow.chapterFilter.toString(); log_1.log.info(text); return true; } else { return false; } } function _filter(chapter) { let b = true; try { const u = unsafeWindow.chapterFilter(chapter); if (typeof u === "boolean") { b = u; } } catch (error) { log_1.log.error("运行自定义筛选函数时出错。", error); log_1.log.trace(error); } return b; } let chapters = book.chapters.filter((chapter) => chapter.status === main_1.Status.pending); const enabled = isEnable(); if (enabled) { log_1.log.debug("[initChapters]筛选需下载章节"); chapters = chapters.filter((chapter) => _filter(chapter)); } return chapters; } async initChapters(book, saveBookObj) { const self = this; log_1.log.info(`[initChapters]开始初始化章节`); Object.entries(self).forEach((kv) => log_1.log.info(`[initChapters] ${kv[0]}: ${kv[1]}`)); const chapters = self.getChapters(book); if (chapters.length === 0) { log_1.log.error(`[initChapters]初始化章节出错,未找到需初始化章节`); return []; } const progress = window.progress; if (progress) { progress.totalChapterNumber = chapters.length; } if (self.concurrencyLimit === 1) { for (let chapter of chapters) { if (window.stopFlag) { log_1.log.info("[chapter]收到停止信号,停止继续下载。"); break; } try { let obj = await chapter.init(); obj = await self.postChapterParseHook(obj); afterGetChpater(obj); } catch (error) { log_1.log.error(error); log_1.log.trace(error); } } } else { await (0, misc_1.concurrencyRun)(chapters, self.concurrencyLimit, async (curChapter) => { if (curChapter === undefined) { return Promise.resolve(); } if (window.stopFlag) { log_1.log.info("[chapter]收到停止信号,停止继续下载。"); return Promise.resolve(); } try { let obj = await curChapter.init(); obj = await self.postChapterParseHook(obj); afterGetChpater(obj); return obj; } catch (error) { log_1.log.error(error); log_1.log.trace(error); } }); } log_1.log.info(`[initChapters]章节初始化完毕`); return chapters; function afterGetChpater(chapter) { const storage = window.customStorage; let workStatus = storage.get(workStatusKeyName); if (workStatus) { workStatus[document.location.href] = true; } else { workStatus = {}; workStatus[document.location.href] = true; } storage.set(workStatusKeyName, workStatus, 20); if (chapter.contentHTML !== undefined) { saveBookObj.addChapter(chapter); const progress = window.progress; if (progress) { progress.finishedChapterNumber++; } } return chapter; } } async postChapterParseHook(obj) { return obj; } } exports.BaseRuleClass = BaseRuleClass; /***/ }), /***/ "./src/rules/17k.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.c17k = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class c17k extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; this.concurrencyLimit = 5; } async bookParse() { const bookUrl = document.location.href.replace("/list/", "/book/"); const bookname = (document.querySelector("h1.Title")).innerText.trim(); const author = (document.querySelector("div.Author > a")).innerText.trim(); const doc = await (0, http_1.getHtmlDOM)(bookUrl, undefined); const introDom = doc.querySelector("#bookInfo p.intro > a"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = doc.querySelector("#bookCover img.book") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const sections = document.querySelectorAll("dl.Volume"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = (s.querySelector("dt > span.tit")).innerText.trim(); let sectionChapterNumber = 0; const cs = s.querySelectorAll("dd > a"); for (let j = 0; j < cs.length; j++) { const a = cs[j]; const span = a.firstElementChild; chapterNumber++; sectionChapterNumber++; const chapterName = span.innerText.trim(); const chapterUrl = a.href; const isVIP = () => { if (span?.className.includes("vip")) { return true; } else { return false; } }; const isPaid = () => { return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const chapterName = (doc.querySelector("#readArea > div.readAreaBox.content > h1")).innerText.trim(); const content = (doc.querySelector("#readArea > div.readAreaBox.content > div.p")); if (content) { (0, misc_1.rm)("p.copy", false, content); (0, misc_1.rm)("#banner_content", false, content); (0, misc_1.rm)("div.qrcode", false, content); (0, misc_1.rm)("div.chapter_text_ad", false, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.c17k = c17k; /***/ }), /***/ "./src/rules/226ks.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.c226ks = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class c226ks extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href.replace(/index_\d+\.html/, "index_1.html"); const bookname = (document.querySelector(".info > .top > h1")).innerText.trim(); const author = (document.querySelector(".info > .top > .fix > p:nth-child(1)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(); const introDom = document.querySelector(".desc"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = document.querySelector(".imgbox > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const indexUrls = Array.from(document.querySelectorAll('[name="pageselect"] > option')).map((opt) => document.location.origin + opt.getAttribute("value")); let lis = []; for (const indexUrl of indexUrls) { log_1.log.debug(`[chapter]请求${indexUrl}`); const dom = await (0, http_1.getHtmlDOM)(indexUrl, "UTF-8"); const ul = dom.querySelector("div.row.row-section > div > div:nth-child(4) > ul"); if (ul?.childElementCount) { lis = lis.concat(Array.from(ul.children)); } } const chapterList = lis.filter((obj) => obj !== undefined); let chapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; chapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = dom.querySelector("h1.title").innerText.trim(); const content = dom.querySelector("#content"); const ad = '
章节错误,点此举报(免注册),举报后维护人员会在两分钟内校正章节内容,请耐心等待,并刷新页面。
'; content.innerHTML = content.innerHTML.replace(ad, ""); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.c226ks = c226ks; /***/ }), /***/ "./src/rules/biquge.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.xbiquge = exports.xyqxs = exports.shuquge = exports.dijiubook = exports.c25zw = exports.biquwx = exports.lwxs9 = exports.luoqiuzw = exports.gebiqu = exports.c81book = exports.common = exports.bookParseTemp = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); async function bookParseTemp({ bookUrl, bookname, author, introDom, introDomPatch, coverUrl, chapterListSelector, charset, chapterParse, }) { const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, introDomPatch); const additionalMetadate = {}; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, "TM", "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const dl = document.querySelector(chapterListSelector); if (dl?.childElementCount) { const dlc = Array.from(dl.children); if (dlc[0].nodeName === "DT" && (dlc[0].innerText.includes("最新章节") || dlc[0].innerText.includes("最新的八个章节"))) { for (let i = 0; i < dl?.childElementCount; i++) { if (i !== 0 && dlc[i].nodeName === "DT") { delete dlc[0]; break; } delete dlc[i]; } } const chapterList = dlc.filter((obj) => obj !== undefined); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; if (node.nodeName === "DT") { sectionNumber++; sectionChapterNumber = 0; if (node.innerText.includes("《")) { sectionName = node.innerText.replace(`《${bookname}》`, "").trim(); } else { sectionName = node.innerText.replace(`${bookname}`, "").trim(); } } else if (node.nodeName === "DD") { if (node.childElementCount === 0) { continue; } chapterNumber++; sectionChapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, chapterParse, charset, { bookname: bookname }); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } exports.bookParseTemp = bookParseTemp; async function chapterParseTemp({ dom, chapterUrl, chapterName, contenSelector, contentPatch, charset, }) { let content = dom.querySelector(contenSelector); if (content) { content = contentPatch(content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } function mkBiqugeClass(introDomPatch, contentPatch, concurrencyLimit = undefined) { return class extends rules_1.BaseRuleClass { constructor() { super(); if (typeof concurrencyLimit === "number") { this.concurrencyLimit = concurrencyLimit; } this.imageMode = "TM"; this.charset = document.charset; this.overrideConstructor(this); } async bookParse() { const self = this; return bookParseTemp({ bookUrl: document.location.href, bookname: (document.querySelector("#info h1:nth-of-type(1)")).innerText .trim() .replace(/最新章节$/, ""), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: introDomPatch, coverUrl: document.querySelector("#fmimg > img") .src, chapterListSelector: "#list>dl", charset: document.charset, chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); return chapterParseTemp({ dom, chapterUrl, chapterName: (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(), contenSelector: "#content", contentPatch: contentPatch, charset, }); } overrideConstructor(self) { } }; } const common = () => mkBiqugeClass((introDom) => introDom, (content) => content); exports.common = common; const c81book = () => mkBiqugeClass((introDom) => introDom, (content) => content); exports.c81book = c81book; const gebiqu = () => mkBiqugeClass((introDom) => { introDom.innerHTML = introDom.innerHTML.replace(/如果您喜欢.+,别忘记分享给朋友/g, ""); (0, misc_1.rm)('a[href^="http://down.gebiqu.com"]', false, introDom); return introDom; }, (content) => { content.innerHTML = content.innerHTML.replace(/"www.gebiqu.com"/g, ""); return content; }); exports.gebiqu = gebiqu; const luoqiuzw = () => mkBiqugeClass((introDom) => introDom, (content) => { const ad = content.firstElementChild; if (ad.innerText.includes("天才一秒记住本站地址:")) { ad.remove(); } const ads = ["记住网址m.luoqiuxzw.com"]; ads.forEach((adt) => (content.innerHTML = content.innerHTML.replace(adt, ""))); return content; }); exports.luoqiuzw = luoqiuzw; const lwxs9 = () => mkBiqugeClass((introDom) => introDom, (content) => { (0, misc_1.rm)("div[align]", false, content); return content; }); exports.lwxs9 = lwxs9; const biquwx = () => mkBiqugeClass((introDom) => { introDom.innerHTML = introDom.innerHTML.replace(/本站提示:各位书友要是觉得《.+》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!/, ""); return introDom; }, (content) => content, 1); exports.biquwx = biquwx; class c25zw extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = document.charset; } async bookParse() { const self = this; return bookParseTemp({ bookUrl: document.location.href, bookname: (document.querySelector("#info h1:nth-of-type(1)")).innerText .trim() .replace(/最新章节$/, ""), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => { introDom.querySelector("font")?.parentElement?.remove(); introDom.innerHTML = introDom.innerHTML.replace("简介:", ""); return introDom; }, coverUrl: document.querySelector("#fmimg > img").src, chapterListSelector: "#list>dl", charset: document.charset, chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); return chapterParseTemp({ dom, chapterUrl, chapterName: (dom.querySelector(".zhangjieming > h1")).innerText.trim(), contenSelector: "#content", contentPatch: (content) => { (0, misc_1.rm)(".bottem", false, content); return content; }, charset, }); } } exports.c25zw = c25zw; const dijiubook = () => { const c = mkBiqugeClass((introDom) => { introDom.innerHTML = introDom.innerHTML.replace("本书网址:", ""); (0, misc_1.rm)('a[href^="https://dijiubook.net/"]', false, introDom); (0, misc_1.rm)("dl > dt:nth-of-type(2)", false, document.querySelector("#list")); document .querySelectorAll('#list a[href^="https://m.dijiubook.net"]') .forEach((elem) => elem.parentElement?.remove()); document .querySelectorAll('#list a[href$=".apk"]') .forEach((elem) => elem.parentElement?.remove()); return introDom; }, (content) => { (0, misc_1.rm)("a", true, content); return content; }); c.prototype.overrideConstructor = (classThis) => { classThis.concurrencyLimit = 1; classThis.maxRunLimit = 1; classThis.postChapterParseHook = async (obj) => { await (0, misc_1.sleep)(3000 * Math.random()); return obj; }; }; return c; }; exports.dijiubook = dijiubook; function mkBiqugeClass2(introDomPatch, contentPatch, concurrencyLimit = undefined) { return class extends rules_1.BaseRuleClass { constructor() { super(); if (typeof concurrencyLimit === "number") { this.concurrencyLimit = concurrencyLimit; } this.imageMode = "TM"; this.charset = document.charset; this.overrideConstructor(this); } async bookParse() { const self = this; return bookParseTemp({ bookUrl: document.location.href, bookname: document.querySelector(".info > h2").innerText .trim() .replace(/最新章节$/, ""), author: (document.querySelector(".small > span:nth-child(1)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector(".intro"), introDomPatch: introDomPatch, coverUrl: (document.querySelector(".info > .cover > img")).src, chapterListSelector: ".listmain>dl", charset: document.charset, chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); return chapterParseTemp({ dom, chapterUrl, chapterName: (dom.querySelector(".content > h1:nth-child(1)")).innerText.trim(), contenSelector: "#content", contentPatch: contentPatch, charset, }); } overrideConstructor(self) { } }; } const shuquge = () => mkBiqugeClass2((introDom) => { introDom.innerHTML = introDom.innerHTML.replace(/推荐地址:https?:\/\/www.shuquge.com\/txt\/\d+\/index\.html/g, ""); return introDom; }, (content) => { content.innerHTML = content.innerHTML .replace("请记住本书首发域名:www.shuquge.com。书趣阁_笔趣阁手机版阅读网址:m.shuquge.com", "") .replace(/https?:\/\/www.shuquge.com\/txt\/\d+\/\d+\.html/, ""); return content; }, 1); exports.shuquge = shuquge; const xyqxs = () => mkBiqugeClass2((introDom) => { introDom.innerHTML = introDom.innerHTML.replace(/推荐地址:https:\/\/www.xyqxs.cc\/html\/\d+\/\d+\/index\.html/g, ""); return introDom; }, (content) => { (0, misc_1.rm)("div[style]", true, content); (0, misc_1.rm)("script", true, content); (0, misc_1.rm)('div[align="center"]', false, content); content.innerHTML = content.innerHTML .replace("请记住本书首发域名:www.xyqxs.cc。笔趣阁手机版阅读网址:m.xyqxs.cc", "") .replace(/\(https:\/\/www.xyqxs.cc\/html\/\d+\/\d+\/\d+\.html\)/, ""); return content; }); exports.xyqxs = xyqxs; class xbiquge extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const self = this; return bookParseTemp({ bookUrl: document.location.href, bookname: (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector("#fmimg > img")?.src, chapterListSelector: "#list>dl", charset: "GBK", chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); return chapterParseTemp({ dom, chapterUrl, chapterName: (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(), contenSelector: "#content", contentPatch: (content) => { content.innerHTML = content.innerHTML.replace(`笔趣阁 www.xbiquge.so,最快更新${options.bookname} !`, ""); return content; }, charset, }); } } exports.xbiquge = xbiquge; /***/ }), /***/ "./src/rules/ciweimao.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ciweimao = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_2 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class ciweimao extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; this.concurrencyLimit = 1; this.maxRunLimit = 1; } async bookParse() { const bookid = unsafeWindow.HB.book.book_id; const bookUrl = `https://www.ciweimao.com/book/${bookid}`; const bookname = (document.querySelector(".book-catalog .hd h3")).innerText.trim(); const author = (document.querySelector(".book-catalog .hd > p > a")).innerText.trim(); const dom = await (0, http_2.getHtmlDOM)(bookUrl, undefined); const introDom = dom.querySelector(".book-intro-cnt .book-desc"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = dom.querySelector(".cover > img").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(dom.querySelectorAll(".label-box > .label")).map((span) => span.innerText.trim()); const chapters = []; const sections = document.querySelectorAll(".book-chapter > .book-chapter-box"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = s.querySelector(".sub-tit").innerText; let sectionChapterNumber = 0; const cs = s.querySelectorAll(".book-chapter-list > li > a"); for (let j = 0; j < cs.length; j++) { const c = cs[j]; chapterNumber++; sectionChapterNumber++; const chapterName = c.innerText.trim(); const chapterUrl = c.href; let isVIP = false; let isPaid = false; if (c.childElementCount) { isVIP = true; if (c.firstElementChild?.className === "icon-unlock") { isPaid = true; } } const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); const isLogin = document.querySelector(".login-info.ly-fr")?.childElementCount === 1 ? true : false; if (isVIP && !(isLogin && isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function decrypt(item) { let message = item.content; let keys = item.keys; let len = item.keys.length; let accessKey = item.accessKey; let accessKeyList = accessKey.split(""); let charsNotLatinNum = accessKeyList.length; let output = new Array(); output.push(keys[accessKeyList[charsNotLatinNum - 1].charCodeAt(0) % len]); output.push(keys[accessKeyList[0].charCodeAt(0) % len]); for (let i = 0; i < output.length; i++) { message = atob(message); let data = output[i]; let iv = btoa(message.substr(0, 16)); let keys255 = btoa(message.substr(16)); let pass = CryptoJS.format.OpenSSL.parse(keys255); message = CryptoJS.AES.decrypt(pass, CryptoJS.enc.Base64.parse(data), { iv: CryptoJS.enc.Base64.parse(iv), format: CryptoJS.format.OpenSSL, }); if (i < output.length - 1) { message = message.toString(CryptoJS.enc.Base64); message = atob(message); } } return message.toString(CryptoJS.enc.Utf8); } async function getChapterAuthorSay() { const doc = await (0, http_2.getHtmlDOM)(chapterUrl, undefined); const _chapter_author_says = doc.querySelectorAll("#J_BookCnt .chapter.author_say"); let div_chapter_author_say; if (_chapter_author_says.length !== 0) { let hr = document.createElement("hr"); div_chapter_author_say = document.createElement("div"); div_chapter_author_say.appendChild(hr); for (let _chapter_author_say of Array.from(_chapter_author_says)) { (0, misc_1.rm)("i", true, _chapter_author_say); div_chapter_author_say.appendChild(_chapter_author_say); } } return div_chapter_author_say; } const chapter_id = chapterUrl.split("/").slice(-1)[0]; async function publicChapter() { async function chapterDecrypt(chapter_id, refererUrl) { const rootPath = "https://www.ciweimao.com/"; const access_key_url = rootPath + "chapter/ajax_get_session_code"; const chapter_content_url = rootPath + "chapter/get_book_chapter_detail_info"; log_1.log.debug(`[Chapter]请求 ${access_key_url} Referer ${refererUrl}`); const access_key_obj = await (0, http_1.gfetch)(access_key_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Referer: refererUrl, Origin: "https://www.ciweimao.com", "X-Requested-With": "XMLHttpRequest", }, data: `chapter_id=${chapter_id}`, responseType: "json", }).then((response) => response.response); const chapter_access_key = access_key_obj .chapter_access_key; log_1.log.debug(`[Chapter]请求 ${chapter_content_url} Referer ${refererUrl}`); const chapter_content_obj = await (0, http_1.gfetch)(chapter_content_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Referer: refererUrl, Origin: "https://www.ciweimao.com", "X-Requested-With": "XMLHttpRequest", }, data: `chapter_id=${chapter_id}&chapter_access_key=${chapter_access_key}`, responseType: "json", }).then((response) => response.response); if (chapter_content_obj.code !== 100000) { log_1.log.error(chapter_content_obj); throw new Error(`下载 ${refererUrl} 失败`); } return decrypt({ content: chapter_content_obj.chapter_content, keys: chapter_content_obj.encryt_keys, accessKey: chapter_access_key, }); } const div_chapter_author_say = await getChapterAuthorSay(); let content = document.createElement("div"); let decryptDate = await chapterDecrypt(chapter_id, chapterUrl); content.innerHTML = decryptDate; (0, misc_1.rm)(".chapter span", true, content); if (div_chapter_author_say) { content.appendChild(div_chapter_author_say); } let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } async function vipChapter() { const isLogin = document.querySelector(".login-info.ly-fr")?.childElementCount === 1 ? true : false; if (isLogin && isPaid) { async function vipChapterDecrypt(chapter_id, refererUrl) { const HB = unsafeWindow.HB; const parentWidth = 871; const setFontSize = "14"; const image_session_code_url = HB.config.rootPath + "chapter/ajax_get_image_session_code"; log_1.log.debug(`[Chapter]请求 ${image_session_code_url} Referer ${refererUrl}`); const image_session_code_object = await (0, http_1.gfetch)(image_session_code_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", Referer: refererUrl, Origin: "https://www.ciweimao.com", "X-Requested-With": "XMLHttpRequest", }, responseType: "json", }).then((response) => response.response); if (image_session_code_object.code !== 100000) { log_1.log.error(image_session_code_object); throw new Error(`下载 ${refererUrl} 失败`); } const imageCode = decrypt({ content: image_session_code_object .image_code, keys: image_session_code_object .encryt_keys, accessKey: image_session_code_object .access_key, }); const vipCHapterImageUrl = HB.config.rootPath + "chapter/book_chapter_image?chapter_id=" + chapter_id + "&area_width=" + parentWidth + "&font=undefined" + "&font_size=" + setFontSize + "&image_code=" + imageCode + "&bg_color_name=white" + "&text_color_name=white"; return vipCHapterImageUrl; } const div_chapter_author_say = await getChapterAuthorSay(); const vipCHapterImageUrl = await vipChapterDecrypt(chapter_id, chapterUrl); log_1.log.debug(`[Chapter]请求 ${vipCHapterImageUrl} Referer ${chapterUrl}`); const vipCHapterImageBlob = await (0, http_1.gfetch)(vipCHapterImageUrl, { method: "GET", headers: { Referer: chapterUrl, Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", }, responseType: "blob", }).then((response) => response.response); const vipCHapterName = `vipCHapter${chapter_id}.png`; const vipCHapterImage = new main_1.attachmentClass(vipCHapterImageUrl, vipCHapterName, "TM"); if (vipCHapterImageBlob) { vipCHapterImage.imageBlob = vipCHapterImageBlob; vipCHapterImage.status = main_1.Status.finished; } const contentImages = [vipCHapterImage]; let ddom, dtext, dimages; if (div_chapter_author_say) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(div_chapter_author_say, "TM"); [ddom, dtext, dimages] = [dom, text, images]; } const img = document.createElement("img"); img.src = vipCHapterName; img.alt = vipCHapterImageUrl; const contentHTML = document.createElement("div"); contentHTML.appendChild(img); if (ddom) { contentHTML.appendChild(ddom); } let contentText = `VIP章节,请打开HTML文件查看。\n![${vipCHapterImageUrl}](${vipCHapterName})`; if (dtext) { contentText = contentText + "\n\n" + dtext; } return { chapterName: chapterName, contentRaw: contentHTML, contentText: contentText, contentHTML: contentHTML, contentImages: contentImages, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.ciweimao = ciweimao; /***/ }), /***/ "./src/rules/dierbanzhu.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.dierbanzhu = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class dierbanzhu extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(); const author = (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(); const introDom = document.querySelector("#intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = document.querySelector("#fmimg > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const dl = document.querySelector("#list>dl"); if (dl?.childElementCount) { const dlc = Array.from(dl.children); const chapterList = dlc.filter((obj) => obj !== undefined); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; if (node.nodeName === "DT" && !node.innerText.includes("最新章节")) { sectionNumber++; sectionChapterNumber = 0; sectionName = node.innerText.replace(`《${bookname}》`, "").trim(); } else if (node.nodeName === "DD") { chapterNumber++; sectionChapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.dierbanzhu = dierbanzhu; /***/ }), /***/ "./src/rules/dingdiann.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.dingdiann = void 0; const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const biquge_1 = __webpack_require__("./src/rules/biquge.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class dingdiann extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const self = this; return (0, biquge_1.bookParseTemp)({ bookUrl: document.location.href, bookname: (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector("#fmimg > img").src, chapterListSelector: "#list>dl", charset: "UTF-8", chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { return (0, common_1.nextPageParse)(chapterName, chapterUrl, charset, "#content", (_content, doc) => { (0, misc_1.rm)("div[align]", false, _content); (0, misc_1.rm)("script", true, _content); const removelist = [ "一秒记住,精彩小说无弹窗免费阅读!", "</a :>", "-->>", "本章未完,点击下一页继续阅读", ]; removelist.forEach((removeStr) => (_content.innerHTML = _content.innerHTML.replaceAll(removeStr, ""))); (0, cleanDOM_1.htmlTrim)(_content); return _content; }, (doc) => doc.querySelector(".bottem2 > a:nth-child(4)") .href, (_content, nextLink) => _content.innerText.includes("本章未完,点击下一页继续阅读")); } } exports.dingdiann = dingdiann; /***/ }), /***/ "./src/rules/dmzj.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.dmzj = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class dmzj extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".comic_deCon > h1 > a")).innerText.trim(); const author = (document.querySelector(".comic_deCon_liO > li:nth-child(1)")).innerText .replace("作者:", "") .trim(); const introDom = document.querySelector(".comic_deCon_d"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector(".comic_i_img > a > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; let cos = document.querySelectorAll("div.zj_list_con:nth-child(4) > ul.list_con_li > li"); let chapterNumber = 0; for (const co of Array.from(cos)) { chapterNumber++; const a = co.firstElementChild; const span = a.lastElementChild; const chapterName = span.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function getpicUrlList(doc) { const img_prefix = "https://images.dmzj.com/"; let pages = (0, misc_1.sandboxed)(doc.querySelector("head > script").innerText + ";return pages;"); pages = pages.replace(/\n/g, ""); pages = pages.replace(/\r/g, "|"); const info = (0, misc_1.sandboxed)("return (" + pages + ")"); if (info) { const picUrlList = info["page_url"] .split("|") .map((pic) => img_prefix + pic); return picUrlList; } } log_1.log.debug(`[Chapter]请求 ${chapterUrl}`); const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const picUrlList = getpicUrlList(doc); if (picUrlList) { const content = document.createElement("div"); for (const picUrl of picUrlList) { const pElem = document.createElement("p"); const imgElem = document.createElement("img"); imgElem.src = picUrl; pElem.appendChild(imgElem); content.appendChild(pElem); } let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } exports.dmzj = dmzj; /***/ }), /***/ "./src/rules/fushuwang.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.fushuwang = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); class fushuwang extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; this.maxRunLimit = 5; this.saveOptions = { genChapterText: (chapterName, contentText) => { return `${contentText}\n`; }, genChapterHtmlFile: (chapterName, DOM, chapterUrl) => { let htmlFile = new DOMParser().parseFromString(`${chapterName}
`, "text/html"); htmlFile.querySelector(".main")?.appendChild(DOM); return new Blob([ htmlFile.documentElement.outerHTML.replaceAll("data-src-address", "src"), ], { type: "text/html; charset=UTF-8", }); }, }; } async bookParse() { const bookUrl = (document.location.origin + document.location.pathname).replace(/(_\d+)\.html$/, ".html"); const [bookname, author] = (document.querySelector(".title_info > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > h1:nth-child(1)")).innerText.split("——"); const [introduction, introductionHTML] = [null, null]; const additionalMetadate = {}; const options = document.querySelectorAll("p.pageLink > select > option"); const urls = Array.from(options).map((option) => document.location.origin + option.getAttribute("value")); const chapters = []; for (let i = 0; i < urls.length; i++) { const chapterUrl = urls[i]; const chapterName = `page${i}`; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, i + 1, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, this.charset, {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); book.saveOptions = this.saveOptions; return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = doc.querySelector("#text"); if (content) { (0, misc_1.rm)("span", true, content); (0, misc_1.rm)("p.pageLink", true, content); (0, misc_1.rm)("script", true, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.fushuwang = fushuwang; /***/ }), /***/ "./src/rules/gongzicp.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.gongzicp = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class gongzicp extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 1; } async bookParse() { const bookUrl = document.location.href; const bookId = (document.querySelector("span.id")).innerText.replace("CP", ""); if (!bookId) { throw new Error("获取bookID出错"); } const novelGetInfoBaseUrl = "https://webapi.gongzicp.com/novel/novelGetInfo"; const novelGetInfoUrl = new URL(novelGetInfoBaseUrl); novelGetInfoUrl.searchParams.set("id", bookId); log_1.log.debug(`请求地址: ${novelGetInfoUrl.toString()}`); const novelInfo = await fetch(novelGetInfoUrl.toString(), { credentials: "include", headers: { Accept: "application/json, text/plain, */*", Client: "pc", Lang: "cn", "Content-Type": "application/json;charset=utf-8", }, referrer: bookUrl, method: "GET", mode: "cors", }).then((response) => response.json()); if (novelInfo.code !== 200) { throw new Error(`数据接口请求失败,URL:${novelGetInfoUrl.toString()}`); } const data = novelInfo.data; const bookname = data.novelInfo.novel_name; const author = data.novelInfo.author_nickname; const introDom = document.createElement("div"); introDom.innerHTML = data.novelInfo.novel_info; const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = data.novelInfo.novel_cover; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = data.novelInfo.tag_list; async function isLogin() { const getUserInfoUrl = "https://webapi.gongzicp.com/user/getUserInfo"; log_1.log.debug(`正在请求: ${getUserInfoUrl}`); const userInfo = await fetch(getUserInfoUrl, { headers: { accept: "application/json, text/javascript, */*; q=0.01", "x-requested-with": "XMLHttpRequest", }, method: "GET", mode: "cors", credentials: "include", }).then((response) => response.json()); if (userInfo.code === 200) { return true; } return false; } const logined = await isLogin(); const chapters = []; const _chapterList = data.chapterList; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (const chapterObj of _chapterList) { if (chapterObj.type === "volume") { sectionNumber = chapterObj.vid; sectionName = chapterObj.name; sectionChapterNumber = 0; } else if (chapterObj.type === "item") { const chapterUrl = [ document.location.origin, "v4", `read-${chapterObj.id}.html`, ].join("/"); const chapterNumber = Number(chapterObj.order); const chapterName = chapterObj.name; const isVIP = chapterObj.pay; const isPaid = chapterObj.is_sub; const isLock = chapterObj.lock; sectionChapterNumber++; const chapterOption = { novel_id: data.novelInfo.novel_id, chapter_id: chapterObj.id, }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", chapterOption); if ((isVIP && !(logined && chapter.isPaid)) || isLock) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function cpDecrypt(content_orig) { const setIv = (key) => { key = key + parseInt("165455", 14).toString(32); const iv = CryptoJS.enc.Utf8.parse("$h$b3!" + key); return iv; }; const setKey = (value) => { value = value + parseInt("4d5a6c8", 14).toString(36); const key = CryptoJS.enc.Utf8.parse(value + "A"); return key; }; const setcfg = (iv) => { return { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: iv, }; }; const encrypt = (value, key, cfg) => { if ("string" != typeof value) { value = JSON.stringify(value); } const xml = CryptoJS.enc.Utf8.parse(value); return CryptoJS.AES.encrypt(xml, key, cfg).toString(); }; const decrypt = (secrets, key, cfg) => { const value = CryptoJS.AES.decrypt(secrets, key, cfg); return CryptoJS.enc.Utf8.stringify(value).toString(); }; let _CP_NUXT; let LCngpxaF_substr; if (_CP_NUXT) { LCngpxaF_substr = _CP_NUXT.state.CpST.LCngpxaF.substr(2, 10); } else { LCngpxaF_substr = (unsafeWindow).__NUXT__.state.CpST.LCngpxaF.substr(1, 10); } const iv = setIv("iGzsYn"); const key = setKey(LCngpxaF_substr); const cfg = setcfg(iv); const content = decrypt(content_orig, key, cfg); return content; } function randomWalker() { log_1.log.info("[chapter]随机翻页中……"); if (document.location.pathname.includes("novel")) { (document.querySelector(".chapter-list > .chapter > a")).click(); } if (document.location.pathname.includes("read")) { const rightMenu = document.querySelector(".right-menu"); if (rightMenu?.childElementCount === 6) { (document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)")).click(); } else if (rightMenu?.childElementCount === 7) { if (document.querySelector("div.content.unpaid")) { (document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)")).click(); } else if (Math.random() < 0.3) { (document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)")).click(); } else { (document.querySelector(".right-menu > div:nth-child(4) > a:nth-child(1)")).click(); } } } } async function getChapter() { const nid = options.novel_id; const cid = options.chapter_id; const chapterGetInfoBaseUrl = "https://webapi.gongzicp.com/novel/chapterGetInfo"; const chapterGetInfoUrl = new URL(chapterGetInfoBaseUrl); chapterGetInfoUrl.searchParams.set("cid", cid.toString()); chapterGetInfoUrl.searchParams.set("nid", nid.toString()); let retryTime = 0; async function getChapterInfo(url) { log_1.log.debug(`请求地址: ${url}, Referrer: ${chapterUrl},retryTime:${retryTime}`); const result = await fetch(url, { credentials: "include", headers: { Accept: "application/json, text/plain, */*", Client: "pc", Lang: "cn", "Content-Type": "application/json;charset=utf-8", }, referrer: chapterUrl, method: "GET", mode: "cors", }).then((resp) => resp.json()); if (result.data.chapterInfo.content.length !== 0 && result.data.chapterInfo.content.length < 30) { retryTime++; if (setting_1.retryLimit > setting_1.retryLimit) { log_1.log.error(`请求 ${url} 失败`); throw new Error(`请求 ${url} 失败`); } log_1.log.warn("[chapter]疑似被阻断,进行随机翻页……"); randomWalker(); await (0, misc_1.sleep)(3000); randomWalker(); await (0, misc_1.sleep)(7000); randomWalker(); await (0, misc_1.sleep)(3000); return getChapterInfo(url); } else { retryTime = 0; return result; } } const result = await getChapterInfo(chapterGetInfoUrl.toString()); if (result.code === 200) { const chapterInfo = result.data.chapterInfo; if (chapterInfo.chapterPrice !== 0 && chapterInfo.content.length === 0) { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } else if (chapterInfo.chapterPrice === 0 || (chapterInfo.chapterPrice !== 0 && chapterInfo.content.length !== 0)) { const content = cpDecrypt(chapterInfo.content); const contentRaw = document.createElement("pre"); contentRaw.innerHTML = content; let contentText = content .split("\n") .map((p) => p.trim()) .join("\n\n"); let contentHTML; const _contentHTML = document.createElement("div"); _contentHTML.innerHTML = content .split("\n") .map((p) => p.trim()) .map((p) => { if (p.length === 0) { return "


"; } else { return `

${p}

`; } }) .join("\n"); if (chapterInfo.postscript.length === 0) { contentHTML = _contentHTML; } else { contentHTML = document.createElement("div"); contentHTML.className = "main"; const hr = document.createElement("hr"); const authorSayDom = document.createElement("div"); authorSayDom.innerHTML = chapterInfo.postscript .split("\n") .map((p) => { if (p.length === 0) { return "


"; } else { return `

${p}

`; } }) .join("\n"); contentHTML.appendChild(_contentHTML); contentHTML.appendChild(hr); contentHTML.appendChild(authorSayDom); contentRaw.innerHTML = [ contentRaw.innerHTML, "-".repeat(20), chapterInfo.postscript, ].join("\n\n"); contentText = [ contentText, "-".repeat(20), chapterInfo.postscript, ].join("\n\n"); } return { chapterName: chapterName, contentRaw: contentRaw, contentText: contentText, contentHTML: contentHTML, contentImages: null, additionalMetadate: null, }; } } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } async function antiAntiCrawler() { if (Math.random() < 0.2) { randomWalker(); } await (0, misc_1.sleep)(3000 + Math.round(Math.random() * 4000)); } async function publicChapter() { await antiAntiCrawler(); return getChapter(); } async function vipChapter() { await antiAntiCrawler(); return getChapter(); } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.gongzicp = gongzicp; /***/ }), /***/ "./src/rules/haitangtxt.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.haitangtxt = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const haitangtxtImageDecode_1 = __webpack_require__("./src/rules/lib/haitangtxtImageDecode.ts"); const log_1 = __webpack_require__("./src/log.ts"); class haitangtxt extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = (document.querySelector("div.currency_head > h1 > a")).href; const bookId = bookUrl.split("/").slice(-2, -1)[0]; log_1.log.debug(`[chapter]请求 ${bookUrl}`); const dom = await (0, http_1.getHtmlDOM)(bookUrl, "UTF-8"); const bookname = (dom.querySelector("div.cataloginfo > h3")).innerText.trim(); const author = (dom.querySelector(".infotype > p:nth-child(1) > a:nth-child(1)")).innerText.trim(); const introDom = dom.querySelector(".intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { (0, misc_1.rm)("span:nth-child(1)", false, introDom); return introDom; }); const additionalMetadate = {}; const chapters = []; const getMaxPageNumber = () => { const pageDom = document.querySelector("div.page:nth-child(6)"); if (pageDom) { const childNodes = Array.from(pageDom.childNodes); const _maxPageNumber = childNodes .slice(-1)[0] .textContent?.match(/第\d+\/(\d+)页/); if (_maxPageNumber) { return _maxPageNumber[1]; } } }; const getIndexUrls = () => { const indexUrls = []; const maxPageNumber = Number(getMaxPageNumber()); for (let i = 1; i <= maxPageNumber; i++) { const indexUrl = [ document.location.origin, document.location.pathname.split("/")[1], `${bookId}_${i}`, ].join("/") + "/"; indexUrls.push(indexUrl); } return indexUrls; }; const indexUrls = getIndexUrls(); let lis = []; for (const indexUrl of indexUrls) { log_1.log.debug(`[chapter]请求 ${indexUrl}`); const dom = await (0, http_1.getHtmlDOM)(indexUrl, "UTF-8"); const ul = dom.querySelector("ul.chapters"); if (ul?.childElementCount) { lis = lis.concat(Array.from(ul.children)); } } const chapterList = lis.filter((obj) => obj !== undefined); let chapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; chapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function contentAppend() { function UpWz(m, i) { let k = Math.ceil((i + 1) % code); k = Math.ceil(m - k); return k; } const _e = dom.getElementsByTagName("meta")[7].getAttribute("content"); const contentRaw = dom.querySelector("#articlecontent"); let codeurl; let code; const _codeurl = dom .getElementsByTagName("script")[1] .innerText.trim() .match(/"(http.+)"/); if (_codeurl) { codeurl = _codeurl[1]; code = Number(new URL(codeurl).searchParams.get("code")); } if (_e) { const e = atob(_e) .split(/[A-Z]+%/) .map((v) => Number(v)); let childNode = []; if (Array.from(dom.querySelectorAll("script")).filter((s) => s.src.includes("/17mb/js/article.js")).length) { for (let i = 0; i < e.length; i++) { let k = UpWz(e[i], i); childNode[k] = contentRaw.childNodes[i]; } for (const node of childNode) { if (node.nodeType != 1) { continue; } if (!(node.innerText.includes("本章尚未完结,请") || node.innerText.includes("本章已阅读完毕"))) { content.appendChild(node); } } return; } } for (const node of Array.from(contentRaw.childNodes)) { if (!(node.innerText.includes("本章尚未完结,请") || node.innerText.includes("本章已阅读完毕"))) { content.appendChild(node); } } return; } let nowUrl = chapterUrl; let dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = document.createElement("div"); let flag = false; do { contentAppend(); const nextLink = (dom.querySelector(".novelbutton .p1.p3 > a:nth-child(1)")).href; if (new URL(nextLink).pathname.includes("_")) { if (nextLink !== nowUrl) { flag = true; } else { log_1.log.error("网站页面出错,URL: " + nowUrl); flag = false; } } else { flag = false; } if (flag) { nowUrl = nextLink; dom = await (0, http_1.getHtmlDOM)(nextLink, charset); } } while (flag); if (content) { let { dom: oldDom, text: _text, images: finalImages, } = await (0, cleanDOM_1.cleanDOM)(content, "TM", { keepImageName: true }); const _newDom = document.createElement("div"); _newDom.innerHTML = (0, haitangtxtImageDecode_1.replaceHaitangtxtImage)(content.innerHTML); let { dom: newDom, text: finalText, images, } = await (0, cleanDOM_1.cleanDOM)(_newDom, "TM", { keepImageName: true }); const fontStyleDom = document.createElement("style"); fontStyleDom.innerHTML = `.hide { display: none; }`; oldDom.className = "hide"; const finalDom = document.createElement("div"); finalDom.appendChild(fontStyleDom); finalDom.appendChild(oldDom); finalDom.appendChild(newDom); return { chapterName: chapterName, contentRaw: content, contentText: finalText, contentHTML: finalDom, contentImages: finalImages, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.haitangtxt = haitangtxt; /***/ }), /***/ "./src/rules/hetushu.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.hetushu = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class hetushu extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".book_info > h2")).innerText.trim(); const author = (document.querySelector(".book_info > div:nth-child(3) > a:nth-child(1)")).innerText.trim(); const introDom = document.querySelector(".intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector(".book_info > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const chapterList = (document.querySelector("#dir")?.childNodes); if (chapterList && chapterList.length !== 0) { let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; if (node.nodeName === "DT") { sectionNumber++; sectionChapterNumber = 0; sectionName = node.innerText.trim(); } else if (node.nodeName === "DD") { chapterNumber++; sectionChapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function sorfPage() { let path, bid, sid, position; if (/\/(book[0-9]?)\/([0-9]+)\/([0-9]+)\.html(\?position=([0-9]+))?$/.test(chapterUrl)) { path = RegExp.$1; bid = RegExp.$2; sid = RegExp.$3; position = RegExp.$5; } else { return false; } const url = [ document.location.origin, path, bid, "r" + sid + ".json", ].join("/"); log_1.log.debug(`[Chapter]请求 ${url} Referer ${chapterUrl}`); const token = await fetch(url, { headers: { accept: "*/*", "cache-control": "no-cache", "content-type": "application/x-www-form-urlencoded", pragma: "no-cache", "x-requested-with": "XMLHttpRequest", }, referrer: chapterUrl, method: "GET", mode: "cors", credentials: "include", }).then((response) => response.headers.get("token")); if (token) { const token_dict = atob(token) .split(/[A-Z]+%/) .map((v) => Number(v)); const this_body = dom.querySelector("#content"); let b = 0, star = 0; for (let i = 0; i < this_body.childNodes.length; i++) { if (this_body.childNodes[i].nodeName == "H2") { star = i + 1; } if (this_body.childNodes[i].nodeName == "DIV" && this_body.childNodes[i].className != "chapter") { break; } } const this_childNode = []; for (let i = 0; i < token_dict.length; i++) { if (token_dict[i] < 5) { this_childNode[token_dict[i]] = this_body.childNodes[i + star]; b++; } else { this_childNode[token_dict[i] - b] = this_body.childNodes[i + star]; } } for (let i = 0; i < this_childNode.length; i++) { if (!this_childNode[i]) { continue; } this_body.appendChild(this_childNode[i]); } } } const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector("#content .h2")).innerText.trim(); await sorfPage(); const content = dom.querySelector("#content"); if (content) { const tagRemoved = "h2, acronym, bdo, big, cite, code, dfn, kbd, q, s, samp, strike, tt, u, var"; tagRemoved.split(", ").forEach((s) => { (0, misc_1.rm)(s, true, content); }); Array.from(content.querySelectorAll("div")).map((oldNode) => { const newNode = document.createElement("p"); newNode.innerHTML = oldNode.innerHTML; oldNode.parentNode?.replaceChild(newNode, oldNode); }); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.hetushu = hetushu; /***/ }), /***/ "./src/rules/idejian.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.idejian = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class idejian extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.maxRunLimit = 5; } async bookParse() { const bookUrl = document.location.href; const _bookID = bookUrl.match(/\/(\d+)\/$/); const bookID = _bookID && _bookID[1]; const bookname = (document.querySelector(".detail_bkname > a")).innerText.trim(); const _author = document.querySelector(".detail_bkauthor") .childNodes[0]; let author = "佚名"; if (_author && _author.textContent) { author = _author.textContent.trim(); } const introDom = document.querySelector(".brief_con"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector(".book_img > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(document.querySelectorAll("div.detail_bkgrade > span")).map((span) => span.innerText.trim()); const chapters = []; const cos = document.querySelectorAll(".catelog_list > li > a"); let chapterNumber = 0; for (const aElem of Array.from(cos)) { chapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", { bookID: bookID }); chapters.push(chapter); } document.cookie = ""; const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const _chapterUrl = new URL(chapterUrl); _chapterUrl.hostname = "m.idejian.com"; chapterUrl = _chapterUrl.toString(); const referBaseUrl = "https://m.idejian.com/catalog"; const _refer = new URL(referBaseUrl); _refer.searchParams.set("bookId", options.bookID); const referUrl = _refer.toString(); const fakeUA = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Snapchat/10.77.5.59 (like Safari/604.1)"; if (document.cookie === "") { await (0, http_1.ggetText)(referUrl, charset, { headers: { "User-Agent": fakeUA } }); await (0, http_1.ggetText)(chapterUrl, charset, { headers: { "User-Agent": fakeUA, Referer: referUrl }, }); } log_1.log.debug(`[Chapter]请求 ${chapterUrl},Refer:${referUrl}`); let doc = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset, { headers: { "User-Agent": fakeUA, Referer: referUrl }, }); chapterName = (doc.querySelector(".text-title-1")).innerText.trim(); let content; if (doc.querySelectorAll("div.h5_mainbody").length === 1) { content = doc.querySelector("div.h5_mainbody"); } else { content = doc.querySelectorAll("div.h5_mainbody")[1]; } if (content) { (0, misc_1.rm)("h1", false, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.idejian = idejian; /***/ }), /***/ "./src/rules/imiaobige.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.imiaobige = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class imiaobige extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; } async bookParse() { const bookUrl = document.location.href .replace("/read/", "/novel/") .replace(/\/$/, ".html"); const doc = await (0, http_1.getHtmlDOM)(bookUrl, this.charset); const bookname = (doc.querySelector(".booktitle > h1")).innerText.trim(); const author = (doc.querySelector("#author > a")).innerText.trim(); const introDom = doc.querySelector("#bookintro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = doc.querySelector("#bookimg > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const sections = document.querySelectorAll("#readerlists > ul"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = s.querySelector("h3").innerText .replace(bookname, "") .trim(); if (sectionName.includes("最新章节")) { continue; } let sectionChapterNumber = 0; const cs = s.querySelectorAll("li > a"); for (let j = 0; j < cs.length; j++) { const a = cs[j]; chapterNumber++; sectionChapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, false, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, { bookname: bookname }); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const bookname = options.bookname; const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".title > h1:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { content.innerHTML = content.innerHTML.replace(`

您可以在百度里搜索“${bookname} 妙笔阁(imiaobige.com)”查找最新章节!

`, ""); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.imiaobige = imiaobige; /***/ }), /***/ "./src/rules/jjwxc.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.jjwxc = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_2 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const jjwxcFontDecode_1 = __webpack_require__("./src/rules/lib/jjwxcFontDecode.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class jjwxc extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; this.charset = "GB18030"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector('h1[itemprop="name"] > span')).innerText.trim(); const additionalMetadate = {}; const author = (document.querySelector("td.sptd h2 a span")).innerText .replace(/作\s+者:/, "") .trim(); const introDom = document.querySelector("#novelintro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); if (introCleanimages) { additionalMetadate.attachments = [...introCleanimages]; } let coverUrl = (document.querySelector(".noveldefaultimage")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } let tags = (document.querySelector("table > tbody > tr > td.readtd > div.righttd > ul.rightul > li:nth-child(1) > span:nth-child(2)")).innerText.split("-"); tags = tags.concat(Array.from(document.querySelectorAll("div.smallreadbody:nth-child(3) > span > a")).map((a) => a.innerText)); const perspective = (document.querySelector("table > tbody > tr > td.readtd > div.righttd > ul.rightul > li:nth-child(2)")).innerText.replace("\n", ""); const workStyle = (document.querySelector("table > tbody > tr > td.readtd > div.righttd > ul.rightul > li:nth-child(3)")).innerText.replace("\n", ""); tags.push(perspective); tags.push(workStyle); additionalMetadate.tags = tags; const chapters = []; const trList = document.querySelectorAll("#oneboolt > tbody > tr"); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < trList.length; i++) { const tr = trList[i]; if (tr.getAttribute("bgcolor")) { sectionNumber++; sectionChapterNumber = 0; sectionName = (tr.querySelector("b.volumnfont"))?.innerText.trim(); } else if (tr.getAttribute("itemprop")) { chapterNumber++; sectionChapterNumber++; const td = tr.querySelector("td:nth-child(2)"); const a = td?.querySelector("a:nth-child(1)"); const isLocked = () => { if (td?.innerText.trim() === "[锁]") { return true; } else { return false; } }; const isVIP = () => { if (a?.getAttribute("onclick")) { return true; } else { return false; } }; if (!isLocked()) { if (isVIP()) { const chapterName = a.innerText.trim(); const chapterUrl = a.getAttribute("rel"); if (chapterUrl) { const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), null, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); const isLogin = () => { if (document.getElementById("jj_login")) { return false; } else { return true; } }; if (isVIP() && !isLogin()) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } else { const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), null, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); const isLogin = () => { if (document.getElementById("jj_login")) { return false; } else { return true; } }; if (isVIP() && !isLogin()) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { const dom = await (0, http_2.getHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector("div.noveltext h2")).innerText.trim(); const content = dom.querySelector("div.noveltext"); if (content) { (0, misc_1.rm)("hr", true, content); const rawAuthorSayDom = content.querySelector(".readsmall"); let authorSayDom, authorSayText; if (rawAuthorSayDom) { let { dom: adom, text: atext, images: aimages, } = await (0, cleanDOM_1.cleanDOM)(rawAuthorSayDom, "TM"); [authorSayDom, authorSayText] = [adom, atext]; } (0, misc_1.rm)("div", true, content); content.innerHTML = content.innerHTML.replaceAll("@无限好文,尽在晋江文学城", ""); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); if (rawAuthorSayDom && authorSayDom && authorSayText) { const hr = document.createElement("hr"); authorSayDom.className = "authorSay"; dom.appendChild(hr); dom.appendChild(authorSayDom); text = text + "\n\n" + "-".repeat(20) + "\n\n" + authorSayText; } return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } async function vipChapter() { async function getFont() { function getFontInfo() { const s = dom.querySelectorAll("body > style")[1]; let fontName, fontUrl; if (s.sheet) { const f = s.sheet.cssRules[s.sheet.cssRules.length - 2]; const m1 = f.cssText.match(/jjwxcfont_[\d\w]+/); const m2 = f.cssText.match(/{(.*)}/); if (m1 && m2) { fontName = m1[0]; const ft = m2[1]; for (const k of ft.split(",")) { if (k.includes('format("woff2")')) { const m3 = k.match(/url\("(.*)"\)\s/); if (m3) { fontUrl = document.location.protocol + m3[1]; return [fontName, fontUrl]; } } } } } const _fontName = document.querySelector("div.noveltext")?.classList[1]; if (_fontName) { fontName = _fontName; fontUrl = document.location.protocol + `//static.jjwxc.net/tmp/fonts/${fontName}.woff2?h=my.jjwxc.net`; return [fontName, fontUrl]; } return [null, null]; } let retryTime = 0; function fetchFont(fontUrl) { log_1.log.debug(`[Chapter]请求 ${fontUrl} Referer ${chapterUrl} 重试次数 ${retryTime}`); return (0, http_1.gfetch)(fontUrl, { headers: { accept: "*/*", Referer: chapterUrl, }, responseType: "blob", }).then((response) => { if (response.status >= 200 && response.status <= 299) { return response.response; } else { log_1.log.error(`[Chapter]请求 ${fontUrl} 失败 Referer ${chapterUrl}`); if (retryTime < setting_1.retryLimit) { retryTime++; return fetchFont(fontUrl); } else { return null; } } }); } const [fontName, fontUrl] = getFontInfo(); if (fontName && fontUrl) { const fontFileName = `${fontName}.woff2`; let fontClassObj; const fontClassObjCache = (0, attachments_1.getAttachmentClassCache)(fontUrl); if (fontClassObjCache) { fontClassObj = fontClassObjCache; } else { const fontBlob = await fetchFont(fontUrl); fontClassObj = new main_1.attachmentClass(fontUrl, fontFileName, "TM"); fontClassObj.imageBlob = fontBlob; fontClassObj.status = main_1.Status.finished; (0, attachments_1.putAttachmentClassCache)(fontClassObj); } const fontStyleDom = document.createElement("style"); fontStyleDom.innerHTML = `.${fontName} { font-family: ${fontName}, 'Microsoft YaHei', PingFangSC-Regular, HelveticaNeue-Light, 'Helvetica Neue Light', sans-serif !important; } @font-face { font-family: ${fontName}; src: url('${fontFileName}') format('woff2'); } .hide { display: none; }`; return [fontName, fontClassObj, fontStyleDom]; } return [null, null, null]; } const dom = await (0, http_2.ggetHtmlDOM)(chapterUrl, charset); const isPaid = () => { if (!dom.querySelector("#buy_content") && dom.querySelector("div.noveltext")) { return true; } else { return false; } }; if (isPaid()) { const chapterName = (dom.querySelector("div.noveltext h2")).innerText.trim(); const content = dom.querySelector("div.noveltext"); if (content) { (0, misc_1.rm)("hr", true, content); const rawAuthorSayDom = content.querySelector(".readsmall"); let authorSayDom, authorSayText; if (rawAuthorSayDom) { let { dom: adom, text: atext, images: aimages, } = await (0, cleanDOM_1.cleanDOM)(rawAuthorSayDom, "TM"); [authorSayDom, authorSayText] = [adom, atext]; } (0, misc_1.rm)("div", true, content); content.innerHTML = content.innerHTML.replaceAll("@无限好文,尽在晋江文学城", ""); let { dom: rawDom, text: rawText, images, } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); if (rawAuthorSayDom && authorSayDom && authorSayText) { const hr = document.createElement("hr"); authorSayDom.className = "authorSay"; rawDom.appendChild(hr); rawDom.appendChild(authorSayDom); rawText = rawText + "\n\n" + "-".repeat(20) + "\n\n" + authorSayText; } let finalDom = rawDom; let finalText = rawText; const [fontName, fontClassObj, fontStyleDom] = await getFont(); if (fontName && fontClassObj && fontStyleDom) { finalText = await (0, jjwxcFontDecode_1.replaceJjwxcCharacter)(fontName, rawText); images.push(fontClassObj); finalDom = document.createElement("div"); const replacedDom = document.createElement("div"); replacedDom.innerHTML = await (0, jjwxcFontDecode_1.replaceJjwxcCharacter)(fontName, rawDom.innerHTML); finalDom.appendChild(fontStyleDom); rawDom.className = `${fontName} hide`; finalDom.appendChild(rawDom); finalDom.appendChild(replacedDom); } return { chapterName: chapterName, contentRaw: content, contentText: finalText, contentHTML: finalDom, contentImages: images, additionalMetadate: null, }; } } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.jjwxc = jjwxc; /***/ }), /***/ "./src/rules/lib/common.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.mkRuleClass1 = exports.nextPageParse = exports.introDomHandle = void 0; const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const log_1 = __webpack_require__("./src/log.ts"); async function introDomHandle(introDom, domPatch = undefined) { if (introDom === null) { return [null, null, null]; } else { if (domPatch) { introDom = domPatch(introDom.cloneNode(true)); } let { dom: introCleanDom, text: introCleantext, images: introCleanimages, } = await (0, cleanDOM_1.cleanDOM)(introDom, "TM"); return [introCleantext, introCleanDom, introCleanimages]; } } exports.introDomHandle = introDomHandle; async function nextPageParse(chapterName, chapterUrl, charset, selector, contentPatch, getNextPage, continueCondition) { log_1.log.debug(`[Chapter]请求 ${chapterUrl}`); let nowUrl = chapterUrl; let doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = document.createElement("div"); let flag = false; do { let _content = doc.querySelector(selector); const nextLink = getNextPage(doc); if (continueCondition(_content, nextLink)) { if (nextLink !== nowUrl) { flag = true; } else { log_1.log.error("网站页面出错,URL: " + nowUrl); flag = false; } } else { flag = false; } _content = contentPatch(_content, doc); for (const _c of Array.from(_content.childNodes)) { content.appendChild(_c.cloneNode(true)); } if (flag) { log_1.log.debug(`[Chapter]请求 ${nextLink}`); nowUrl = nextLink; doc = await (0, http_1.getHtmlDOM)(nextLink, charset); } } while (flag); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } exports.nextPageParse = nextPageParse; function mkRuleClass1(optionis) { const { bookUrl, bookname, author, introDom, introDomPatch, coverUrl, cos, getContent, contentPatch, } = optionis; return class extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = document.charset; } async bookParse() { const [introduction, introductionHTML, introCleanimages] = await introDomHandle(introDom, introDomPatch); const additionalMetadate = {}; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; let chapterNumber = 0; for (const aElem of Array.from(cos)) { chapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, this.charset, { bookname: bookname }); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); let content = getContent(doc); if (content) { content = contentPatch(content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } }; } exports.mkRuleClass1 = mkRuleClass1; /***/ }), /***/ "./src/rules/lib/haitangtxtImageDecode.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.replaceHaitangtxtImage = void 0; function replaceHaitangtxtImage(inputText) { let outputText = inputText; for (const imageFilename in imageTable) { const normalCharacter = imageTable[imageFilename]; const imageHTML = ``; outputText = outputText.replaceAll(imageHTML, normalCharacter); } return outputText; } exports.replaceHaitangtxtImage = replaceHaitangtxtImage; const imageTable = {}; /***/ }), /***/ "./src/rules/lib/jjwxcFontDecode.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.replaceJjwxcCharacter = void 0; const idb_keyval_1 = __webpack_require__("./node_modules/idb-keyval/dist/index.js"); const setting_1 = __webpack_require__("./src/setting.ts"); const log_1 = __webpack_require__("./src/log.ts"); async function replaceJjwxcCharacter(fontName, inputText) { let outputText = inputText; const jjwxcFontTable = await getJjwxcFontTable(fontName); if (jjwxcFontTable) { for (const jjwxcCharacter in jjwxcFontTable) { const normalCharacter = jjwxcFontTable[jjwxcCharacter]; outputText = outputText.replaceAll(jjwxcCharacter, normalCharacter); } outputText = outputText.replaceAll("‌", ""); } return outputText; } exports.replaceJjwxcCharacter = replaceJjwxcCharacter; async function getJjwxcFontTable(fontName) { const jjwxcFontTables = await getJjwxcFontTables(); const jjwxcFontTableLocal = jjwxcFontTables[fontName]; if (jjwxcFontTableLocal) { return jjwxcFontTableLocal; } else if (setting_1.enableJjwxcRemoteFont) { return await fetchRemoteFont(fontName); } else { return undefined; } } async function fetchRemoteFont(fontName) { const url = `https://jjwxc.bgme.bid/${fontName}.json`; try { log_1.log.info(`[jjwxc-font]开始请求远程字体对照表 ${fontName}`); const resp = await fetch(url); if (resp.status === 200) { log_1.log.info(`[jjwxc-font]远程字体对照表 ${fontName} 下载成功`); return (await resp.json()); } else { log_1.log.info(`[jjwxc-font]远程字体对照表 ${fontName} 下载失败`); return undefined; } } catch (error) { log_1.log.error(error); log_1.log.info(`[jjwxc-font]远程字体对照表 ${fontName} 下载失败`); return undefined; } } async function getJjwxcFontTables() { const JjwxcFontTablesKeyName = "novel-downloader-jjwxcFontTables"; const JjwxcFontTablesExpiresKeyName = "novel-downloader-jjwxcFontTables__expires__"; const JjwxcFontTablesUrl = "https://cdn.jsdelivr.net/gh/yingziwu/jjwxcFontTables@gh-pages/bundle.json"; async function fetchAndSave() { try { log_1.log.info("[jjwxc-font]开始下载字体对照表打包文件。"); const resp = await fetch(JjwxcFontTablesUrl); _jjwxcFontTables = await resp.json(); if (_jjwxcFontTables) { if (await (0, idb_keyval_1.get)(JjwxcFontTablesKeyName)) { await (0, idb_keyval_1.update)(JjwxcFontTablesKeyName, (val) => _jjwxcFontTables); } else { await (0, idb_keyval_1.set)(JjwxcFontTablesKeyName, _jjwxcFontTables); } if (await (0, idb_keyval_1.get)(JjwxcFontTablesExpiresKeyName)) { await (0, idb_keyval_1.update)(JjwxcFontTablesExpiresKeyName, (val) => Date.now() + 1000 * 86400); } else { await (0, idb_keyval_1.set)(JjwxcFontTablesExpiresKeyName, Date.now() + 1000 * 86400); } return _jjwxcFontTables; } else { return {}; } } catch (error) { return {}; } } let _jjwxcFontTables = await (0, idb_keyval_1.get)(JjwxcFontTablesKeyName); if (_jjwxcFontTables) { if ((await (0, idb_keyval_1.get)(JjwxcFontTablesExpiresKeyName)) && (await (0, idb_keyval_1.get)(JjwxcFontTablesExpiresKeyName)) > Date.now()) { return _jjwxcFontTables; } else { return await fetchAndSave(); } } else { return await fetchAndSave(); } } /***/ }), /***/ "./src/rules/lib/yuzhaigeImageDecode.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.replaceYuzhaigeImage = void 0; function replaceYuzhaigeImage(inputText) { let outputText = inputText; for (const imageFilename in imageTable) { const normalCharacter = imageTable[imageFilename]; const imageHTML = ``; outputText = outputText.replaceAll(imageHTML, normalCharacter); } return outputText; } exports.replaceYuzhaigeImage = replaceYuzhaigeImage; const imageTable = { "wc5pDq.png": "\u52c3", "wEwIpN.png": "\u8404", "WFOBXF.png": "\u4f26", "WFuqEG.png": "\u6eda", "WNTyYB.png": "\u83ca", "WrI5St.png": "\u6234", "WSYLdq.png": "\u5ba0", "wvHBh4.png": "\u5976", "wWVoto.png": "\u5df4", "wz2cGb.png": "\u4e73", "wZicAt.png": "\u9053", "WzS8He.png": "\u6234", "X6QTS9.png": "\u80ef", "XBTII5.png": "\u817f", "XBv6rP.png": "\u8df3", "xFVZW9.png": "\u6b96", "XhuslD.png": "\u9e21", "xIFlai.png": "\u98df", "XK7taQ.png": "\u723d", "xljRqd.png": "\u9876", "xo18Yq.png": "\u5c3f", "xOIyuf.png": "\u585e", "xQ2ZWb.png": "\u80a1", "XqsaJY.png": "\u8f6f", "xrbxqL.png": "\u88f8", "xw7cLW.png": "\u868c", "xwkwQW.png": "\u7cbe", "XXlZMA.png": "\u6b96", "y3FgRm.png": "\u67f1", "y4Afmt.png": "\u817f", "Y4aXzR.png": "\u7c97", "Y7G6Lu.png": "\u547b", "YGnnuo.png": "\u871c", "ygqjgt.png": "\u634f", "yGwSy7.png": "\u9a9a", "yjX9oi.png": "\u63c9", "YNmgYJ.png": "\u809b", "yuo7sA.png": "\u6469", "yWAu0U.png": "\u50ac", "yWhRNI.png": "\u5a07", "YZ4EAh.png": "\u5589", "yzS8NJ.png": "\u80ef", "z0DZro.png": "\u542e", "Z7byDx.png": "\u6da6", "ZatUU6.png": "\u5974", "zCtJCx.png": "\u6da6", "ZDJHkT.png": "\u6ccc", "ZKDja5.png": "\u9f9f", "ZqyamF.png": "\u5c44", "ZzsV7x.png": "\u777e", "0bErVo.png": "\u6df1", "0ShNwM.png": "\u5439", "0uCAgc.png": "\u5f3a", "1AMfxw.png": "\u5e72", "1EmzV7.png": "\u6027", "1RbeKi.png": "\u5934", "1RIz6c.png": "\u611f", "1ZkZsI.png": "\u6b32", "2AXYPX.png": "\u6cc4", "2gwsiE.png": "\u6e7f", "2LQHtR.png": "\u6839", "2wePG6.png": "\u4f53", "2Xijao.png": "\u634f", "3ha4Fq.png": "\u6b22", "3RfcEA.png": "\u9ad8", "3uNZxG.png": "\u80f8", "4bu7Gr.png": "\u8482", "4T4DPM.png": "\u64e6", "4XjmUQ.png": "\u8fdb", "5hjo9r.png": "\u4e0b", "5ueElb.png": "\u5bab", "5yFlDm.png": "\u5bab", "6UsGer.png": "\u74e3", "6w928M.png": "\u633a", "6YavUk.png": "\u6696", "7dKm1T.png": "\u8fdb", "7tzEqy.png": "\u70b9", "8Q4cTQ.png": "\u90e8", "9Ns27O.png": "\u9633", "9pAfcz.png": "\u5934", "9Xkn86.png": "\u5507", "62TB7X.png": "\u7d27", "668QKT.png": "\u4e0b", "aedVOS.png": "\u9732", "AI15xh.png": "\u5a07", "AikKsW.png": "\u80a0", "AJcH1b.png": "\u51fa", "ALnkng.png": "\u5598", "anzcle.png": "\u9053", "apsw0Z.png": "\u5b50", "azRZNn.png": "\u6c34", "B38zEI.png": "\u6c34", "BAVYZd.png": "\u9634", "BBioQd.png": "\u6696", "BBZnCY.png": "\u5507", "bE6LV6.png": "\u7f8e", "bF30CY.png": "\u5438", "bihdjA.png": "\u5507", "BPQcCZ.png": "\u5177", "BpYip0.png": "\u7ba1", "BrY1ZI.png": "\u817f", "BvbcsW.png": "\u7d27", "bXRYQt.png": "\u5904", "Caqk3D.png": "\u773c", "CBylOX.png": "\u9053", "ClFBCD.png": "\u5904", "CLS5cG.png": "\u575a", "cPjFxZ.png": "\u79cd", "CUJkGk.png": "\u60c5", "CZL2OC.png": "\u76ae", "D3I7u1.png": "\u8482", "d5KjC5.png": "\u4f53", "d7fjCZ.png": "\u9732", "df6AnM.png": "\u51fa", "dhAaVT.png": "\u575a", "dkuDIk.png": "\u820c", "DSiSlL.png": "\u7231", "dTnQ9K.png": "\u9b54", "dXMpnD.png": "\u6655", "DXtzqf.png": "\u8eab", "DXXixh.png": "\u5957", "DZYaDR.png": "\u9633", "e5QAQ1.png": "\u5f3a", "ECcmqT.png": "\u6625", "eeYwrN.png": "\u6c34", "eGWHWT.png": "\u6170", "eOOKlp.png": "\u89e6", "EvHzor.png": "\u6b32", "ewwRMT.png": "\u903c", "EZW46f.png": "\u6df1", "FBosfH.png": "\u6027", "fC5MmR.png": "\u6237", "ffTW4v.png": "\u62bd", "ffZqua.png": "\u6027", "FgN2Tl.png": "\u4e71", "fHvZK9.png": "\u7f1d", "fj7veK.png": "\u957f", "fkPlzo.png": "\u98df", "fKWetR.png": "\u7ba1", "FUmeqN.png": "\u25a1", "Fus88J.png": "\u725b", "G4uOno.png": "\u55b7", "g7bVzL.png": "\u9ad8", "GBmlnw.png": "\u8df3", "gCWM61.png": "\u7cbe", "GdAidg.png": "\u7b4b", "GLZIqA.png": "\u5b50", "gqDVGg.png": "\u5de8", "gu5ykL.png": "\u8f6e", "GULUze.png": "\u9ad8", "h2FI8R.png": "\u80f8", "h4WPDX.png": "\u6655", "hCztH8.png": "\u9732", "hfI2uM.png": "\u575a", "hGHijB.png": "\u5668", "hIhWai.png": "\u9ad8", "HIUVkJ.png": "\u5c04", "HkcQea.png": "\u4ea4", "hm5O6l.png": "\u5957", "hpFE8s.png": "\u6d41", "HPxfmS.png": "\u542b", "hVxPKi.png": "\u89e6", "Ia3sI1.png": "\u4e71", "IA8APJ.png": "\u5df4", "IlUZRn.png": "\u575a", "iN7Lri.png": "\u98df", "iQMM3x.png": "\u611f", "ISfDuf.png": "\u4f53", "isWxov.png": "\u9a6c", "ITILdU.png": "\u6267", "IU731r.png": "\u9876", "IUanTB.png": "\u878d", "IUUwWq.png": "\u5165", "Ixqere.png": "\u6d41", "J9AEU9.png": "\u5165", "JBfhPp.png": "\u64cd", "jDxrrX.png": "\u5b50", "jE4V2B.png": "\u6df1", "jF1KPd.png": "\u25a1", "jFACnh.png": "\u6bdb", "jiyfGR.png": "\u6839", "JLkmp8.png": "\u80a1", "jWwTqU.png": "\u60c5", "K00hgA.png": "\u5165", "KaFnqe.png": "\u6eda", "Kaqaq0.png": "\u9634", "kDOkxJ.png": "\u957f", "kSkOOe.png": "\u6309", "KtjQU3.png": "\u634f", "kWmDQN.png": "\u5904", "kZQ8K6.png": "\u4e0b", "l0kRFF.png": "\u7269", "L9dqnM.png": "\u6b32", "Ldo3hW.png": "\u8089", "ljppnW.png": "\u611f", "lNGSuh.png": "\u80a0", "lRfqbE.png": "\u7cbe", "lUzsIi.png": "\u8f6e", "LZraJy.png": "\u6625", "mBpVnV.png": "\u4e71", "MEM8Wx.png": "\u5e72", "MO2VKV.png": "\u6db2", "ModDMS.png": "\u62bd", "mOZJWk.png": "\u9a6c", "mpgh5T.png": "\u51fa", "nj29a6.png": "\u6267", "NOEnvb.png": "\u8df3", "nrSIO8.png": "\u6df1", "o2xN3U.png": "\u82b1", "O3b3KR.png": "\u6696", "o5uSeU.png": "\u5bab", "OaBMS5.png": "\u62d4", "OB7KzU.png": "\u773c", "oCH7SV.png": "\u9b54", "oeeXig.png": "\u9a6c", "OgBVeb.png": "\u8f6f", "oHc3dE.png": "\u7269", "OLHWRr.png": "\u70b9", "onuRXa.png": "\u8482", "oqLfcR.png": "\u6ed1", "oUntUm.png": "\u6d53", "OXOdsf.png": "\u9053", "p3ARaM.png": "\u6d41", "p068ps.png": "\u5bab", "PLwxDG.png": "\u79cd", "PmCTBy.png": "\u8272", "pMlQBk.png": "\u6c41", "pQypTa.png": "\u8fdb", "PtUVdN.png": "\u62bd", "PW1WSi.png": "\u6e7f", "Pw3ezj.png": "\u914d", "pXy3UL.png": "\u4ea4", "Q7jy4x.png": "\u5185", "q07XV1.png": "\u5668", "Q9OBtA.png": "\u6f6e", "QbYFBI.png": "\u9634", "qEI00x.png": "\u4e0b", "qewOBk.png": "\u6ed1", "QfXoIi.png": "\u8089", "qJIAe3.png": "\u6309", "QkWjrV.png": "\u8eab", "QnFF9j.png": "\u6839", "qNFYq4.png": "\u5e72", "QU7Lcv.png": "\u25a1", "qwsVcX.png": "\u62bd", "qxb6Lz.png": "\u70b9", "QzP4Nz.png": "\u773c", "R8uNPt.png": "\u5185", "R9tjeh.png": "\u51fa", "rFr75w.png": "\u80f8", "rGA9Cq.png": "\u4ea4", "RjCFQu.png": "\u7d27", "RLNC0G.png": "\u70b9", "rocNQb.png": "\u505a", "Rpp7lC.png": "\u8482", "rUJMTx.png": "\u8272", "RZZBiZ.png": "\u773c", "S2Dvd4.png": "\u6cc4", "s8DZGN.png": "\u60c5", "s560YT.png": "\u5177", "SeKcc0.png": "\u8272", "sFFl4b.png": "\u5ba0", "SiAa7G.png": "\u5934", "slAZvO.png": "\u8272", "sTPB8l.png": "\u89e6", "sV6OrY.png": "\u957f", "syPCmu.png": "\u8f6e", "Sz5U6E.png": "\u5668", "SZn6xB.png": "\u7269", "T6sDn9.png": "\u60c5", "t9WGXQ.png": "\u903c", "TCRQtC.png": "\u6ed1", "TGkFFQ.png": "\u903c", "tNjFEZ.png": "\u82b1", "tOUYgC.png": "\u9b54", "TSjC0C.png": "\u5ead", "TSp4f1.png": "\u62d4", "TWIhpT.png": "\u7231", "TxaWbU.png": "\u878d", "ua2bew.png": "\u9876", "UbTLa5.png": "\u633a", "uDN4sP.png": "\u5165", "ueMquS.png": "\u8eab", "UEVcqG.png": "\u8eab", "UIFeaH.png": "\u914d", "unR6fo.png": "\u9633", "Upc9Pu.png": "\u4ea4", "UukBzP.png": "\u6d1e", "UvCU0f.png": "\u5ba0", "VAOIqQ.png": "\u7f8e", "vMf2zS.png": "\u914d", "VnXHdX.png": "\u505a", "vpHmyj.png": "\u5185", "Vql6Ev.png": "\u59d0", "vrkjXi.png": "\u79cd", "vtnLR7.png": "\u6c34", "wkUtOc.png": "\u25a1", "WOHLvx.png": "\u5976", "WppxBg.png": "\u7f8e", "WRtMHz.png": "\u56ca", "WTAi5O.png": "\u63c9", "wtwCbu.png": "\u725b", "WXf8jT.png": "\u5177", "xpWTjp.png": "\u7269", "XqFPrk.png": "\u505a", "XrHw7R.png": "\u4f53", "XskrJT.png": "\u9633", "xubhKq.png": "\u6bdb", "xxqGbU.png": "\u80f8", "y2rhls.png": "\u505a", "y8TJ26.png": "\u79cd", "YbmlHp.png": "\u82b1", "YpcoIg.png": "\u7f8e", "yruS8G.png": "\u8650", "YTWiNM.png": "\u82b1", "YvzoUL.png": "\u5589", "YY1gAh.png": "\u878d", "yYS2XJ.png": "\u8fdb", "ZaWg8Q.png": "\u6d53", "zbUsFu.png": "\u70ed", "zGqroA.png": "\u5b50", "zhogXd.png": "\u9732", "zM4vGZ.png": "\u6eda", "ZMyXfX.png": "\u786c", "Znemv4.png": "\u9a6c", "ZnORLb.png": "\u5934", "zovunx.png": "\u7a74", "ZpcLFr.png": "\u7231", "4KLtoP.png": "\u868c", "k2hzhi.png": "\u854a", "OpOeoc.png": "\u96cf", "D6GjNJ.png": "\u90a6", "nSh1y5.png": "\u90a6", "ZD1bga.png": "\u819c", "0JNnRt.png": "\u88c6", "0laGrG.png": "\u52c3", "0sEWeF.png": "\u723d", "0X07Oj.png": "\u957f", "0ZBaBv.png": "\u7a74", "1WoJda.png": "\u633a", "1yUGqq.png": "\u5957", "2ABT9u.png": "\u7ba1", "2BcI5e.png": "\u6838", "2dfEmL.png": "\u808f", "2LdPZ9.png": "\u5df4", "2VLZTT.png": "\u5438", "2WgKu9.png": "\u6625", "03PhNV.png": "\u6469", "3preuJ.png": "\u6f6e", "3tNh88.png": "\u63d2", "4m7wbi.png": "\u6655", "4mO3Bj.png": "\u5993", "4P4bWw.png": "\u70eb", "4qJrgq.png": "\u50ac", "4xMdlq.png": "\u6345", "5aHMLF.png": "\u6d53", "5caAaX.png": "\u542b", "5IL1sE.png": "\u817a", "5qxLLo.png": "\u8404", "5rXkkk.png": "\u5f04", "5uAxU4.png": "\u63c9", "5XAgwu.png": "\u5978", "6A9MvV.png": "\u52c3", "6jL6AP.png": "\u8361", "6ontyx.png": "\u8461", "6VRwjR.png": "\u7c97", "6zcWUT.png": "\u6cc4", "7aWXdF.png": "\u6f6e", "7Bz8yG.png": "\u68cd", "7fhmqV.png": "\u88e4", "7jKFaP.png": "\u5978", "7lNejO.png": "\u704c", "7pFdxn.png": "\u64b8", "7Q7Jrg.png": "\u5c4c", "8BNYPM.png": "\u6696", "8J5geS.png": "\u541f", "8Kf7GD.png": "\u830e", "8mHmVv.png": "\u830e", "8N16Hq.png": "\u8650", "8UniDu.png": "\u6237", "8w5K9T.png": "\u88f8", "8wm13p.png": "\u6655", "8ZNrSv.png": "\u786c", "9BRV3o.png": "\u5c4c", "9Nqw8t.png": "\u762b", "9RBhTJ.png": "\u9a9a", "9RvnBS.png": "\u8089", "9TaMmD.png": "\u6ccc", "9UaEDH.png": "\u6d1e", "9zWVtd.png": "\u59d0", "47FrvB.png": "\u4e73", "76gAv7.png": "\u723d", "77lL1M.png": "\u541f", "798jja.png": "\u76ae", "a0mCeq.png": "\u8f6f", "ACrPlr.png": "\u98df", "aFoXhJ.png": "\u75d2", "Afr6zx.png": "\u6b96", "aHuUcm.png": "\u83ca", "AiDkbY.png": "\u809b", "aOxG78.png": "\u8461", "AQZ08I.png": "\u809b", "ARAUs9.png": "\u5c41", "arEzdS.png": "\u5976", "axdkbW.png": "\u58c1", "aYGWo2.png": "\u83ca", "b1C6Pu.png": "\u75d2", "bCQ2nL.png": "\u654f", "BgJzfk.png": "\u6b22", "BhgFcH.png": "\u56ca", "bOoL0J.png": "\u6deb", "BqO1fa.png": "\u820c", "bqXZDH.png": "\u80a5", "BsU6ka.png": "\u854a", "Bu9FZQ.png": "\u6deb", "bufT6t.png": "\u819c", "bWdbXA.png": "\u6eda", "C4UN5R.png": "\u6deb", "CgqkFG.png": "\u8361", "CH67yh.png": "\u5a07", "CM7jpY.png": "\u5b55", "cNghja.png": "\u8361", "CnOBoo.png": "\u63d2", "CNQW3o.png": "\u70eb", "cow4Kc.png": "\u5f3a", "CXC9uz.png": "\u8089", "Cy7Ynb.png": "\u762b", "czWHZw.png": "\u96cf", "D0Lwo9.png": "\u871c", "dB0uJO.png": "\u820c", "dHuyiO.png": "\u5c4c", "DQWBph.png": "\u4e38", "DsEJTV.png": "\u547b", "dUrJvn.png": "\u819c", "Ea3lho.png": "\u81c0", "EboGWZ.png": "\u80a0", "eifoua.png": "\u5b55", "EiUhlF.png": "\u5957", "ENwWoX.png": "\u4e71", "EQEgJx.png": "\u6469", "EQiUab.png": "\u88e4", "er8NJ7.png": "\u542e", "F0WoiN.png": "\u5177", "f1YTv0.png": "\u6f6e", "f2N1vL.png": "\u5978", "F3nlmb.png": "\u88e4", "F6lW1R.png": "\u80bf", "f60BEY.png": "\u5c3f", "f461mD.png": "\u6839", "fd6C8F.png": "\u9e21", "Fdz1Vc.png": "\u58c1", "FetNxM.png": "\u5c4c", "FfxOzl.png": "\u88f8", "Fge27m.png": "\u8404", "fGpEWq.png": "\u547b", "Fl20Ip.png": "\u9f9f", "fNXZyj.png": "\u6234", "fRmx68.png": "\u90e8", "fSdsL1.png": "\u88c6", "FT9nI5.png": "\u83ca", "FVVqzv.png": "\u86cb", "FwjZJi.png": "\u5438", "fX4WIp.png": "\u4f26", "FXgFwc.png": "\u63d2", "FXmf8I.png": "\u647a", "fxPcW3.png": "\u6d1e", "g2jVxn.png": "\u808f", "gb3LOX.png": "\u80ef", "gDVng6.png": "\u5ba0", "gImiVY.png": "\u5f04", "gJDFQC.png": "\u8214", "gJDG8l.png": "\u5b55", "GJodYn.png": "\u62d4", "GmLjKa.png": "\u5c09", "gNlJMc.png": "\u68cd", "GppocX.png": "\u914d", "gsRjtr.png": "\u67f1", "GTOAc4.png": "\u633a", "GzjpTS.png": "\u7cbe", "h8zRxr.png": "\u80a1", "H17DtI.png": "\u5c41", "ha14XV.png": "\u89e6", "hatLmR.png": "\u81c0", "hbrRIS.png": "\u857e", "hC4NbQ.png": "\u777e", "hG0SRP.png": "\u64e6", "HhNUaw.png": "\u854a", "hKjWPG.png": "\u64b8", "Hn8Afh.png": "\u74e3", "hngWaZ.png": "\u5438", "htV3uv.png": "\u58c1", "hVaVng.png": "\u6309", "HVHPCy.png": "\u74e3", "hVwy7k.png": "\u8214", "i4tyrQ.png": "\u830e", "i5s28n.png": "\u4f26", "IAloq6.png": "\u542e", "ICHARH.png": "\u6237", "icI6Ey.png": "\u81c0", "iCRh88.png": "\u68d2", "Iej2pu.png": "\u5993", "IkqJmu.png": "\u8650", "imVjMj.png": "\u4e73", "iNIMEL.png": "\u86cb", "IOjnEP.png": "\u6b22", "ip6KUM.png": "\u79bd", "IPC2R8.png": "\u9e21", "ipVGiA.png": "\u6345", "IpYNG3.png": "\u5974", "ITUjFq.png": "\u76ae", "ixiion.png": "\u90e8", "IZcCzq.png": "\u871c", "IzJ4WG.png": "\u830e", "J1CBtB.png": "\u8df3", "j9C44i.png": "\u70eb", "JCQtUs.png": "\u4e73", "JEcz0E.png": "\u871c", "JfPEEe.png": "\u4f26", "jHi6Vu.png": "\u9f9f", "jjfR6D.png": "\u8461", "jktdia.png": "\u64e6", "JlkuRa.png": "\u8404", "jnAvXp.png": "\u5ead", "jnCCk9.png": "\u6cc4", "jvj3DG.png": "\u786c", "Jy4pAI.png": "\u74e3", "jZyPEL.png": "\u5b55", "K2AtMQ.png": "\u9a9a", "K2jjT6.png": "\u857e", "k6X0xy.png": "\u80bf", "k9h8DR.png": "\u903c", "k9zXwG.png": "\u723d", "KalRLt.png": "\u6da6", "kawcM7.png": "\u68cd", "kdsEv6.png": "\u5f04", "KdwL4R.png": "\u86cb", "kPG0vR.png": "\u704c", "KSqmoM.png": "\u6db2", "kTCaM9.png": "\u86cb", "kVLLjB.png": "\u8361", "kygbuo.png": "\u725b", "kZDlEj.png": "\u7ba1", "l0BNLC.png": "\u6ccc", "l1Dmft.png": "\u725b", "L1yl45.png": "\u5c04", "L3a5ft.png": "\u56ca", "L3LaNQ.png": "\u5439", "L9F6F8.png": "\u50ac", "LB1WMg.png": "\u64cd", "LBPqYj.png": "\u6d1e", "LDjbfQ.png": "\u5c3f", "ldo7FB.png": "\u7d27", "lErO3o.png": "\u67f1", "LFBZKA.png": "\u59d0", "lfGqdb.png": "\u68d2", "lGKjej.png": "\u5993", "LjemA3.png": "\u809b", "Ljh7qo.png": "\u63d2", "LJSiT5.png": "\u5c44", "Lk5uQy.png": "\u6838", "lngKEo.png": "\u55b7", "lOfDdC.png": "\u4e38", "Lsq92O.png": "\u541f", "LsyPdc.png": "\u541f", "lVbZkd.png": "\u634f", "lVMTQu.png": "\u654f", "LVmymH.png": "\u80a0", "lyYo4Y.png": "\u547b", "lZtabT.png": "\u9634", "M3VjF9.png": "\u64b8", "m4yvu3.png": "\u7a74", "M8bV3k.png": "\u56ca", "MBhDEi.png": "\u75d2", "MC5lZn.png": "\u585e", "Mc8JM6.png": "\u62d4", "mD7hPS.png": "\u5c41", "mExNDV.png": "\u704c", "MKapwC.png": "\u80a5", "mKxUHv.png": "\u64e6", "Mo31Ax.png": "\u6bdb", "mRFQJQ.png": "\u5589", "MsUFfR.png": "\u6b96", "mTzxxd.png": "\u7f1d", "n2ufBJ.png": "\u5978", "n3oOgA.png": "\u6345", "n9j6EC.png": "\u5ead", "n49ZFH.png": "\u88c6", "nCrl80.png": "\u762b", "NDlwhm.png": "\u817a", "nE1Y7y.png": "\u762b", "neIgqc.png": "\u5439", "NeKVfz.png": "\u6170", "NHH9A1.png": "\u777e", "NKN1rk.png": "\u542e", "NKUSkP.png": "\u58c1", "NlfTkc.png": "\u5c44", "NlZDDQ.png": "\u817f", "nmoPI2.png": "\u4e38", "NnfPEJ.png": "\u9f9f", "NP33MO.png": "\u6c41", "NQ7oga.png": "\u611f", "nsDzuq.png": "\u90a6", "NsIwni.png": "\u5de8", "oaLZIg.png": "\u777e", "oC3HDZ.png": "\u7c97", "OFx7ZU.png": "\u88f8", "OHU6tX.png": "\u6db2", "olFcqI.png": "\u5e72", "OMdbeV.png": "\u819c", "On4f9C.png": "\u7b4b", "oncaJq.png": "\u76ae", "Oo8iWN.png": "\u6309", "OUWXqz.png": "\u6625", "OuXWg2.png": "\u4e38", "ozF5Kr.png": "\u8650", "p0bqZi.png": "\u5c44", "p1H9RN.png": "\u5c04", "p5QCRV.png": "\u6ed1", "p5zEbo.png": "\u857e", "P43O6G.png": "\u6234", "PalsBW.png": "\u5974", "PcAvOY.png": "\u5ae9", "pHfPTa.png": "\u5de8", "pi2z0b.png": "\u7b4b", "plFlPb.png": "\u68cd", "pNPlu5.png": "\u704c", "PnZNBC.png": "\u6deb", "pQ1W2F.png": "\u88e4", "PX3jJ6.png": "\u6ccc", "q14YbK.png": "\u9876", "Qc9LRh.png": "\u5598", "qe2YZi.png": "\u63c9", "qEy1kT.png": "\u90e8", "Qfs9DA.png": "\u50ac", "Qg8Qwg.png": "\u857e", "qJ1X2h.png": "\u59d0", "qm0ZBO.png": "\u6170", "QmcP4w.png": "\u654f", "Qn3xBM.png": "\u5ae9", "qNGvlk.png": "\u5c3f", "qPhrVf.png": "\u5904", "qPX1Ef.png": "\u542b", "qr8InI.png": "\u80a5", "QtLIGq.png": "\u6db2", "QtSnzR.png": "\u5598", "Qv3JbY.png": "\u7f1d", "QYF65i.png": "\u7b4b", "Qz4Txd.png": "\u81c0", "qzdvCv.png": "\u5df4", "r7NsvF.png": "\u5f04", "r8oBsP.png": "\u9e21", "r9Gw4X.png": "\u6838", "R65BZO.png": "\u8214", "Rf7Jf6.png": "\u6469", "Rho2GL.png": "\u75d2", "rlVLx7.png": "\u7231", "Rm3wex.png": "\u55b7", "RmrhKk.png": "\u8214", "RMWsBY.png": "\u654f", "rn9y6F.png": "\u585e", "RnfJ8h.png": "\u67f1", "RP5Oud.png": "\u5598", "Rp5tmA.png": "\u64cd", "rpSSYK.png": "\u80ef", "rQKjMD.png": "\u6bdb", "RrXcE9.png": "\u5668", "RyL5jk.png": "\u6c41", "s67RPe.png": "\u70eb", "s95kq4.png": "\u6e7f", "sdXZMk.png": "\u52c3", "SGxBy7.png": "\u5c41", "smhB8j.png": "\u5c04", "Srgobp.png": "\u6237", "srlW2t.png": "\u6d41", "ST21xu.png": "\u6d53", "STzFJz.png": "\u7c97", "sugwEw.png": "\u5976", "SzADhL.png": "\u80bf", "T5yzvl.png": "\u6c41", "t6K8rK.png": "\u6027", "tAIV6q.png": "\u64cd", "TCFRca.png": "\u68d2", "te79V0.png": "\u68d2", "tjbhCV.png": "\u5ae9", "tNFwEz.png": "\u5589", "tPTX1h.png": "\u80a5", "tsQMiL.png": "\u5439", "TUZb1W.png": "\u6b32", "TWFykG.png": "\u5993", "twLxYU.png": "\u8f6f", "tXNaZ2.png": "\u878d", "U3bhkh.png": "\u9a9a", "u6K6ci.png": "\u6b22", "u9Tibu.png": "\u5185", "Ua2WwL.png": "\u5a07", "Uai2en.png": "\u5f3a", "UeWULF.png": "\u5ead", "UfXSsz.png": "\u540e", "ui0T5v.png": "\u79bd", "UqClGF.png": "\u80a1", "Urv1FM.png": "\u80bf", "uwXRHd.png": "\u55b7", "v4iqzP.png": "\u7f1d", "vAdmoL.png": "\u786c", "VhA8GI.png": "\u5ae9", "VHsdy1.png": "\u6838", "vjOssT.png": "\u585e", "vkYfGf.png": "\u9b54", "vMmUqq.png": "\u5974", "VnvOwV.png": "\u6da6", "VoAjiw.png": "\u6e7f", "vrtXeW.png": "\u88c6", "VUbefT.png": "\u8f6e", "vulCqw.png": "\u6267", "VYaPfX.png": "\u7a74", "VyJ2cS.png": "\u90a6", "W06Vg1.png": "\u5de8", "W7cCwn.png": "\u6345", "W9Y9vD.png": "\u820c", "wa54S5.png": "\u542b", "FNq1zS.png": "\u868C", "DDpMPK.png": "\u868C", "vDbU8w.png": "\u817A", "SSoXSL.png": "\u8461", "YB6iOy.png": "\u817A", "kMqpt6.png": "\u96CF", "5RwMUT.png": "\u854A", "b94JXX.png": "\u8114", "oxFS6J.png": "\u8114", "H53jMR.png": "\u96CF", }; /***/ }), /***/ "./src/rules/linovel.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.linovel = void 0; const main_1 = __webpack_require__("./src/main.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class linovel extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".book-title")).innerText.trim(); const author = (document.querySelector(".author-frame > .novelist > div:nth-child(3) > a")).innerText.trim(); const introDom = document.querySelector(".about-text"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const attachmentsUrlList = []; const coverUrl = (document.querySelector(".book-cover > a")).href; if (coverUrl) { attachmentsUrlList.push(coverUrl); (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.attachments = []; const volumeCoverUrlList = Array.from(document.querySelectorAll(".section-list > .section > .volume-info > .volume-cover a")).map((a) => a.href); for (const volumeCoverUrl of volumeCoverUrlList) { if (!attachmentsUrlList.includes(volumeCoverUrl)) { attachmentsUrlList.push(volumeCoverUrl); (0, attachments_1.getImageAttachment)(volumeCoverUrl, this.imageMode, "volumeCover-").then((volumeCoverObj) => { additionalMetadate.attachments?.push(volumeCoverObj); }); } } additionalMetadate.tags = Array.from(document.querySelectorAll("div.meta-info > div.book-cats.clearfix > a")).map((a) => a.innerText.trim()); const chapters = []; const sections = document.querySelectorAll(".section-list > .section"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = (s.querySelector(".volume-info > h2.volume-title > a")).innerText.trim(); let sectionChapterNumber = 0; const cs = s.querySelectorAll(".chapter-list > .text-content-actual div.chapter"); for (let j = 0; j < cs.length; j++) { const div = cs[j]; const a = div.firstElementChild; chapterNumber++; sectionChapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const isVIP = () => { if (div.className.includes("lock")) { if (div.className.includes("unlock")) { return false; } else { return true; } } return false; }; const isPaid = () => { return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const chapterName = (doc.querySelector(".article-title")).innerText.trim(); const content = doc.querySelector(".article-text"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.linovel = linovel; /***/ }), /***/ "./src/rules/linovelib.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.linovelib = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class linovelib extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href.replace(/\/catalog$/, ".html"); const bookname = (document.querySelector(".book-meta > h1")).innerText.trim(); const author = (document.querySelector(".book-meta > p:nth-child(2) > span:nth-child(1) > a:nth-child(2)")).innerText.trim(); const doc = await (0, http_1.getHtmlDOM)(bookUrl, undefined); const introDom = doc.querySelector(".book-dec > p:nth-child(1)"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = doc.querySelector(".book-img > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(doc.querySelectorAll(".book-label a")).map((a) => a.innerText.trim()); const chapters = []; const chapterList = document.querySelector(".chapter-list"); if (!chapterList) { throw new Error("获取章节失败!"); } const liList = chapterList.children; let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < liList.length; i++) { const node = liList[i]; const nodeNmae = node.nodeName.toLowerCase(); if (nodeNmae === "div") { sectionNumber++; sectionChapterNumber = 0; sectionName = node.innerText.trim(); } else if (nodeNmae === "li") { chapterNumber++; sectionChapterNumber++; const a = node.firstElementChild; const isVIP = false; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, null, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); if (chapterUrl.startsWith("javascript")) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { return (0, common_1.nextPageParse)(chapterName, chapterUrl, charset, "#TextContent", (_content, doc) => { const s = Array.from(doc.querySelectorAll("script")).find((s) => s.innerHTML.includes('document.getElementById("chapter_last")')); if (s) { const _dom_nr = s.innerText.trim().match(/let dom_nr = '(.+)';/); if (_dom_nr) { const dom_nr = _dom_nr[1]; doc.getElementById("chapter_last").innerHTML = dom_nr; } } (0, misc_1.rm)(".tp", true, _content); (0, misc_1.rm)(".bd", true, _content); return _content; }, (doc) => doc.querySelector(".mlfy_page > a:nth-child(5)") .href, (_content, nextLink) => new URL(nextLink).pathname.includes("_")); } } exports.linovelib = linovelib; /***/ }), /***/ "./src/rules/lofter.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.lofter = void 0; const main_1 = __webpack_require__("./src/main.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const log_1 = __webpack_require__("./src/log.ts"); class lofter extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { const bookUrl = document.location.origin; const author = JSON.parse('"' + unsafeWindow._ntes_ntit.replaceAll("%", "\\") + '"'); const bookname = author + "的Lofter"; const introduction = document .querySelector('meta[name="Description"]') ?.getAttribute("content") ?.replace(new RegExp(`^${author} - `), "") ?? null; let introductionHTML = null; if (introduction) { introductionHTML = document.createElement("p"); introductionHTML.innerText = introduction; } const additionalMetadate = {}; const _avatar = document .querySelector('link[rel="shortcut icon"]') ?.getAttribute("href"); if (_avatar) { const avatar = new URL(_avatar); avatar.search = ""; const avatarUrl = avatar.toString(); (0, attachments_1.getImageAttachment)(avatarUrl, this.imageMode, "avatar-").then((avatarClass) => { additionalMetadate.cover = avatarClass; }); } const chapters = []; const pageUrlSet = new Set(); const indexPageUrls = []; const getPageUrl = async (url) => { log_1.log.info(`[chapter]正在抓取目录页:${url}`); const doc = await (0, http_1.getHtmlDOM)(url, undefined); const selector = `a[href^="${[document.location.origin, "post"].join("/")}"]`; const urlSet = new Set(Array.from(doc.querySelectorAll(selector)).map((a) => a.href)); urlSet.forEach((item) => pageUrlSet.add(item)); const selectorl = `a[href^="https://www.lofter.com/lpost"]`; const urlSetl = new Set(Array.from(doc.querySelectorAll(selectorl)).map((a) => a.href)); urlSetl.forEach((item) => pageUrlSet.add(item)); const getIndexPageNumber = (url) => { const _pageNumber = new URL(url).searchParams.get("page") ?? "1"; const indexPageNumber = Number(_pageNumber); return indexPageNumber; }; const nowIndexPageNumber = getIndexPageNumber(url); const indexPages = doc.querySelectorAll('a[href^="?page"]'); for (const indexPage of Array.from(indexPages)) { const indexPageUrl = indexPage.href; const _indexPageUrlFormat = new URL(indexPageUrl); _indexPageUrlFormat.searchParams.delete("t"); const indexPageUrlFormat = _indexPageUrlFormat.toString(); const indexPageNumber = getIndexPageNumber(indexPageUrl); if (indexPageNumber !== nowIndexPageNumber) { if (!indexPageUrls.includes(indexPageUrlFormat)) { indexPageUrls.push(indexPageUrlFormat); await getPageUrl(indexPageUrl); } } } }; await getPageUrl(document.location.href); let i = 0; for (const pageUrl of Array.from(pageUrlSet)) { const chapter = new main_1.Chapter(bookUrl, bookname, pageUrl, i, null, false, false, null, null, null, this.chapterParse, "UTF-8", { author: author }); chapters.push(chapter); i++; } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function post() { log_1.log.debug(`[chapter]请求页面:${chapterUrl}`); const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc .querySelector("title") ?.innerText.replace(new RegExp(`-${options.author}$`), "") .replace("\n", "") .trim() ?? null; const selectors = [".ct .ctc", ".main .content", ".m-post .text"]; let content; for (const selector of selectors) { const _content = doc.querySelector(selector); if (_content !== null) { content = _content; break; } } if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { throw new Error(`[chapter]未发现内容,url:${chapterUrl}`); } } async function lpost() { log_1.log.debug(`[chapter]请求页面:${chapterUrl}`); const doc = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset); chapterName = (doc.querySelector("#title"))?.innerText.trim(); const content = doc.querySelector("#m-cnt .long-text"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { throw new Error(`[chapter]未发现内容,url:${chapterUrl}`); } } if (new URL(chapterUrl).pathname.startsWith("/lpost/")) { return lpost(); } else { return post(); } } } exports.lofter = lofter; /***/ }), /***/ "./src/rules/longmabook.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.longmabook = void 0; const main_1 = __webpack_require__("./src/main.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); class longmabook extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { const isLogin = Boolean(document.querySelector('a[href="/?act=signinlst"]')); if (!isLogin) { alert("海棠文化线上文学城需登录后方可浏览!请登录帐号。"); throw new main_1.ExpectError("海棠文化线上文学城需登录后方可浏览!"); } const bookUrl = document.location.href; const bookname = document.querySelector("#mypages > div:nth-child(8) > div:nth-child(1) > h4").innerText; const author = document.querySelector("#writerinfos > a").innerText; const _urlSearch = new URLSearchParams(document.location.search); const bookId = _urlSearch.get("bookid"); const bookwritercode = _urlSearch.get("bookwritercode"); const introDom = document .querySelector("#mypages > div:nth-child(8) > div:nth-child(1)") ?.cloneNode(true); let [introduction, introductionHTML, introCleanimages] = [null, null, null]; if (introDom) { (0, misc_1.rm)("div", true, introDom); (0, misc_1.rm)("textarea", true, introDom); (0, misc_1.rm)("font", true, introDom); (0, misc_1.rm)("b", true, introDom); (0, misc_1.rm)("span", true, introDom); (0, misc_1.rm)("h4", true, introDom); (0, misc_1.rm)("img", true, introDom); introDom.innerHTML = introDom.innerHTML .replace(/【作品编号:\d+】|【作品編號:\d+】/, "") .replace("\n)\n", ""); [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); } const additionalMetadate = {}; const coverUrl = (document.querySelector("#mypages > div:nth-child(8) > div:nth-child(1) > img"))?.src.replace("_s.", "_b."); if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = document.querySelector('#mypages > div:nth-child(8) > div:nth-child(1) > font[color="#800080"]')?.innerText .split("/") .map((item) => item.trim()) ?? []; const chapters = []; const liList = document.querySelectorAll(`#showbooklist${bookId} > div > ul > li`); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < liList.length; i++) { const li = liList[i]; const uk_icon = li.querySelector("span")?.getAttribute("uk-icon"); if (uk_icon === "folder") { sectionNumber++; sectionChapterNumber = 0; sectionName = (li.querySelector("b > font"))?.innerText.trim(); } else if (uk_icon === "file-text") { chapterNumber++; sectionChapterNumber++; const a = li.querySelector("a"); const chapterName = a?.innerText.trim(); const chapterUrl = a?.href; const isVIP = Boolean(li.innerText.match(/\$[\d\.]+/)); if (chapterUrl && chapterName) { const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, null, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, { bookId: bookId, bookwritercode: bookwritercode }); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const self = this; const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); if (doc.body.innerHTML.includes("您目前正在海棠清水區,只能觀看清水認證文章。")) { if (!window.stopFlag) { alert("您目前正在海棠清水區,只能觀看清水認證文章。請使用海棠其他網址進入。"); window.stopFlag = true; } throw new Error("您目前正在海棠清水區,只能觀看清水認證文章。請使用海棠其他網址進入。"); } const nullObj = { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; if (doc.querySelector("#paperbuybtm")) { log_1.log.info(`[chapter]付费章节 ${chapterName} 未购买。`); return nullObj; } const content = document.createElement("div"); let contentText = ""; let contentImages = []; const [imagesDom, imagesText, imagesImages] = await getImages(); const [mainDom, mainText, mainImages] = await getMainContent(); const [authorDom, authorText, authorImages] = await getAuthorSay(); if (imagesDom) { content.appendChild(imagesDom); contentText += imagesText + "\n\n"; if (imagesImages) { contentImages = contentImages.concat(imagesImages); } } if (mainDom) { content.appendChild(mainDom); contentText += mainText; if (mainImages) { contentImages = contentImages.concat(mainImages); } } if (authorDom) { const hr = document.createElement("hr"); authorDom.className = "authorSay"; content.appendChild(hr); content.appendChild(authorDom); contentText += "\n\n" + "-".repeat(20) + "\n\n" + authorText; if (authorImages) { contentImages = contentImages.concat(authorImages); } } return { chapterName: chapterName, contentRaw: content, contentText: contentText, contentHTML: content, contentImages: contentImages, additionalMetadate: null, }; async function getImages() { const imageDom = document.createElement("div"); Array.from(doc.querySelectorAll("#mypages > div:nth-child(10) > div:nth-child(2) > div:nth-child(6) > ul > li:nth-child(14) > img")).forEach((img) => imageDom.appendChild(img.cloneNode(true))); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(imageDom, self.imageMode); return [dom, text, images]; } async function getMainContent() { const getPaperidAndVercodechk = () => { const s = Array.from(doc.querySelectorAll("script")).filter((s) => s.innerText.includes("vercodechk"))[0]; const m = s.innerText.match(/{\spaperid:\s'(\d+)',\svercodechk:\s'(\w+)'}/); if (m?.length === 3) { const [paperid, vercodechk] = m.slice(1); return [paperid, vercodechk]; } return [null, null]; }; const [paperid, vercodechk] = getPaperidAndVercodechk(); if (paperid && vercodechk) { const showpapercolorUrl = document.location.origin + "/showpapercolor.php"; log_1.log.debug(`[chapter]正在请求${showpapercolorUrl}`); const resp = await fetch(showpapercolorUrl, { credentials: "include", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest", "Cache-Control": "max-age=0", }, referrer: chapterUrl, body: new URLSearchParams({ paperid: paperid, vercodechk: vercodechk, }).toString(), method: "POST", mode: "cors", }); const contentMain = document.createElement("div"); contentMain.innerHTML = await resp.text(); (0, misc_1.rm)('img[src="/images/fullcolor.png"]', true, contentMain); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(contentMain, self.imageMode); return [dom, text, images]; } else { return [null, null, null]; } } async function getAuthorSay() { const authorSayDom = doc.querySelector("#colorpanelwritersay"); if (authorSayDom) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(authorSayDom, self.imageMode); return [dom, text, images]; } else { return [null, null, null]; } } function getEgg() { } } } exports.longmabook = longmabook; /***/ }), /***/ "./src/rules/meegoq.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.meegoq = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class meegoq extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 3; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.href.replace("/book", "/info"); const dom = await (0, http_1.getHtmlDOM)(bookUrl, "GBK"); const author = (dom.querySelector("article.info > p.detail.pt20 > i:nth-child(1) > a")).innerText.trim(); const bookname = (dom.querySelector("article.info > header > h1")).innerText.trim(); const introDom = dom.querySelector("article.info > p.desc"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { (0, misc_1.rm)("b", false, introDom); return introDom; }); const additionalMetadate = {}; const coverUrl = (dom.querySelector("article.info > div.cover > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const ul = document.querySelector("ul.mulu"); if (ul?.childElementCount) { const ulc = Array.from(ul.children); if (Array.from(ulc[0].classList).includes("volumn") && ulc[0].innerText.match(/最新.章/)) { for (let i = 0; i < ul?.childElementCount; i++) { if (i !== 0 && Array.from(ulc[i].classList).includes("volumn") && ulc[i].innerText.trim() !== "全部章节") { delete ulc[0]; break; } delete ulc[i]; } } const chapterList = ulc.filter((obj) => obj !== undefined); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const li = chapterList[i]; if (Array.from(li.classList).includes("volumn")) { sectionNumber++; sectionChapterNumber = 0; sectionName = li.innerText.trim(); } else { chapterNumber++; sectionChapterNumber++; const a = li.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector("article > header > h1")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.meegoq = meegoq; /***/ }), /***/ "./src/rules/mht.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.mht = void 0; const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const biquge_1 = __webpack_require__("./src/rules/biquge.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class mht extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const self = this; return (0, biquge_1.bookParseTemp)({ bookUrl: document.location.href, bookname: (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector("#fmimg > img").src, chapterListSelector: "#list>dl", charset: "UTF-8", chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { return (0, common_1.nextPageParse)(chapterName, chapterUrl, charset, "#content", (_content, doc) => { (0, misc_1.rm)("p[data-id]", true, _content); return _content; }, (doc) => doc.querySelector(".bottem2 > a:nth-child(4)") .href, (_content, nextLink) => new URL(nextLink).pathname.includes("_")); } } exports.mht = mht; /***/ }), /***/ "./src/rules/qidian.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.qidian = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_2 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class qidian extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { let bookId = document.getElementById("bookImg"); if (bookId) { bookId = bookId.getAttribute("data-bid"); } else { throw new Error("未发现 bookId"); } const authorId = document .getElementById("authorId") ?.getAttribute("data-authorid"); const _csrfToken = unsafeWindow.jQuery.ajaxSettings.data._csrfToken; const bookUrl = document.location.href; const bookname = (document.querySelector(".book-info > h1 > em")).innerText.trim(); const author = (document.querySelector(".book-info .writer")).innerText .replace(/作\s+者:/, "") .trim(); const introDom = document.querySelector(".book-info-detail .book-intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector("#bookImg > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(document.querySelectorAll(".book-info > .tag > a, .tag-wrap > .tags")).map((a) => a.innerText.trim()); const limitFree = Boolean(document.querySelector(".book-information .flag")); log_1.log.info(`[Book]限免书籍 ${limitFree}`); const chapters = []; const liLength = document.querySelectorAll("#j-catalogWrap li").length; const getChapterTotalNumber = () => { const span = (document.querySelector("#J-catalogCount")).innerText.match(/\d+/); if (span) { return Number(span[0]); } }; if (!(liLength && getChapterTotalNumber() === liLength)) { await (0, misc_1.sleep)(3000); } const sections = document.querySelectorAll("#j-catalogWrap > .volume-wrap > .volume"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = s.querySelector("h3").innerText .trim() .split("\n") .slice(-1)[0] .split("·")[0]; let sectionChapterNumber = 0; const cs = s.querySelectorAll("ul.cf > li"); for (let j = 0; j < cs.length; j++) { const c = cs[j]; const a = c.querySelector("a"); chapterNumber++; sectionChapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const isVIP = () => { const host = new URL(chapterUrl).host; if (host === "vipreader.qidian.com") { return true; } return false; }; const isPaid = () => { if (isVIP()) { if (c.childElementCount === 2) { return false; } else { return true; } } return false; }; let chapterId; if (isVIP()) { chapterId = chapterUrl.split("/").slice(-1)[0]; } else { chapterId = null; } const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", { _csrfToken: _csrfToken, bookId: bookId, authorId: authorId, chapterId: chapterId, limitFree: limitFree, }); const isLogin = () => { const sign_in_dom = document.querySelector(".sign-in"); const sign_out_dom = document.querySelector(".sign-out"); if (sign_in_dom && sign_out_dom) { if (Array.from(sign_out_dom.classList).includes("hidden")) { return true; } } return false; }; if (isVIP()) { chapter.status = main_1.Status.aborted; if (limitFree) { chapter.status = main_1.Status.pending; } if (isLogin() && chapter.isPaid) { chapter.status = main_1.Status.pending; } } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const bookId = options.bookId; const authorId = options.authorId; const chapterId = options.chapterId; const limitFree = options.limitFree; const _csrfToken = options._csrfToken; async function publicChapter() { const dom = await (0, http_2.ggetHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector(".j_chapterName > .content-wrap")).innerText.trim(); const nullObj = { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; if (dom.querySelector(".vip-limit-wrap")) { return nullObj; } const content = dom.querySelector(".read-content"); const author_say_wrap = (dom.querySelector(".author-say-wrap")); if (content) { if (author_say_wrap) { const author_say = author_say_wrap.querySelector("div.author-say > p:nth-child(3)"); const hr = document.createElement("hr"); content.appendChild(hr); content.appendChild(author_say); } let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return nullObj; } } async function vipChapter() { async function getChapterInfo() { const baseUrl = "https://vipreader.qidian.com/ajax/chapter/chapterInfo"; const search = new URLSearchParams({ _csrfToken: _csrfToken, bookId: bookId, chapterId: chapterId, authorId: authorId, }); const url = baseUrl + "?" + search.toString(); log_1.log.debug(`[Chapter]请求 ${url} Referer ${chapterUrl}`); return (0, http_1.gfetch)(url, { headers: { accept: "application/json, text/javascript, */*; q=0.01", "x-requested-with": "XMLHttpRequest", Referer: chapterUrl, }, responseType: "json", }).then((response) => response.response); } async function getByAPI() { const chapterInfo = await getChapterInfo(); if (chapterInfo.code === 0) { const authorSay = chapterInfo.data.chapterInfo.authorSay; const _content = chapterInfo.data.chapterInfo.content; const content = document.createElement("div"); content.innerHTML = _content; if (authorSay) { const hr = document.createElement("hr"); content.appendChild(hr); const authorSayDom = document.createElement("p"); authorSayDom.innerHTML = authorSay; content.appendChild(authorSayDom); } const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { log_1.log.error(`[chapter]VIP章节API请求失败!\n${JSON.stringify(chapterInfo)}`); return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } if (limitFree || isPaid) { const _obj = await publicChapter(); if (!_obj.contentHTML) { return getByAPI(); } else { return _obj; } } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.qidian = qidian; /***/ }), /***/ "./src/rules/qimao.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.qimao = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class qimao extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { let bookUrl = document.location.href; const bookname = (document.querySelector("h2.tit")).innerText.trim(); const author = (document.querySelector(".p-name > a")).innerHTML.trim(); const introDom = (document.querySelector(".book-introduction .article")); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector(".poster-pic > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(document.querySelectorAll(".qm-tags > a")).map((a) => a.innerText.trim()); const chapters = []; const cos = document.querySelectorAll('.chapter-directory > dd > div[sort-type="ascending"] a'); let chapterNumber = 0; for (const aElem of Array.from(cos)) { chapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const isVIP = () => { if (aElem.childElementCount) { return true; } else { return false; } }; const isPaid = () => { return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), null, null, null, this.chapterParse, "UTF-8", {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { log_1.log.debug(`[Chapter]请求 ${chapterUrl}`); let doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".title").innerText.trim(); const content = doc.querySelector(".article"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.qimao = qimao; /***/ }), /***/ "./src/rules/qingoo.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.qingoo = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class qingoo extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; } async bookParse() { let bookUrl = document.location.href; const bookname = (document.querySelector(".title > dl > dd > h1")).innerText.trim(); const author = document.querySelector("#author").innerText .replace("作者:", "") .trim(); const introDom = document.querySelector("#allDesc"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector(".title > dl > dt > img:nth-child(1)")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const data = unsafeWindow.data; const _linkTemp = (document.querySelector("#chapterItem")?.firstElementChild)?.href; const linkTemp = new URL(_linkTemp); for (const d of data) { const status = d.status; const chapterNumber = d.sn; const chapterName = d.name; linkTemp.searchParams.set("index", (chapterNumber - 1).toString()); const chapterUrl = linkTemp.toString(); const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, this.charset, {}); if (!status) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (doc.querySelector("#content > h1")).innerText.trim(); const content = doc.querySelector("#content"); if (content) { (0, misc_1.rm)("div.header", false, content); (0, misc_1.rm)("h1", false, content); (0, misc_1.rm)("h6", false, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.qingoo = qingoo; /***/ }), /***/ "./src/rules/sfacg.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.sfacg = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class sfacg extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 1; } async bookParse() { const bookUrl = document.location.href.replace("/MainIndex/", ""); const bookname = (document.querySelector("h1.story-title")).innerText.trim(); const dom = await (0, http_1.getHtmlDOM)(bookUrl, undefined); const author = (dom.querySelector(".author-name")).innerText.trim(); const introDom = dom.querySelector(".introduce"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = (dom.querySelector("#hasTicket div.pic img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(dom.querySelectorAll("ul.tag-list > li.tag > a")).map((a) => { (0, misc_1.rm)("span.icn", false, a); return a.innerText.trim().replace(/\(\d+\)$/, ""); }); if (dom.querySelector(".d-banner")) { const _beitouUrl = (dom.querySelector(".d-banner"))?.style.backgroundImage.split('"'); if (_beitouUrl?.length === 3) { const beitouUrl = _beitouUrl[1]; const beitou = new main_1.attachmentClass(beitouUrl, `beitou.${beitouUrl.split(".").slice(-1)[0]}`, "TM"); beitou.init(); additionalMetadate.attachments = [beitou]; } } const chapters = []; const sections = document.querySelectorAll(".story-catalog"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionName = (s.querySelector(".catalog-title")).innerText .replace(`【${bookname}】`, "") .trim(); let sectionChapterNumber = 0; const cs = s.querySelectorAll(".catalog-list > ul > li > a"); for (let j = 0; j < cs.length; j++) { const c = cs[j]; const _chapterName = c.getAttribute("title")?.trim(); chapterNumber++; sectionChapterNumber++; const chapterName = _chapterName ? _chapterName : ""; const chapterUrl = c.href; let isVIP = false; let isPaid = null; if (c.childElementCount && c.firstElementChild?.getAttribute("class") === "icn_vip") { isVIP = true; } const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); const isLogin = document.querySelector(".user-bar > .top-link > .normal-link") ?.childElementCount === 3 ? true : false; if (isVIP && !isLogin) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const chapter_id = chapterUrl.split("/").slice(-2, -1)[0]; async function publicChapter() { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector("h1.article-title")).innerText.trim(); const content = dom.querySelector(".article-content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { async function getvipChapterImage(vipChapterImageUrl, vipChapterName) { let retryTime = 0; function fetchVipChapterImage(vipChapterImageUrl) { log_1.log.debug(`[Chapter]请求 ${vipChapterImageUrl} Referer ${chapterUrl} 重试次数 ${retryTime}`); return fetch(vipChapterImageUrl, { headers: { accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", }, referrer: chapterUrl, body: null, method: "GET", mode: "cors", credentials: "include", }) .then((response) => response.blob()) .then((blob) => { if (blob.size === 53658 || blob.size === 42356) { log_1.log.error(`[Chapter]请求 ${vipChapterImageUrl} 失败 Referer ${chapterUrl}`); if (retryTime < setting_1.retryLimit) { retryTime++; return fetchVipChapterImage(vipChapterImageUrl); } else { return null; } } else { return blob; } }); } const vipChapterImageBlob = await fetchVipChapterImage(vipChapterImageUrl); const vipChapterImage = new main_1.attachmentClass(vipChapterImageUrl, vipChapterName, "naive"); if (vipChapterImageBlob) { vipChapterImage.imageBlob = vipChapterImageBlob; vipChapterImage.status = main_1.Status.finished; } else { vipChapterImage.status = main_1.Status.failed; } return vipChapterImage; } const isLogin = document.querySelector(".user-bar > .top-link > .normal-link") ?.childElementCount === 3 ? true : false; if (isLogin) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector("h1.article-title")).innerText.trim(); const isPaid = dom.querySelector(".pay-section") === null; if (isPaid) { const vipChapterDom = (dom.querySelector(".article-content > #vipImage")); if (vipChapterDom) { const vipChapterImageUrl = vipChapterDom.src; const vipChapterName = `vipCHapter${chapter_id}.gif`; const vipChapterImage = await getvipChapterImage(vipChapterImageUrl, vipChapterName); const contentImages = [vipChapterImage]; const img = document.createElement("img"); img.src = vipChapterName; img.alt = vipChapterImageUrl; const contentHTML = document.createElement("div"); contentHTML.appendChild(img); const contentText = `VIP章节,请打开HTML文件查看。\n![${vipChapterImageUrl}](${vipChapterName})`; return { chapterName: chapterName, contentRaw: contentHTML, contentText: contentText, contentHTML: contentHTML, contentImages: contentImages, additionalMetadate: null, }; } else { return publicChapter(); } } } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.sfacg = sfacg; /***/ }), /***/ "./src/rules/shouda8.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.shouda8 = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class shouda8 extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".bread-crumbs > li:nth-child(4)")).innerText.trim(); const author = (document.querySelector("div.bookname > h1 > em")).innerText .replace("作者:", "") .trim(); const introDom = document.querySelector(".intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { (0, misc_1.rm)(".book_keywords", false, introDom); (0, misc_1.rm)("script", true, introDom); (0, misc_1.rm)("#cambrian0", false, introDom); return introDom; }); const additionalMetadate = {}; const coverUrl = (document.querySelector(".pic > img:nth-child(1)")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const chapterList = document.querySelectorAll(".link_14 > dl dd a"); for (let i = 0; i < chapterList.length; i++) { const a = chapterList[i]; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, i + 1, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".kfyd > h2:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { (0, misc_1.rm)("p:last-child", false, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.shouda8 = shouda8; /***/ }), /***/ "./src/rules/shubaowa.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.shubaowa = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class shubaowa extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(); const author = (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(); const introDom = document.querySelector("#intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = document.querySelector("#fmimg > img") ?.src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const cos = document.querySelectorAll("#list > dl > dd > a"); let chapterNumber = 0; for (const aElem of Array.from(cos)) { chapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, false, null, null, null, this.chapterParse, this.charset, {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.shubaowa = shubaowa; /***/ }), /***/ "./src/rules/shubl.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.shubl = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class shubl extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; this.concurrencyLimit = 1; this.maxRunLimit = 1; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".book-title > span")).innerText.trim(); const author = (document.querySelector("div.username")).innerText.trim(); const introDom = document.querySelector(".book-brief"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { introDom.innerHTML = introDom.innerHTML.replace("简介:", ""); return introDom; }); const additionalMetadate = {}; const coverUrl = document.querySelector(".book-img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(document.querySelectorAll("div.row > span.tag")).map((span) => span.innerText.trim()); const chapters = []; const chapterTitleList = Array.from(document.querySelectorAll("#chapter_list > div.chapter > div.chapter-title")).map((div) => div.innerText.trim()); const articlesList = document.querySelectorAll("#chapter_list > div.chapter > div.articles"); const sectionLength = chapterTitleList.length; let chapterNumber = 0; for (let i = 0; i < sectionLength; i++) { const s = articlesList[i]; const sectionNumber = i + 1; const sectionName = chapterTitleList[i]; let sectionChapterNumber = 0; const cs = s.querySelectorAll("span.chapter_item"); for (let j = 0; j < cs.length; j++) { const c = cs[j]; chapterNumber++; sectionChapterNumber++; const a = c.querySelector("a"); if (a) { const chapterName = a.innerText.trim(); const chapterUrl = a.href; const isVIP = () => { if (c.childElementCount === 2) { return true; } return false; }; const isPaid = () => { if (isVIP() && c.querySelector("i")?.className === "unlock") { return true; } return false; }; const isLogin = () => { if (document.querySelector("#header > div.container > div.right.pull-right")?.childElementCount === 3) { return true; } return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); if (isVIP() && !(isLogin() && isPaid())) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function decrypt(item) { let message = item.content; let keys = item.keys; let len = item.keys.length; let accessKey = item.accessKey; let accessKeyList = accessKey.split(""); let charsNotLatinNum = accessKeyList.length; let output = new Array(); output.push(keys[accessKeyList[charsNotLatinNum - 1].charCodeAt(0) % len]); output.push(keys[accessKeyList[0].charCodeAt(0) % len]); for (let i = 0; i < output.length; i++) { message = atob(message); let data = output[i]; let iv = btoa(message.substr(0, 16)); let keys255 = btoa(message.substr(16)); let pass = CryptoJS.format.OpenSSL.parse(keys255); message = CryptoJS.AES.decrypt(pass, CryptoJS.enc.Base64.parse(data), { iv: CryptoJS.enc.Base64.parse(iv), format: CryptoJS.format.OpenSSL, }); if (i < output.length - 1) { message = message.toString(CryptoJS.enc.Base64); message = atob(message); } } return message.toString(CryptoJS.enc.Utf8); } const chapter_id = chapterUrl.split("/").slice(-1)[0]; const rootPath = "https://www.shubl.com/"; async function publicChapter() { async function chapterDecrypt(chapter_id, refererUrl) { const access_key_url = rootPath + "chapter/ajax_get_session_code"; const chapter_content_url = rootPath + "chapter/get_book_chapter_detail_info"; log_1.log.debug(`[Chapter]请求 ${access_key_url} Referer ${refererUrl}`); const access_key_obj = await (0, http_1.gfetch)(access_key_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Referer: refererUrl, Origin: document.location.origin, "X-Requested-With": "XMLHttpRequest", }, data: `chapter_id=${chapter_id}`, responseType: "json", }).then((response) => response.response); const chapter_access_key = access_key_obj .chapter_access_key; log_1.log.debug(`[Chapter]请求 ${chapter_content_url} Referer ${refererUrl}`); const chapter_content_obj = await (0, http_1.gfetch)(chapter_content_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Referer: refererUrl, Origin: document.location.origin, "X-Requested-With": "XMLHttpRequest", }, data: `chapter_id=${chapter_id}&chapter_access_key=${chapter_access_key}`, responseType: "json", }).then((response) => response.response); if (chapter_content_obj.code !== 100000) { log_1.log.error(chapter_content_obj); throw new Error(`下载 ${refererUrl} 失败`); } return decrypt({ content: chapter_content_obj.chapter_content, keys: chapter_content_obj.encryt_keys, accessKey: chapter_access_key, }); } let content = document.createElement("div"); let decryptDate = await chapterDecrypt(chapter_id, chapterUrl); content.innerHTML = decryptDate; (0, misc_1.rm)(".chapter span", true, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } async function vipChapter() { if (isPaid) { async function vipChapterDecrypt(chapter_id, refererUrl) { const parentWidth = 939.2; const setFontSize = "18"; const image_session_code_url = rootPath + "chapter/ajax_get_image_session_code"; log_1.log.debug(`[Chapter]请求 ${image_session_code_url} Referer ${refererUrl}`); const image_session_code_object = await (0, http_1.gfetch)(image_session_code_url, { method: "POST", headers: { Accept: "application/json, text/javascript, */*; q=0.01", Referer: refererUrl, Origin: document.location.origin, "X-Requested-With": "XMLHttpRequest", }, responseType: "json", }).then((response) => response.response); if (image_session_code_object.code !== 100000) { log_1.log.error(image_session_code_object); throw new Error(`下载 ${refererUrl} 失败`); } const imageCode = decrypt({ content: image_session_code_object .image_code, keys: image_session_code_object .encryt_keys, accessKey: image_session_code_object .access_key, }); const vipCHapterImageUrl = rootPath + "chapter/book_chapter_image?chapter_id=" + chapter_id + "&area_width=" + parentWidth + "&font=undefined" + "&font_size=" + setFontSize + "&image_code=" + imageCode + "&bg_color_name=white" + "&text_color_name=white"; return vipCHapterImageUrl; } const vipCHapterImageUrl = await vipChapterDecrypt(chapter_id, chapterUrl); log_1.log.debug(`[Chapter]请求 ${vipCHapterImageUrl} Referer ${chapterUrl}`); const vipCHapterImageBlob = await (0, http_1.gfetch)(vipCHapterImageUrl, { method: "GET", headers: { Referer: chapterUrl, Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", }, responseType: "blob", }).then((response) => response.response); const vipCHapterName = `vipCHapter${chapter_id}.png`; const vipCHapterImage = new main_1.attachmentClass(vipCHapterImageUrl, vipCHapterName, "TM"); if (vipCHapterImageBlob) { vipCHapterImage.imageBlob = vipCHapterImageBlob; vipCHapterImage.status = main_1.Status.finished; } const contentImages = [vipCHapterImage]; const img = document.createElement("img"); img.src = vipCHapterName; img.alt = vipCHapterImageUrl; const contentHTML = document.createElement("div"); contentHTML.appendChild(img); let contentText = `VIP章节,请打开HTML文件查看。\n![${vipCHapterImageUrl}](${vipCHapterName})`; return { chapterName: chapterName, contentRaw: contentHTML, contentText: contentText, contentHTML: contentHTML, contentImages: contentImages, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.shubl = shubl; /***/ }), /***/ "./src/rules/shuhai.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.shuhai = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class shuhai extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("div.book-info-bookname > span:nth-child(1)")).innerText.trim(); const author = (document.querySelector("div.book-info-bookname > span:nth-child(2)")).innerText .replace("作者: ", "") .trim(); const introDom = document.querySelector("div.book-info-bookintro") || document.querySelector("div.book-info-bookintro-all"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = (document.querySelector(".book-cover-wrapper > img")).getAttribute("data-original"); if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(document.querySelectorAll(".book-info-bookstate > .tag")).map((span) => span.innerText.trim()); const chapters = []; if (document.querySelectorAll("#catalog > .chapter-item").length === 0) { await (0, misc_1.sleep)(3000); } const dsList = document.querySelectorAll("#catalog > .chapter-item"); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < dsList.length; i++) { const node = dsList[i]; if (node.nodeName === "SPAN") { sectionNumber++; sectionChapterNumber = 0; sectionName = node?.innerText.trim(); } else if (node.nodeName === "DIV") { chapterNumber++; sectionChapterNumber++; const a = node.querySelector("a"); const isVIP = () => { if (node.childElementCount === 2) { return true; } else { return false; } }; const isPaid = () => { return false; }; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { const dom = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector("div.chapter-name")).innerText .replace("正文 ", "") .trim(); const content = (dom.querySelector("#reader-content > div:nth-child(1)")); if (content) { (0, misc_1.rm)("div.chaper-info", false, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.shuhai = shuhai; /***/ }), /***/ "./src/rules/simple/256wxc.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.c256wxc = void 0; const common_1 = __webpack_require__("./src/rules/lib/common.ts"); exports.c256wxc = (0, common_1.mkRuleClass1)({ bookUrl: document.location.href, bookname: (document.querySelector(".art_tit")).innerText.trim(), author: (document.querySelector("span.bookinfo:nth-child(1) > a")).innerText.trim(), introDom: document.querySelector(".infotype > p"), introDomPatch: (introDom) => introDom, coverUrl: null, cos: document.querySelectorAll(".catalog > li > a"), getContent: (doc) => doc.querySelector(".book_con"), contentPatch: (content) => content, }); /***/ }), /***/ "./src/rules/simple/630shu.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.c630shu = void 0; const common_1 = __webpack_require__("./src/rules/lib/common.ts"); exports.c630shu = (0, common_1.mkRuleClass1)({ bookUrl: document.location.href, bookname: (document.querySelector("#info > h1")).innerText.trim(), author: (document.querySelector("div.options > span.item:nth-child(1) > a")).innerText.trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector(".img_in > img").src, cos: document.querySelectorAll(".zjlist > dd > a"), getContent: (doc) => doc.querySelector("#content"), contentPatch: (content) => { content.innerHTML = content.innerHTML.replace(/恋上你看书网 WWW.630SHU.NET ,最快更新.+最新章节!/, ""); return content; }, }); /***/ }), /***/ "./src/rules/simple/trxs.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.tongrenquan = exports.trxs = void 0; const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const trxs = () => (0, common_1.mkRuleClass1)({ bookUrl: document.location.href, bookname: document.querySelector(".infos > h1").innerText .split("(")[0] .trim(), author: (document.querySelector(".date > span > a")).innerText.trim(), introDom: document.querySelector(".infos > p"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector(".pic > img").src, cos: document.querySelectorAll("div.book_list > ul.clearfix > li > a"), getContent: (doc) => doc.querySelector(".read_chapterDetail"), contentPatch: (content) => content, }); exports.trxs = trxs; const tongrenquan = () => (0, common_1.mkRuleClass1)({ bookUrl: document.location.href, bookname: document.querySelector(".infos > h1").innerText .split("(")[0] .trim(), author: (document.querySelector(".date > span")).innerText .replace("作者:", "") .trim(), introDom: document.querySelector(".infos > p"), introDomPatch: (introDom) => introDom, coverUrl: document.querySelector(".pic > img").src, cos: document.querySelectorAll("div.book_list > ul.clearfix > li > a"), getContent: (doc) => doc.querySelector(".read_chapterDetail"), contentPatch: (content) => content, }); exports.tongrenquan = tongrenquan; /***/ }), /***/ "./src/rules/sosadfun.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.sosadfun = void 0; const main_1 = __webpack_require__("./src/main.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); class sosadfun extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.origin + document.location.pathname; const bookname = (document.querySelector(".font-1")).innerText.trim(); const authorDom = (document.querySelector("div.h5:nth-child(1) > div:nth-child(1) > a:nth-child(1)")); let author; if (authorDom) { author = authorDom.innerText.trim(); } else { author = "匿名咸鱼"; } const needLogin = () => { const mainDom = document.querySelector(".col-xs-12 > .main-text.no-selection"); if (mainDom.innerText.trim() === "主楼隐藏,请登录后查看") { return true; } else { return false; } }; const additionalMetadate = {}; additionalMetadate.tags = Array.from(document.querySelectorAll("div.h5:nth-child(1) > div:nth-child(3) > a")).map((a) => a.innerText.trim()); let introduction; let introductionHTML; let introDom; if (needLogin()) { alert("本小说需要登录后浏览!"); throw new main_1.ExpectError("本小说需要登录后浏览!"); } else { introDom = document.createElement("div"); const shortIntroDom = document.querySelector("div.article-title div.h5"); const longIntroDom = document.querySelector(".col-xs-12 > .main-text.no-selection"); if (shortIntroDom) { const pElem = document.createElement("p"); pElem.innerText = shortIntroDom.innerText; introDom.appendChild(pElem); } if (longIntroDom) { for (const elem of Array.from(longIntroDom.cloneNode(true).children)) { introDom.appendChild(elem); } } } if (introDom === null) { introduction = null; introductionHTML = null; } else { let { dom: introCleanDom, text: introCleantext, images: introCleanimages, } = await (0, cleanDOM_1.cleanDOM)(introDom, "TM"); introduction = introCleantext; introductionHTML = introCleanDom; if (introCleanimages) { additionalMetadate.attachments = [...introCleanimages]; } } const chapters = []; const aList = document.querySelectorAll(".table > tbody:nth-child(2) > tr > th:nth-child(1) > a"); let chapterNumber = 0; for (const a of Array.from(aList)) { chapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, false, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (doc.querySelector("strong.h3")).innerText.trim(); const content = document.createElement("div"); const _content = (doc.querySelector(".main-text.no-selection > span[id^=full]")); const _authorSay = doc.querySelector(".main-text.no-selection > .grayout"); if (_content) { for (const elem of Array.from(_content.cloneNode(true).children)) { content.appendChild(elem); } } if (_content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); if (_authorSay) { let { dom: authorSayDom, text: authorySayText, images: authorSayImages, } = await (0, cleanDOM_1.cleanDOM)(_authorSay, "TM"); const hrElem = document.createElement("hr"); const authorSayDiv = document.createElement("div"); authorSayDiv.className = "authorSay"; for (const elem of Array.from(authorSayDom.cloneNode(true).children)) { authorSayDiv.appendChild(elem); } content.appendChild(hrElem); content.appendChild(authorSayDiv); dom.appendChild(hrElem); dom.appendChild(authorSayDiv); text = text + "\n\n" + "-".repeat(20) + "\n\n" + authorySayText; authorSayImages.forEach((aImage) => images.push(aImage)); } return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.sosadfun = sosadfun; /***/ }), /***/ "./src/rules/soxscc.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.soxscc = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class soxscc extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".xiaoshuo > h1")).innerText.trim(); const author = (document.querySelector(".xiaoshuo > h6:nth-child(3) > a")).innerText.trim(); const introDom = document.querySelector("#intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { (0, misc_1.rm)("span.tags", false, introDom); (0, misc_1.rm)("q", true, introDom); return introDom; }); const additionalMetadate = {}; const coverUrl = (document.querySelector(".book_cover > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const novel_list = document.querySelector("div.novel_list[id]"); const sections = Array.from(novel_list.children); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const section = sections[i]; const sectionName = section.querySelector("dt > b") ?.innerText; const cos = Array.from(section.querySelectorAll("dd > a")); let sectionChapterNumber = 0; for (const a of cos) { chapterNumber++; sectionChapterNumber++; const chapterUrl = a.href; const chapterName = a.innerText; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, i + 1, sectionChapterNumber, this.chapterParse, "UTF-8", { bookname: bookname }); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const bookname = options.bookname; chapterName = (doc.querySelector(".read_title > h1")).innerText.trim(); const content = doc.querySelector("div.content[id]"); if (content) { const ad = `您可以在百度里搜索“${bookname} .+(${document.location.hostname})”查找最新章节!`; content.innerHTML = content.innerHTML.replaceAll(ad, ""); Array.from(content.querySelectorAll("p")).forEach((p) => { const adwords = [ "最新章节地址:", "全文阅读地址:", "txt下载地址:", "手机阅读:", '为了方便下次阅读,你可以点击下方的"收藏"记录本次', "请向你的朋友(QQ、博客、微信等方式)推荐本书", ]; for (const adword of adwords) { if (p.innerText.includes(adword)) { p.remove(); } } }); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.soxscc = soxscc; /***/ }), /***/ "./src/rules/tadu.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.tadu = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_2 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class tadu extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { let bookUrl = document.location.href; const bookname = (document.querySelector("div.bookNm > a.bkNm")).innerText.trim(); const author = (document.querySelector("div.authorInfo > a.author > span")).innerText.trim(); const introDom = (document.querySelector("div.boxCenter.boxT.clearfix > div.lf.lfO > p.intro")); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (document.querySelector("a.bookImg > img")).getAttribute("data-src"); if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const cos = document.querySelectorAll("div.lf.lfT > li > div > a"); let chapterNumber = 0; for (const aElem of Array.from(cos)) { chapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const isVIP = () => { if (aElem.childElementCount) { return true; } else { return false; } }; const isPaid = () => { return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), null, null, null, this.chapterParse, "UTF-8", {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { log_1.log.debug(`[Chapter]请求 ${chapterUrl}`); const doc = await (0, http_2.getHtmlDOM)(chapterUrl, charset); const content = document.createElement("div"); const _bookPartResourceUrl = doc .getElementById("bookPartResourceUrl") ?.getAttribute("value"); if (_bookPartResourceUrl) { const bookPartResourceUrl = new URL(_bookPartResourceUrl); bookPartResourceUrl.searchParams.set("callback", "callback"); log_1.log.debug(`[Chapter]请求 ${bookPartResourceUrl.toString()}`); const jsonpText = await (0, http_1.gfetch)(bookPartResourceUrl.toString(), { headers: { accept: "*/*", Referer: document.location.origin, }, }).then((response) => { if (response.status >= 200 && response.status <= 299) { return response.responseText; } else { throw new Error(`Bad response! ${bookPartResourceUrl.toString()}`); } }); const callback = (obj) => { return obj; }; const contentObj = eval(jsonpText); if (typeof contentObj === "object") { content.innerHTML = contentObj.content; let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } } return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.tadu = tadu; /***/ }), /***/ "./src/rules/ujxs.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ujxs = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class ujxs extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.origin + document.location.pathname.replace(/^\/read/, "/book"); const bookname = (document.querySelector("#smallcons > h1")).innerText.trim(); const author = (document.querySelector("#smallcons > span:nth-child(3) > a")).innerText.trim(); const doc = await (0, http_1.getHtmlDOM)(bookUrl, this.charset); const introDom = doc.querySelector("#bookintro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = doc.querySelector(".img > img")?.src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const liList = document.querySelectorAll("#readerlist > ul > li"); const chapters = []; let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < liList.length; i++) { const li = liList[i]; if (li.getAttribute("class")) { sectionNumber++; sectionChapterNumber = 0; sectionName = li.querySelector("h3")?.innerText.replace(bookname, "").trim() ?? null; } else { const aElem = li.firstElementChild; chapterNumber++; sectionChapterNumber++; const chapterName = aElem.innerText; const chapterUrl = aElem.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, { bookname: bookname }); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = doc.querySelector(".read-content"); if (content) { (0, misc_1.rm)("script", true, content); const ads = [ "【悠久小説網ωωω.UJХS.net】,免费小说无弹窗免费阅读!", "佰度搜索 【悠久小說網 WWW.UJХS.NET】 全集TXT电子书免费下载!", ]; ads.forEach((ad) => (content.innerHTML = content.innerHTML.replaceAll(ad, ""))); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.ujxs = ujxs; /***/ }), /***/ "./src/rules/uukanshu.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.uukanshu = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class uukanshu extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("dd.jieshao_content > h1 > a")).innerText .replace("最新章节", "") .trim(); const author = (document.querySelector("dd.jieshao_content > h2 > a")).innerText.trim(); const introDom = (document.querySelector("dd.jieshao_content > h3")); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { introDom.innerHTML = introDom.innerHTML .replace(/^.+简介:\s+www.uukanshu.com\s+/, "") .replace(/\s+https:\/\/www.uukanshu.com/, "") .replace(/-+/, ""); return introDom; }); const additionalMetadate = {}; const coverUrl = (document.querySelector("a.bookImg > img")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const button = (document.querySelector('span[onclick="javascript:reverse(this);"]')); const reverse = unsafeWindow.reverse; if (button.innerText === "顺序排列") { reverse(button); } const chapterList = (document.getElementById("chapterList")?.childNodes); if (chapterList && chapterList.length !== 0) { let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const li = chapterList[i]; if (li.className === "volume") { sectionNumber++; sectionChapterNumber = 0; sectionName = li.innerText; } else { chapterNumber++; sectionChapterNumber++; const a = li.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = dom.querySelector("#timu").innerText.trim(); const content = dom.querySelector("#contentbox"); if (content) { (0, misc_1.rm)(".ad_content", true, content); const contentReplace = [ /[UuUu]+看书\s*[ww]+.[UuUu]+[kk][aa][nn][ss][hh][UuUu].[nn][ee][tt]/g, /[UuUu]+看书\s*[ww]+.[UuUu]+[kk][aa][nn][ss][hh][UuUu].[cCc][oOo][mMm]/g, /[UU]*看书[(\\(].*?[)\\)]文字首发。/, /请记住本书首发域名:。?/g, /笔趣阁手机版阅读网址:/g, /小说网手机版阅读网址:/g, /https:\/\//g, /http:\/\//g, /UU看书\s+欢迎广大书友光临阅读,最新、最快、最火的连载作品尽在UU看书!UU看书。;?/g, ]; for (let r of contentReplace) { content.innerHTML = content.innerHTML.replace(r, ""); } let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.uukanshu = uukanshu; /***/ }), /***/ "./src/rules/wenku8.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.wenku8 = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class wenku8 extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; } async bookParse() { const bookId = document.location.pathname.split("/").slice(-2, -1)[0]; const bookUrl = [document.location.origin, "book", `${bookId}.htm`].join("/"); const bookname = (document.querySelector("#title")).innerText.trim(); const doc = await (0, http_1.getHtmlDOM)(bookUrl, "GBK"); const author = (doc.querySelector("#content > div:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2)")).innerText .replace("小说作者:", "") .trim(); const introDom = doc.querySelector("#content > div:nth-child(1) > table:nth-child(4) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > span:nth-child(11)"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = (doc.querySelector("#content > div:nth-child(1) > table:nth-child(4) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > img:nth-child(1)")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const tdList = Array.from(document.querySelectorAll(".css > tbody td")).filter((td) => td.innerText.trim()); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < tdList.length; i++) { const td = tdList[i]; if (td.className === "vcss") { sectionNumber++; sectionChapterNumber = 0; sectionName = td.innerText.trim(); } else if (td.className === "ccss") { chapterNumber++; sectionChapterNumber++; const a = td.firstElementChild; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, false, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = doc.querySelector("#content"); if (content) { (0, misc_1.rm)("#contentdp", true, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.wenku8 = wenku8; /***/ }), /***/ "./src/rules/westnovel.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.westnovel = void 0; const main_1 = __webpack_require__("./src/main.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class westnovel extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector(".btitle > h1 > a")).innerText.trim(); const author = (document.querySelector(".btitle > em:nth-child(2)")).innerText .replace("作者:", "") .trim(); const introDom = document.querySelector(".intro-p > p:nth-child(1)"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = document.querySelector(".img-img").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const aList = document.querySelectorAll(".chapterlist > dd > a"); let chapterNumber = 0; for (const a of Array.from(aList)) { chapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, false, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (doc.querySelector("#BookCon > h1:nth-child(1)")).innerText.trim(); const content = doc.querySelector("#BookText"); if (content) { (0, misc_1.rm)("div.ads", true, content); (0, misc_1.rm)("div.link", true, content); (0, misc_1.rm)("h4", true, content); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.westnovel = westnovel; /***/ }), /***/ "./src/rules/xiaoshuodaquan.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.xiaoshuodaquan = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class xiaoshuodaquan extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "GBK"; this.concurrencyLimit = 5; } async bookParse() { const ccount = document.querySelector(".crumbswrap")?.childElementCount; let bookUrl = document.location.href; if (ccount) { bookUrl = (document.querySelector(`.crumbswrap > a:nth-child(${ccount - 2})`)).href; } const bookname = (document.querySelector("div.dirwraps > h1")).innerText .replace("《", "") .replace("》", "") .trim(); const author = (document.querySelector(".smallcons > span:nth-child(1) > a:nth-child(1)")).innerText.trim(); const introDom = document.querySelector(".bookintro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { introDom.innerHTML = introDom.innerHTML.replace("内容简介:", ""); return introDom; }); const additionalMetadate = {}; let coverUrl; if (ccount) { const dom = await (0, http_1.getHtmlDOM)(bookUrl, "GBK"); coverUrl = dom.querySelector(".con_limg > img").src; } if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const sectionNames = document.querySelectorAll(".dirwraps > div.dirtitone"); const sections = document.querySelectorAll(".dirwraps > div.clearfix.dirconone"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const sectionNameObj = sectionNames[i]; const sectionObj = sections[i]; const sectionNumber = i + 1; const sectionName = (sectionNameObj.firstElementChild)?.innerText .replace(bookname, "") .trim(); let sectionChapterNumber = 0; const cos = sectionObj.querySelectorAll("ul>li>a"); for (let j = 0; j < cos.length; j++) { chapterNumber++; sectionChapterNumber++; const a = cos[j]; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".page-body > h1:nth-child(4)")).innerText.trim(); const _content = dom.querySelector("#content"); if (_content) { (0, misc_1.rm)("div", true, _content); (0, misc_1.rm)("script", true, _content); const content = document.createElement("div"); content.innerHTML = _content.innerHTML.replace(/\n/g, "
"); let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.xiaoshuodaquan = xiaoshuodaquan; /***/ }), /***/ "./src/rules/xinwanben.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.xinwanben = void 0; const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const biquge_1 = __webpack_require__("./src/rules/biquge.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class xinwanben extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const self = this; return (0, biquge_1.bookParseTemp)({ bookUrl: document.location.href, bookname: (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(), author: (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(), introDom: document.querySelector("#intro"), introDomPatch: (introDom) => { const _bookname = introDom.innerHTML.match(/《(.*)》/); let bookname; if (_bookname?.length === 2) { bookname = _bookname[1]; } introDom.querySelectorAll("p").forEach((p) => { const adList = [ "还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!", "小说免费阅读地址:", ]; for (const ad of adList) { if (p.innerText.includes(ad)) { p.remove(); } } }); introDom.innerHTML = introDom.innerHTML.replace(`${bookname}小说简介:`, ""); return introDom; }, coverUrl: document.querySelector("#fmimg > img").src, chapterListSelector: "div.box_con:nth-child(5) > div:nth-child(2) > dl:nth-child(1)", charset: "UTF-8", chapterParse: self.chapterParse, }); } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { return (0, common_1.nextPageParse)(chapterName, chapterUrl, charset, "#content", (_content, doc) => { (0, cleanDOM_1.htmlTrim)(_content); return _content; }, (doc) => doc.querySelector("#next_url").href, (_content, nextLink) => nextLink.includes("_")); } } exports.xinwanben = xinwanben; /***/ }), /***/ "./src/rules/xkzw.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.xkzw = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const log_1 = __webpack_require__("./src/log.ts"); class xkzw extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(); const author = (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(); const introDom = document.querySelector("#intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = document.querySelector("#fmimg > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const bookid = unsafeWindow.bookId; const apiUrl = [document.location.origin, "action.php"].join("/"); log_1.log.debug(`[chapter]正在请求${apiUrl}`); const siteChapterList = await fetch(apiUrl, { headers: { accept: "application/json, text/javascript, */*", "content-type": "application/x-www-form-urlencoded", "x-requested-with": "XMLHttpRequest", }, body: `action=clist&bookid=${bookid}`, method: "POST", mode: "cors", credentials: "include", }).then((response) => response.json()); const dl1 = document.querySelector("#wrapper > div.box_con:nth-child(7) > div:nth-child(1) > dl:nth-child(1)"); const dl2 = document.querySelector("#wrapper > div.box_con:nth-child(11) > div:nth-child(1) > dl:nth-child(1)"); const mkList = (dl) => { let tmpColumnName = ""; let tmpColumnList = []; let tmpChapterList = []; if (dl?.childElementCount) { const dlc = Array.from(dl.children); for (let i = 0; i < dl.childElementCount; i++) { const node = dlc[i]; if (i !== 0) { if (node.nodeName === "DD") { const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const chapterid = chapterUrl .split("/") .slice(-1)[0] .replace(".html", ""); tmpChapterList.push({ chapterid: Number(chapterid) - bookid * 11, chaptername: chapterName, isempty: 0, originalurl: "", currenturl: "", }); } else if (node.nodeName === "DT") { const tmpColumnObj = { columnname: tmpColumnName, columnid: 0, chapterlist: tmpChapterList, }; tmpColumnList.push(tmpColumnObj); tmpColumnName = node.innerText .replace(`《${bookname}》`, "") .trim(); tmpChapterList = []; } } else { tmpColumnName = node.innerText .replace(`《${bookname}》`, "") .trim(); } } } return [tmpColumnList, tmpChapterList]; }; const [tmpColumnList, tmpChapterList] = mkList(dl1); const tcl = tmpChapterList.length; for (let i = 0; i < tcl; i++) { const tmpChapterObject = tmpChapterList.pop(); if (tmpChapterObject) { siteChapterList.columnlist[0].chapterlist.unshift(tmpChapterObject); } } if (tmpColumnList.length !== 0) { const tmpColumnListLenght = tmpColumnList.length; for (let i = 0; i < tmpColumnListLenght; i++) { const tmpColumnObject = tmpColumnList.pop(); if (tmpColumnObject) { siteChapterList.columnlist.unshift(tmpColumnObject); } } } const [tmpColumnList1, tmpChapterList1] = mkList(dl2); const tcl1 = tmpChapterList1.length; const cll = siteChapterList.columnlist.length; for (let i = 0; i < tcl1; i++) { const tmpChapterObject = tmpChapterList1.shift(); if (tmpChapterObject) { siteChapterList.columnlist[cll - 1].chapterlist.push(tmpChapterObject); } } if (tmpColumnList1.length !== 0) { const tmpColumnListLenght = tmpColumnList1.length; for (let i = 0; i < tmpColumnListLenght; i++) { const tmpColumnObject = tmpColumnList1.shift(); if (tmpColumnObject) { siteChapterList.columnlist.push(tmpColumnObject); } } } let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (const column of siteChapterList.columnlist) { sectionNumber++; sectionName = column.columnname; for (const sitechapter of column.chapterlist) { chapterNumber++; sectionChapterNumber++; const chapterName = sitechapter.chaptername; const chapterUrl = bookUrl + (sitechapter.chapterid + bookid * 11) + ".html"; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function runEval(CryptoJS) { function gettt1(str, keyStr, ivStr) { let key = CryptoJS.enc.Utf8.parse(keyStr); let iv = CryptoJS.enc.Utf8.parse(ivStr); let encryptedHexStr = CryptoJS.enc.Hex.parse(str); let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); let decrypt = CryptoJS.DES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function gettt2(str, keyStr, ivStr) { let key = CryptoJS.enc.Utf8.parse(keyStr); let iv = CryptoJS.enc.Utf8.parse(ivStr); let encryptedHexStr = CryptoJS.enc.Hex.parse(str); let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function gettt3(str, keyStr, ivStr) { let key = CryptoJS.enc.Utf8.parse(keyStr); let iv = CryptoJS.enc.Utf8.parse(ivStr); let encryptedHexStr = CryptoJS.enc.Hex.parse(str); let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); let decrypt = CryptoJS.RC4.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function getttn(str, keyStr, ivStr) { let key = CryptoJS.enc.Utf8.parse(keyStr); let iv = CryptoJS.enc.Utf8.parse(ivStr); let encryptedHexStr = CryptoJS.enc.Hex.parse(str); let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); let decrypt = CryptoJS.TripleDES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function showttt1(dom) { let obj = dom.getElementById("other"); let objTips = dom.getElementById("contenttips"); if (obj) { let content = obj.innerHTML.trim(); let type = parseInt(content.substring(0, 1)); let key; let iv; if (type === 1) { key = content.substring(1, 9); iv = content.substring(9, 17); content = content.substring(17); obj.innerHTML = gettt1(content, key, iv); obj.style.display = "block"; if (objTips) { objTips.remove(); } } else if (type === 2) { key = content.substring(1, 33); iv = content.substring(33, 49); content = content.substring(49); obj.innerHTML = gettt2(content, key, iv); obj.style.display = "block"; if (objTips) { objTips.remove(); } } else if (type === 3) { key = content.substring(1, 9); iv = content.substring(9, 17); content = content.substring(17); obj.innerHTML = gettt3(content, key, iv); obj.style.display = "block"; if (objTips) { objTips.remove(); } } else { key = content.substring(1, 25); iv = content.substring(25, 33); content = content.substring(33); obj.innerHTML = getttn(content, key, iv); obj.style.display = "block"; if (objTips) { objTips.remove(); } } } } showttt1(dom); } const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); runEval(CryptoJS); chapterName = (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.xkzw = xkzw; /***/ }), /***/ "./src/rules/yibige.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.yibige = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class yibige extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = (document.querySelector("#list_hb > li:nth-child(2) > a:nth-child(1)")).href; const doc = await (0, http_1.getHtmlDOM)(bookUrl, undefined); const bookname = (doc.querySelector(".title > h1:nth-child(1)")).innerText.trim(); const author = (doc.querySelector("div.xsxq_2:nth-child(2) > a:nth-child(1)")).innerText.trim(); const introDom = document.createElement("p"); const _introDom = doc.querySelector(".nr"); for (const node of Array.from(_introDom.childNodes)) { if (node.nodeName.toLowerCase() === "#text" && node.textContent?.trim() === "相关:") { break; } introDom.appendChild(node.cloneNode(true)); } const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = (doc.querySelector(".limg > img:nth-child(1)")).src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const dl = document.querySelector(".books_li"); if (dl?.childElementCount) { const dlc = Array.from(dl.children); if (dlc[0].nodeName === "DT" && dlc[0].innerText.includes("最新12章节")) { for (let i = 0; i < dl?.childElementCount; i++) { if (i !== 0 && dlc[i].nodeName === "DT") { delete dlc[0]; break; } delete dlc[i]; } } const chapterList = dlc.filter((obj) => obj !== undefined && obj.getAttribute("style") === null); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; if (node.nodeName === "DT") { sectionNumber++; sectionChapterNumber = 0; sectionName = node.innerText.replace(`《${bookname}》`, "").trim(); } else if (node.nodeName === "DD") { if (node.childElementCount === 0) { continue; } chapterNumber++; sectionChapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", { bookname: bookname }); chapters.push(chapter); } } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { return (0, common_1.nextPageParse)(chapterName, chapterUrl, charset, "#fontsize", (_content, doc) => { (0, misc_1.rm)("div", true, _content); (0, misc_1.rm)("script", true, _content); _content.innerHTML = _content.innerHTML .replaceAll("测试广告1", "") .replaceAll("测试广告2", ""); return _content; }, (doc) => doc.querySelector(".nr_fy > a:nth-child(4)").href, (_content, nextLink) => new URL(nextLink).pathname.includes("_")); } } exports.yibige = yibige; /***/ }), /***/ "./src/rules/yruan.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.yrun = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class yrun extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 1; } async bookParse() { const bookUrl = document.location.href; const bookname = (document.querySelector("#info > h1:nth-child(1)")).innerText.trim(); const author = (document.querySelector("#info > p:nth-child(2)")).innerText .replace(/作(\s+)?者[::]/, "") .trim(); const introDom = document.querySelector("#intro > p"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; const coverUrl = document.querySelector("#fmimg > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } const chapters = []; const chapterList = document.querySelectorAll("#list>dl>dd>a"); if (chapterList && chapterList.length !== 0) { for (let i = 0; i < chapterList.length; i++) { const a = chapterList[i]; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, i, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { const dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = (dom.querySelector(".bookname > h1:nth-child(1)")).innerText.trim(); const content = dom.querySelector("#content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.yrun = yrun; /***/ }), /***/ "./src/rules/yuzhaige.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.yuzhaige = void 0; const main_1 = __webpack_require__("./src/main.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); const yuzhaigeImageDecode_1 = __webpack_require__("./src/rules/lib/yuzhaigeImageDecode.ts"); const log_1 = __webpack_require__("./src/log.ts"); class yuzhaige extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; } async bookParse() { const bookUrl = (document.querySelector("div.currency_head > h1 > a")).href; const bookId = bookUrl.split("/").slice(-2, -1)[0]; log_1.log.debug(`[chapter]请求 ${bookUrl}`); const dom = await (0, http_1.getHtmlDOM)(bookUrl, "UTF-8"); const bookname = (dom.querySelector("div.cataloginfo > h3")).innerText.trim(); const author = (dom.querySelector(".infotype > p:nth-child(1) > a:nth-child(1)")).innerText.trim(); const introDom = dom.querySelector(".intro"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom, (introDom) => { (0, misc_1.rm)("span:nth-child(1)", false, introDom); return introDom; }); const additionalMetadate = {}; const chapters = []; const getMaxPageNumber = () => { const pageDom = document.querySelector("div.page:nth-child(6)"); if (pageDom) { const childNodes = Array.from(pageDom.childNodes); const _maxPageNumber = childNodes .slice(-1)[0] .textContent?.match(/第\d+\/(\d+)页/); if (_maxPageNumber) { return _maxPageNumber[1]; } } }; const getIndexUrls = () => { const indexUrls = []; const maxPageNumber = Number(getMaxPageNumber()); for (let i = 1; i <= maxPageNumber; i++) { const indexUrl = [ document.location.origin, document.location.pathname.split("/")[1], `${bookId}_${i}`, ].join("/") + "/"; indexUrls.push(indexUrl); } return indexUrls; }; const indexUrls = getIndexUrls(); let lis = []; for (const indexUrl of indexUrls) { log_1.log.debug(`[chapter]请求 ${indexUrl}`); const dom = await (0, http_1.getHtmlDOM)(indexUrl, "UTF-8"); const ul = dom.querySelector("ul.chapters"); if (ul?.childElementCount) { lis = lis.concat(Array.from(ul.children)); } } const chapterList = lis.filter((obj) => obj !== undefined); let chapterNumber = 0; for (let i = 0; i < chapterList.length; i++) { const node = chapterList[i]; chapterNumber++; const a = node.firstElementChild; const chapterName = a.innerText; const chapterUrl = a.href; const isVIP = false; const isPaid = false; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP, isPaid, null, null, null, this.chapterParse, "UTF-8", {}); chapters.push(chapter); } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { function contentAppend() { function UpWz(m, i) { let k = Math.ceil((i + 1) % code); k = Math.ceil(m - k); return k; } const _e = dom.getElementsByTagName("meta")[7].getAttribute("content"); const contentRaw = dom.querySelector("#articlecontent"); let codeurl; let code; const _codeurl = dom .getElementsByTagName("script")[1] .innerText.trim() .match(/"(http.+)"/); if (_codeurl) { codeurl = _codeurl[1]; code = Number(new URL(codeurl).searchParams.get("code")); } if (_e) { const e = atob(_e) .split(/[A-Z]+%/) .map((v) => Number(v)); let childNode = []; if (Array.from(dom.querySelectorAll("script")).filter((s) => s.src.includes("/17mb/js/article.js")).length) { for (let i = 0; i < e.length; i++) { let k = UpWz(e[i], i); childNode[k] = contentRaw.childNodes[i]; } for (const node of childNode) { if (node.nodeType != 1) { continue; } if (!(node.innerText.includes("本章尚未完结,请") || node.innerText.includes("本章已阅读完毕"))) { content.appendChild(node); } } return; } } for (const node of Array.from(contentRaw.childNodes)) { if (!(node.innerText.includes("本章尚未完结,请") || node.innerText.includes("本章已阅读完毕"))) { content.appendChild(node); } } return; } let nowUrl = chapterUrl; let dom = await (0, http_1.getHtmlDOM)(chapterUrl, charset); const content = document.createElement("div"); let flag = false; do { contentAppend(); const nextLink = (dom.querySelector(".novelbutton .p1.p3 > a:nth-child(1)")).href; if (new URL(nextLink).pathname.includes("_")) { if (nextLink !== nowUrl) { flag = true; } else { log_1.log.error("网站页面出错,URL: " + nowUrl); flag = false; } } else { flag = false; } if (flag) { nowUrl = nextLink; dom = await (0, http_1.getHtmlDOM)(nextLink, charset); } } while (flag); if (content) { let { dom: oldDom, text: _text, images: finalImages, } = await (0, cleanDOM_1.cleanDOM)(content, "TM", { keepImageName: true }); const _newDom = document.createElement("div"); _newDom.innerHTML = (0, yuzhaigeImageDecode_1.replaceYuzhaigeImage)(content.innerHTML); let { dom: newDom, text: finalText, images, } = await (0, cleanDOM_1.cleanDOM)(_newDom, "TM", { keepImageName: true }); const fontStyleDom = document.createElement("style"); fontStyleDom.innerHTML = `.hide { display: none; }`; oldDom.className = "hide"; const finalDom = document.createElement("div"); finalDom.appendChild(fontStyleDom); finalDom.appendChild(oldDom); finalDom.appendChild(newDom); return { chapterName: chapterName, contentRaw: content, contentText: finalText, contentHTML: finalDom, contentImages: finalImages, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } } exports.yuzhaige = yuzhaige; /***/ }), /***/ "./src/rules/zongheng.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.zongheng = void 0; const main_1 = __webpack_require__("./src/main.ts"); const cleanDOM_1 = __webpack_require__("./src/lib/cleanDOM.ts"); const attachments_1 = __webpack_require__("./src/lib/attachments.ts"); const http_1 = __webpack_require__("./src/lib/http.ts"); const rules_1 = __webpack_require__("./src/rules.ts"); const common_1 = __webpack_require__("./src/rules/lib/common.ts"); class zongheng extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.concurrencyLimit = 5; } async bookParse() { const bookUrl = document.location.href.replace("/showchapter/", "/book/"); const bookname = (document.querySelector("div.book-meta > h1")).innerText.trim(); const author = (document.querySelector("div.book-meta > p > span:nth-child(1) > a")).innerText.trim(); const doc = await (0, http_1.getHtmlDOM)(bookUrl, undefined); const introDom = doc.querySelector("div.book-info > div.book-dec"); const [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); const additionalMetadate = {}; let coverUrl = doc.querySelector("div.book-img > img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-").then((coverClass) => { additionalMetadate.cover = coverClass; }); } additionalMetadate.tags = Array.from(doc.querySelectorAll(".book-info>.book-label a")).map((a) => a.innerText.trim()); const chapters = []; const sections = document.querySelectorAll(".volume-list"); let chapterNumber = 0; for (let i = 0; i < sections.length; i++) { const s = sections[i]; const sectionNumber = i + 1; const sectionLabel = s.querySelector("div.volume"); Array.from(sectionLabel.children).forEach((ele) => ele.remove()); const sectionName = sectionLabel.innerText.trim(); let sectionChapterNumber = 0; const cs = s.querySelectorAll("ul.chapter-list > li"); for (let j = 0; j < cs.length; j++) { const c = cs[j]; const a = c.querySelector("a"); chapterNumber++; sectionChapterNumber++; const chapterName = a.innerText.trim(); const chapterUrl = a.href; const isVIP = () => { if (c.className.includes("vip")) { return true; } else { return false; } }; const isPaid = () => { return false; }; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, isVIP(), isPaid(), sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, "UTF-8", {}); const isLogin = () => { return false; }; if (isVIP() && !(isLogin() && chapter.isPaid)) { chapter.status = main_1.Status.aborted; } chapters.push(chapter); } } const book = new main_1.Book(bookUrl, bookname, author, introduction, introductionHTML, additionalMetadate, chapters); return book; } async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) { async function publicChapter() { const dom = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset); const chapterName = (dom.querySelector("div.title_txtbox")).innerText.trim(); const content = dom.querySelector("div.content"); if (content) { let { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName: chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName: chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.zongheng = zongheng; /***/ }), /***/ "./src/save.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getSaveBookObj = exports.saveOptionsValidate = exports.saveBook = void 0; const main_1 = __webpack_require__("./src/main.ts"); const zip_1 = __webpack_require__("./src/lib/zip.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const log_1 = __webpack_require__("./src/log.ts"); class saveBook { constructor(book) { this.book = book; this.chapters = book.chapters; this.chapters.sort(this.chapterSort); this.savedZip = new zip_1.fflateZip(); this._sections = []; this._savedChapters = []; this.savedTextArray = []; this.saveFileNameBase = `[${this.book.author}]${this.book.bookname}`; this.mainStyleText = `body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div.main { width: 900px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0, 0, 0, 0.02); } @media (max-width: 700px) { div.main { margin: 0 auto; width: auto; } } h1 { line-height: 130%; text-align: center; font-weight: bold; font-size: xxx-large; margin-top: 3.2em; margin-bottom: 3.3em; } h2 { line-height: 130%; text-align: center; font-weight: bold; font-size: x-large; margin-top: 1.2em; margin-bottom: 2.3em; } div { margin: 0px; padding: 0px; text-align: justify; } p { text-indent: 2em; display: block; line-height: 1.3em; margin-top: 0.4em; margin-bottom: 0.4em; } img { vertical-align: text-bottom; max-width: 90%; } .title { margin-bottom: 0.7em; } .author { text-align: center; }`; this.tocStyleText = `img { max-width: 100%; max-height: 15em; } .introduction { font-size: smaller; max-height: 18em; overflow-y: scroll; } .introduction p { text-indent: 0; } .bookurl { text-align: center; font-size: smaller; padding-top: 1em; padding-bottom: 0.5em; margin-top: 0.4em; } .bookurl > a { color: gray; } .info { display: grid; grid-template-columns: 30% 70%; } .info h3 { padding-left: 0.5em; margin-top: -1.2em; margin-bottom: 0.5em; } .section { margin-top: 1.5em; display: grid; grid-template-columns: 30% 30% 30%; } .section > h2:first-child { grid-column-end: span 3; } .section > .chapter { padding-bottom: 0.3em; text-align: center; } .main > h1 { margin-top: 1.5em; margin-bottom: 1.5em; } a.disabled { pointer-events: none; cursor: default; color: gray; } .author::before { content: "作者:"; } .author { text-align: center; margin-top: -3em; margin-bottom: 3em; }`; } saveTxt() { const metaDateText = this.genMetaDateTxt(); this.savedTextArray.push(metaDateText); let sections = []; for (const chapter of this.chapters) { const chapterName = this.getchapterName(chapter); if (chapter.sectionName && !sections.includes(chapter.sectionName)) { sections.push(chapter.sectionName); const sectionText = this.genSectionText(chapter.sectionName); this.savedTextArray.push(sectionText); } if (chapter.contentText) { const chapterText = this.genChapterText(chapterName, chapter.contentText); this.savedTextArray.push(chapterText); } if (!setting_1.enaleDebug) { chapter.contentText = null; } } log_1.log.info("[save]保存TXT文件"); const savedText = this.savedTextArray.join("\n").replaceAll("\n", "\r\n"); saveAs(new Blob([savedText], { type: "text/plain;charset=utf-8" }), `${this.saveFileNameBase}.txt`); } saveLog() { this.savedZip.file("debug.log", new Blob([log_1.logText], { type: "text/plain; charset=UTF-8" })); } saveZip(runSaveChapters = false) { log_1.log.debug("[save]保存元数据文本"); const metaDateText = this.genMetaDateTxt(); this.savedZip.file("info.txt", new Blob([metaDateText], { type: "text/plain;charset=utf-8" })); log_1.log.debug("[save]保存样式"); this.savedZip.file("style.css", new Blob([this.mainStyleText], { type: "text/css;charset=utf-8" })); if (this.book.additionalMetadate.cover) { log_1.log.debug("[save]保存封面"); this.addImageToZip(this.book.additionalMetadate.cover, this.savedZip); } if (this.book.additionalMetadate.attachments) { log_1.log.debug("[save]保存书籍附件"); for (const bookAttachment of this.book.additionalMetadate.attachments) { this.addImageToZip(bookAttachment, this.savedZip); } } if (runSaveChapters) { log_1.log.debug("[save]开始保存章节文件"); this.saveChapters(); } log_1.log.debug("[save]开始生成并保存ToC.html"); this.saveToC(); log_1.log.info("[save]开始保存ZIP文件"); const self = this; self.saveLog(); return new Promise((resolve, reject) => { const finalHandle = (blob) => { saveAs(blob, `${self.saveFileNameBase}.zip`); resolve(); }; const finalErrorHandle = (err) => { log_1.log.error("saveZip: " + err); log_1.log.trace(err); reject(err); }; this.savedZip.onFinal = finalHandle; this.savedZip.onFinalError = finalErrorHandle; this.savedZip.generateAsync((percent) => { const progress = window.progress; if (progress) { progress.zipPercent = percent; } }); }); } saveToC() { const ToC = new DOMParser().parseFromString(`${this.book.bookname}

${this.book.bookname}

${this.book.author}

`, "text/html"); const TocMain = ToC.querySelector("div.main"); log_1.log.debug("[save]生成ToC模板"); const infoDom = document.createElement("div"); infoDom.className = "info"; if (this.book.additionalMetadate.cover) { const coverDom = document.createElement("img"); coverDom.className = "cover"; coverDom.setAttribute("data-src-address", this.book.additionalMetadate.cover.name); infoDom.appendChild(coverDom); } if (this.book.introductionHTML) { const divElem = document.createElement("div"); const h3Elem = document.createElement("h3"); h3Elem.innerText = "简介"; const introDom = document.createElement("div"); introDom.className = "introduction"; introDom.innerHTML = this.book.introductionHTML.innerHTML; divElem.appendChild(h3Elem); divElem.appendChild(introDom); infoDom.appendChild(divElem); } TocMain?.appendChild(infoDom); const bookUrlDom = document.createElement("div"); bookUrlDom.className = "bookurl"; const bookUrlAnchor = document.createElement("a"); bookUrlAnchor.href = this.book.bookUrl; bookUrlAnchor.innerText = "打开原始网站"; bookUrlDom.appendChild(bookUrlAnchor); TocMain?.appendChild(bookUrlDom); const hr = document.createElement("hr"); TocMain?.appendChild(hr); const tocStyle = document.createElement("style"); tocStyle.innerHTML = this.tocStyleText; ToC.head.appendChild(tocStyle); let sections = []; for (const chapter of this.chapters) { const chapterName = this.getchapterName(chapter); const htmlfileNameBase = `${"0".repeat(this.chapters.length.toString().length - chapter.chapterNumber.toString().length)}${chapter.chapterNumber.toString()}.html`; const chapterHtmlFileName = `Chapter${htmlfileNameBase}`; if (chapter.sectionName) { const sectionHtmlId = `section${chapter.sectionNumber}`; if (!sections.includes(chapter.sectionName)) { sections.push(chapter.sectionName); log_1.log.debug(`[save]生成卷DOM:${chapter.sectionName}`); const sectionDiv = document.createElement("div"); sectionDiv.id = sectionHtmlId; sectionDiv.className = "section"; const heading = document.createElement("h2"); heading.className = "section-label"; heading.innerHTML = chapter.sectionName; sectionDiv.appendChild(heading); if (sections.length !== 1) { const hr = document.createElement("hr"); TocMain?.appendChild(hr); } TocMain?.appendChild(sectionDiv); } log_1.log.debug(`[save]生成章DOM:${chapterName}`); const sectionDiv = TocMain?.querySelector("#" + sectionHtmlId); const chapterDiv = document.createElement("div"); chapterDiv.className = "chapter"; const chapterAnchor = document.createElement("a"); chapterAnchor.href = chapterHtmlFileName; chapterAnchor.innerHTML = chapterName; if (!(chapter.contentHTML || chapter.status === main_1.Status.saved)) { chapterAnchor.classList.add("disabled"); } chapterDiv.appendChild(chapterAnchor); sectionDiv?.appendChild(chapterDiv); } else { let sectionDiv; if (TocMain?.querySelector("#section00")) { sectionDiv = TocMain?.querySelector("#section00"); } else { sectionDiv = document.createElement("div"); sectionDiv.id = "section00"; sectionDiv.className = "section"; TocMain?.appendChild(sectionDiv); } const chapterDiv = document.createElement("div"); chapterDiv.className = "chapter"; const chapterAnchor = document.createElement("a"); chapterAnchor.href = chapterHtmlFileName; chapterAnchor.innerHTML = chapterName; if (!(chapter.contentHTML || chapter.status === main_1.Status.saved)) { chapterAnchor.classList.add("disabled"); } chapterDiv.appendChild(chapterAnchor); sectionDiv?.appendChild(chapterDiv); } } log_1.log.debug("[save]保存ToC文件"); this.savedZip.file("index.html", new Blob([ToC.documentElement.outerHTML.replaceAll("data-src-address", "src")], { type: "text/html; charset=UTF-8", })); } saveChapters() { for (const chapter of this.chapters) { this.addChapter(chapter); } } addChapter(chapter) { const chapterName = this.getchapterName(chapter); const htmlfileNameBase = `${"0".repeat(this.chapters.length.toString().length - chapter.chapterNumber.toString().length)}${chapter.chapterNumber.toString()}.html`; const chapterHtmlFileName = `Chapter${htmlfileNameBase}`; if (chapter.sectionName) { if (!this._sections.includes(chapter.sectionName)) { this._sections.push(chapter.sectionName); log_1.log.debug(`[save]保存卷HTML文件:${chapter.sectionName}`); const sectionHTMLBlob = this.genSectionHtmlFile(chapter.sectionName); this.savedZip.file(`Section${htmlfileNameBase}`, sectionHTMLBlob); } } log_1.log.debug(`[save]保存章HTML文件:${chapterName}`); if (chapter.contentHTML) { const chapterHTMLBlob = this.genChapterHtmlFile(chapterName, chapter.contentHTML, chapter.chapterUrl); if (!setting_1.enaleDebug) { chapter.contentRaw = null; chapter.contentHTML = null; chapter.status = main_1.Status.saved; } this.savedZip.file(chapterHtmlFileName, chapterHTMLBlob); } log_1.log.debug(`[save]开始保存章节附件:${chapterName}`); if (chapter.contentImages) { for (const attachment of chapter.contentImages) { this.addImageToZip(attachment, this.savedZip); } if (!setting_1.enaleDebug) { chapter.contentImages = null; } } this._savedChapters.push(chapter); } getchapterName(chapter) { if (chapter.chapterName) { return chapter.chapterName; } else { return chapter.chapterNumber.toString(); } } genMetaDateTxt() { let metaDateText = `题名:${this.book.bookname}\n作者:${this.book.author}`; if (this.book.additionalMetadate.tags) { metaDateText += `\nTag列表:${this.book.additionalMetadate.tags.join("、")}`; } metaDateText += `\n原始网址:${this.book.bookUrl}`; if (this.book.additionalMetadate.cover) { metaDateText += `\n封面图片地址:${this.book.additionalMetadate.cover.url}`; } if (this.book.introduction) { metaDateText += `\n简介:${this.book.introduction}`; } metaDateText += `\n下载时间:${new Date().toISOString()}\n本文件由小说下载器生成,软件地址:https://github.com/yingziwu/novel-downloader\n\n`; return metaDateText; } addImageToZip(attachment, zip) { if (attachment.status === main_1.Status.finished && attachment.imageBlob) { log_1.log.debug(`[save]添加附件,文件名:${attachment.name},对象`, attachment.imageBlob); zip.file(attachment.name, attachment.imageBlob); if (!setting_1.enaleDebug) { attachment.imageBlob = null; attachment.status = main_1.Status.saved; } } else if (attachment.status === main_1.Status.saved) { log_1.log.debug(`[save]附件${attachment.name}已添加`); } else { log_1.log.warn(`[save]添加附件${attachment.name}失败,该附件未完成或内容为空。`); log_1.log.warn(attachment); } } genSectionText(sectionName) { return (`${"=".repeat(20)}\n\n\n\n# ${sectionName}\n\n\n\n${"=".repeat(20)}` + "\n\n"); } genChapterText(chapterName, contentText) { return `## ${chapterName}\n\n${contentText}\n\n`; } genSectionHtmlFile(sectionName) { let htmlFile = new DOMParser().parseFromString(`${sectionName}

${sectionName}

`, "text/html"); return new Blob([ htmlFile.documentElement.outerHTML.replaceAll("data-src-address", "src"), ], { type: "text/html; charset=UTF-8", }); } genChapterHtmlFile(chapterName, DOM, chapterUrl) { let htmlFile = new DOMParser().parseFromString(`${chapterName}

${chapterName}

`, "text/html"); htmlFile.querySelector(".main")?.appendChild(DOM); return new Blob([ htmlFile.documentElement.outerHTML.replaceAll("data-src-address", "src"), ], { type: "text/html; charset=UTF-8", }); } chapterSort(a, b) { if (a.chapterNumber > b.chapterNumber) { return 1; } if (a.chapterNumber === b.chapterNumber) { return 0; } if (a.chapterNumber < b.chapterNumber) { return -1; } return 0; } } exports.saveBook = saveBook; function saveOptionsValidate(data) { const keyNamesS = ["mainStyleText", "tocStyleText"]; const keyNamesF = ["getchapterName"]; function keyNametest(keyname) { const keyList = new Array().concat(keyNamesS).concat(keyNamesF); if (keyList.includes(keyname)) { return true; } return false; } function keyNamesStest(keyname) { if (keyNamesS.includes(keyname)) { if (typeof data[keyname] === "string") { return true; } } return false; } function keyNamesFtest(keyname) { if (keyNamesF.includes(keyname)) { if (typeof data[keyname] === "function") { return true; } } return false; } if (typeof data !== "object") { return false; } if (Object.keys(data).length === 0) { return false; } for (const keyname in data) { if (!keyNametest(keyname)) { return false; } if (!(keyNamesStest(keyname) || keyNamesFtest(keyname))) { return false; } } return true; } exports.saveOptionsValidate = saveOptionsValidate; function getSaveBookObj(book, options) { const saveBookObj = new saveBook(book); if (setting_1.enableCustomSaveOptions && saveOptionsValidate(options)) { for (const option in options) { saveBookObj[option] = options[option]; } } if (book.saveOptions !== undefined) { for (const option in book.saveOptions) { saveBookObj[option] = book.saveOptions[option]; } } return saveBookObj; } exports.getSaveBookObj = getSaveBookObj; /***/ }), /***/ "./src/setting.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.r18SiteList = exports.icon1 = exports.icon0 = exports.enableJjwxcRemoteFont = exports.enableR18SiteWarning = exports.enableCustomSaveOptions = exports.enableCustomChapterFilter = exports.enableCustomFinishCallback = exports.enaleDebug = exports.retryLimit = void 0; exports.retryLimit = 5; exports.enaleDebug = unsafeWindow.enaleDebug ?? false; exports.enableCustomFinishCallback = true; exports.enableCustomChapterFilter = true; exports.enableCustomSaveOptions = true; exports.enableR18SiteWarning = false; exports.enableJjwxcRemoteFont = true; exports.icon0 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAFYElEQVR4nO2dIUxkORyHP4XD4E6RYNZgUGvWonAnVqxDbbJiNWLNOsQ65Oo1CMQIFAnJJiQIcgY7YhIEbgTJiEkm4USPuyNh3pv2tf33tb9f8kl4fe3H0Pm37xXi50/gHJgBC+C5YB6Bv4AL4CuwH7872skBcI/9oA5lBpwAO1F7p/IcUf5fuy8L4AzYjthPVWYfeMJ+wFLxABxG660K8xv7QcrBWawOqykfsB+YnEzQv4RXOcV+UHJzD+zF6LwaMsF+QCyYo3kBALfYD4YVK+DL8C4cd+6wHwhrfgJbQztyrJEAjhvgj4F9OcrUKMA33Me778/NaLCUXKMA27ivt48BP7vArYU0k1oFAPeRHjrJPQ3u0ZGlZgHATe5+Bv6ecxooGtUuwEuOCVvsugd2vXp0ZGlFAHDL3bOA3zfHzSmqTEsCgNsjcBXwO5e4T5Hq0poA4OYFoWsg1RWNWhTgJZ8ImxdcUdFuo5YFADcvmAZcY0olRaPWBQD313wZcJ0n3Fa6UUcC/JfvAdda4TagjjYS4HWOcF/7fK/5i5FODmvcDzC0eveOsO3xt4xwRVECvJ1t3MMmvtd+AN5HuH62SIDunOC/tLxgREUjCdCf0HnBKFYUJcBm2SNsXnCZqD3RIgE2zzZuidi3PVPcxLLISAD/fMYtDvm0qdht6BIgLIf4zwuWOHmKigQIzy5hhbSiKocSYFi2cFVA3zZ+ytjGztQogMVS7Vf85gVPFLLVrEYBrGbcvlvRJzbNfJ0aBbDc1++7Fd28bFyjAOdRe8g/PlvOfhm18d/UKMCKMjZqHNM/L1hiXCmsUYBn3ILMZ+zX6N/jVgi72mr6KFqtArzwiJtsneE+li3oezLJdNGodgHGgOm3AQlgz03vKCWMBLDnrneUEkYC2CMBGkcCNI4EaBwJ0DgSYEMecE/mbkLIA59NCnCzplElEbqfLvTJXwlQGEN2z+zjv4GzKQFK/xewZPiCTumS6xOgg4cI9xiyZ08CFIIESBwJYI8E6EACJI4EsEcCdCABEkcC2CMBOpAAiSMB7JEAHUiAxJEA9kiADiRA4kgAeyRABxIgcSSAPRKgAwmQOBLAHgnQgQRIHAlgjwToQAIkjgSwRwJ0IAESRwLYYyrA7zWNKgUJkDgSwB4J0IEESBwJYE8zAqxwr0T7webv2Ivxbv2PHtc7xb1qNucDpc0I8DHTPcXIB/yPi5MAHcT4KM+dXH3ThADzXDcUMSHHxEmADr5kuqcYOSJfvzQjwIKCz8/7X3bof8O3BAjkDvtXuPcl5HBICeDB9yx3FpZj8vdHcwKsKOCsnDeyhzvNSwJkYEp5hypfY9MXTQrwjDtJo5ScYNcPzQrwTBmHOx1g+y7BpgV4xJ21Z5Ut8hV8JMAaLpPf5fqcdbRLAmTE4lj1wwHtlQCRyV0l3MHvnF8JkIGcVcLc1T4JsCE5qoQW1T4JsCGpq4RW1b5iBbhe0yhLUlYJS7xfCfAGKaqE3wq4LwngQcxTta2rfRIggDlxqoQlVPskQCAxqoQlVPskwACG7CUspdonAQYQWiUsqdonAQYSUiUsqdonASLgUyUsrdonASKwwj2y1ZcSq30SIBKbVAlLK29LgMh0VQlLrfZJgMi89aRxydU+CRCZOe5g6JfsMo6TwiVARJbABe7r3pgmfRJASAAhAQQSQCABmsdUgKs1jRL5uO0dpYSRAPZMekcpYS7WNErk47R3lBLmx5pGiXyYvi1lDFumaua6f4jS5w77jmiRBa/XM8zyjnHX0sfIkrjPPQzOAeNdTRsbUzbb2ZQ9W7i9dBNghltyjUHrny4r3JtHJ//0b9RH4P8GSxsCzEN/51YAAAAASUVORK5CYII="; exports.icon1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAESElEQVR4nO2cLUxcQRSFv4QgEBiSKgQCh6pCouvQlbVVdaRuTFUNoqaqEkktCoVD4HBITBMMosmaVsxu+kL3l3lv7p13z5ccyc68OSf3sLtvHwghhBBCjJM/hRKNowAERwEIjgIQHAUgOApAcBSA4CgAwVEAgqMABEcBCI4CEBwFIDgKQHAUgOAoAMFRAIKjAARHAQiOAhAcBSA4CkBwFIDgKADBUQCCowAERwEIjgIQHAUgOApAcBSA4CgAzkmUm9SqUvHpjYSEvRky35iEvSky35iEvTky35iEvUky35iEvVky35iEvWky35iEvXky35iEvYky35iEvZky35iEvaky35iEvbky35iEvcky35iEvdky35iEveky35iEzA9PQuaHJyHzm2e78O8T7Zhfeq2j4i1wDvyi/GAT/s1P5Gs9J197SN4An4A7hjlgz+a/fM078lm8KXxt92wDp8BPYEL9g/ZoflcT8tmcMrKK6I54TwfueS/NV8SyEe/54D3uoZmK2GTEt2KA5dov5bYiXjvivRthsea6Mq+Ivka8V0NqrlWqahUx1IjfRGeF15DWWCMVrnG2xhpDaLCKqDHiV+ka+ADs9nA9ack6qYfX3yXv9XrJOkOruCIsRvxLPZANOXztRSwhzVkvDbDO4fR1H+asV0trV4SHEf8M/ABOVm22B1Jn3VRhvRPytT1jc7YLK8LTiN/Z/FyLSNT/Vm8HZxVhtYnZiD8oOc3GOcC+Iqou9gx8p86Ib40T8tnUrogqi1wB76k/4ltkh3xWVzQegHvgM7Df6/HEYp98hvc0EoAn8hg7HuAwonNMPtsnnAVggkZ8TboV0cfb9aIRf4ZGvCX7ZA9KKmLjEf8NjXiPHJO92bQiFICRUCUAqgBfVK+AedI/gXVx80/goorQ28BhcPs2cFlF6IOgMpr7IGiRVBHrM5qPguep5vf9rWF1v0DVxbrS18EBvw5epGv6u+fPOx7uGXQXgJnGXBHWt4Q1EYCuhrwptBYebgptNgBd3dBORcxG/A325zaaAMz0G7gA3gFbaxpSgy3yni7Ie7Q+p9EGoKtH4AtwtNqfwTia7uER+/MIF4CuboCPwN5Su/phb7pWKyM+RABmGqoiWh7xoQLQ1SPwlbKKOJq+RssjPmwAurpl/YqYjfhbB/tWAHrWBLjk/9/HzX4XeYnd7yIVgMqa/T7O+neR1jLfgKQASIYy34CkAEiGcvGACKmu5j5DKPJboQha9BZ4Lh4eEiX1o+LnCKoi2tMgTxJVRfjWRiO+FFWEH5k/TVwVUV/mD4ueh4cHTY5ZVUd8KaqI/mQ+4ktRRWwulyO+FFXEcjU14ktRRfxT8yO+lIgVMcoRX8rYP2gKNeJLGVNFhB/xpbRYERrxA+C9IjTiK+KpIjTijbGoCI14hwxdERrxDdFnRWjEN85rKkIjfoSsqgiN+EB0K0IjXgghhBDh+Avri3imoU6g/AAAAABJRU5ErkJggg=="; exports.r18SiteList = [ "www.dierbanzhu1.com", "www.banzhuer.org", "m.yuzhaige.cc", ]; /***/ }), /***/ "./src/stat.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.resetStat = exports.printStat = exports.failedPlus = exports.successPlus = void 0; const log_1 = __webpack_require__("./src/log.ts"); const GM_1 = __webpack_require__("./src/lib/GM.ts"); const statKeyName = "novel-downloader-22932304826849026"; const domain = document.location.hostname; const _data = (0, GM_1._GM_getValue)(statKeyName); let statData; if (_data) { statData = JSON.parse(_data); } else { statData = { success: {}, failed: {} }; } const saveData = () => { const dataJSON = JSON.stringify(statData); if (GM_1._GM_setValue === null || GM_1._GM_getValue === null || GM_1._GM_deleteValue === null) { throw new Error("未发现 GM value 相关 API"); } (0, GM_1._GM_setValue)(statKeyName, dataJSON); return statData; }; const dataPlus = (key) => { const tmpData = statData[key]; if (tmpData[domain]) { tmpData[domain] = tmpData[domain] + 1; } else { tmpData[domain] = 1; } return saveData(); }; const successPlus = () => { return dataPlus("success"); }; exports.successPlus = successPlus; const failedPlus = () => { return dataPlus("failed"); }; exports.failedPlus = failedPlus; const printStat = () => { log_1.log.info("[stat]小说下载器脚本运行情况统计:"); log_1.log.info(statData); for (const k in statData) { log_1.log.info(`[stat]${k}:`); const subData = statData[k]; for (const j in subData) { log_1.log.info(` [stat]${j}: ${subData[j]}`); } } }; exports.printStat = printStat; const resetStat = () => { statData = { success: {}, failed: {} }; return saveData(); }; exports.resetStat = resetStat; /***/ }), /***/ "./node_modules/fflate/lib/index.cjs": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; // DEFLATE is a complex format; to read this code, you should probably check the RFC first: // https://tools.ietf.org/html/rfc1951 // You may also wish to take a look at the guide I made about this program: // https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad // Some of the following code is similar to that of UZIP.js: // https://github.com/photopea/UZIP.js // However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size. // Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint // is better for memory in most engines (I *think*). var node_worker_1 = __webpack_require__("./node_modules/fflate/lib/worker.cjs"); // aliases for shorter compressed code (most minifers don't do this) var u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array; // fixed length extra bits var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]); // fixed distance extra bits // see fleb note var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]); // code length index map var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); // get base, reverse index map from extra bits var freb = function (eb, start) { var b = new u16(31); for (var i = 0; i < 31; ++i) { b[i] = start += 1 << eb[i - 1]; } // numbers here are at max 18 bits var r = new u32(b[30]); for (var i = 1; i < 30; ++i) { for (var j = b[i]; j < b[i + 1]; ++j) { r[j] = ((j - b[i]) << 5) | i; } } return [b, r]; }; var _a = freb(fleb, 2), fl = _a[0], revfl = _a[1]; // we can ignore the fact that the other numbers are wrong; they never happen anyway fl[28] = 258, revfl[258] = 28; var _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1]; // map of value to reverse (assuming 16 bits) var rev = new u16(32768); for (var i = 0; i < 32768; ++i) { // reverse table algorithm from SO var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1); x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2); x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4); rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1; } // create huffman tree from u8 "map": index -> code length for code index // mb (max bits) must be at most 15 // TODO: optimize/split up? var hMap = (function (cd, mb, r) { var s = cd.length; // index var i = 0; // u16 "map": index -> # of codes with bit length = index var l = new u16(mb); // length of cd must be 288 (total # of codes) for (; i < s; ++i) ++l[cd[i] - 1]; // u16 "map": index -> minimum code for bit length = index var le = new u16(mb); for (i = 0; i < mb; ++i) { le[i] = (le[i - 1] + l[i - 1]) << 1; } var co; if (r) { // u16 "map": index -> number of actual bits, symbol for code co = new u16(1 << mb); // bits to remove for reverser var rvb = 15 - mb; for (i = 0; i < s; ++i) { // ignore 0 lengths if (cd[i]) { // num encoding both symbol and bits read var sv = (i << 4) | cd[i]; // free bits var r_1 = mb - cd[i]; // start value var v = le[cd[i] - 1]++ << r_1; // m is end value for (var m = v | ((1 << r_1) - 1); v <= m; ++v) { // every 16 bit value starting with the code yields the same result co[rev[v] >>> rvb] = sv; } } } } else { co = new u16(s); for (i = 0; i < s; ++i) { if (cd[i]) { co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]); } } } return co; }); // fixed length tree var flt = new u8(288); for (var i = 0; i < 144; ++i) flt[i] = 8; for (var i = 144; i < 256; ++i) flt[i] = 9; for (var i = 256; i < 280; ++i) flt[i] = 7; for (var i = 280; i < 288; ++i) flt[i] = 8; // fixed distance tree var fdt = new u8(32); for (var i = 0; i < 32; ++i) fdt[i] = 5; // fixed length map var flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1); // fixed distance map var fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1); // find max of array var max = function (a) { var m = a[0]; for (var i = 1; i < a.length; ++i) { if (a[i] > m) m = a[i]; } return m; }; // read d, starting at bit p and mask with m var bits = function (d, p, m) { var o = (p / 8) | 0; return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m; }; // read d, starting at bit p continuing for at least 16 bits var bits16 = function (d, p) { var o = (p / 8) | 0; return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7)); }; // get end of byte var shft = function (p) { return ((p + 7) / 8) | 0; }; // typed array slice - allows garbage collector to free original reference, // while being more compatible than .slice var slc = function (v, s, e) { if (s == null || s < 0) s = 0; if (e == null || e > v.length) e = v.length; // can't use .constructor in case user-supplied var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s); n.set(v.subarray(s, e)); return n; }; /** * Codes for errors generated within this library */ exports.FlateErrorCode = { UnexpectedEOF: 0, InvalidBlockType: 1, InvalidLengthLiteral: 2, InvalidDistance: 3, StreamFinished: 4, NoStreamHandler: 5, InvalidHeader: 6, NoCallback: 7, InvalidUTF8: 8, ExtraFieldTooLong: 9, InvalidDate: 10, FilenameTooLong: 11, StreamFinishing: 12, InvalidZipData: 13, UnknownCompressionMethod: 14 }; // error codes var ec = [ 'unexpected EOF', 'invalid block type', 'invalid length/literal', 'invalid distance', 'stream finished', 'no stream handler', , 'no callback', 'invalid UTF-8 data', 'extra field too long', 'date not in range 1980-2099', 'filename too long', 'stream finishing', 'invalid zip data' // determined by unknown compression method ]; ; var err = function (ind, msg, nt) { var e = new Error(msg || ec[ind]); e.code = ind; if (Error.captureStackTrace) Error.captureStackTrace(e, err); if (!nt) throw e; return e; }; // expands raw DEFLATE data var inflt = function (dat, buf, st) { // source length var sl = dat.length; if (!sl || (st && st.f && !st.l)) return buf || new u8(0); // have to estimate size var noBuf = !buf || st; // no state var noSt = !st || st.i; if (!st) st = {}; // Assumes roughly 33% compression ratio average if (!buf) buf = new u8(sl * 3); // ensure buffer can fit at least l elements var cbuf = function (l) { var bl = buf.length; // need to increase size to fit if (l > bl) { // Double or set to necessary, whichever is greater var nbuf = new u8(Math.max(bl * 2, l)); nbuf.set(buf); buf = nbuf; } }; // last chunk bitpos bytes var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n; // total bits var tbts = sl * 8; do { if (!lm) { // BFINAL - this is only 1 when last chunk is next final = bits(dat, pos, 1); // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman var type = bits(dat, pos + 1, 3); pos += 3; if (!type) { // go to end of byte boundary var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l; if (t > sl) { if (noSt) err(0); break; } // ensure size if (noBuf) cbuf(bt + l); // Copy over uncompressed data buf.set(dat.subarray(s, t), bt); // Get new bitpos, update byte count st.b = bt += l, st.p = pos = t * 8, st.f = final; continue; } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5; else if (type == 2) { // literal lengths var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4; var tl = hLit + bits(dat, pos + 5, 31) + 1; pos += 14; // length+distance tree var ldt = new u8(tl); // code length tree var clt = new u8(19); for (var i = 0; i < hcLen; ++i) { // use index map to get real code clt[clim[i]] = bits(dat, pos + i * 3, 7); } pos += hcLen * 3; // code lengths bits var clb = max(clt), clbmsk = (1 << clb) - 1; // code lengths map var clm = hMap(clt, clb, 1); for (var i = 0; i < tl;) { var r = clm[bits(dat, pos, clbmsk)]; // bits read pos += r & 15; // symbol var s = r >>> 4; // code length to copy if (s < 16) { ldt[i++] = s; } else { // copy count var c = 0, n = 0; if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1]; else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3; else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7; while (n--) ldt[i++] = c; } } // length tree distance tree var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit); // max length bits lbt = max(lt); // max dist bits dbt = max(dt); lm = hMap(lt, lbt, 1); dm = hMap(dt, dbt, 1); } else err(1); if (pos > tbts) { if (noSt) err(0); break; } } // Make sure the buffer can hold this + the largest possible addition // Maximum chunk size (practically, theoretically infinite) is 2^17; if (noBuf) cbuf(bt + 131072); var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1; var lpos = pos; for (;; lpos = pos) { // bits read, code var c = lm[bits16(dat, pos) & lms], sym = c >>> 4; pos += c & 15; if (pos > tbts) { if (noSt) err(0); break; } if (!c) err(2); if (sym < 256) buf[bt++] = sym; else if (sym == 256) { lpos = pos, lm = null; break; } else { var add = sym - 254; // no extra bits needed if less if (sym > 264) { // index var i = sym - 257, b = fleb[i]; add = bits(dat, pos, (1 << b) - 1) + fl[i]; pos += b; } // dist var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4; if (!d) err(3); pos += d & 15; var dt = fd[dsym]; if (dsym > 3) { var b = fdeb[dsym]; dt += bits16(dat, pos) & ((1 << b) - 1), pos += b; } if (pos > tbts) { if (noSt) err(0); break; } if (noBuf) cbuf(bt + 131072); var end = bt + add; for (; bt < end; bt += 4) { buf[bt] = buf[bt - dt]; buf[bt + 1] = buf[bt + 1 - dt]; buf[bt + 2] = buf[bt + 2 - dt]; buf[bt + 3] = buf[bt + 3 - dt]; } bt = end; } } st.l = lm, st.p = lpos, st.b = bt, st.f = final; if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt; } while (!final); return bt == buf.length ? buf : slc(buf, 0, bt); }; // starting at p, write the minimum number of bits that can hold v to d var wbits = function (d, p, v) { v <<= p & 7; var o = (p / 8) | 0; d[o] |= v; d[o + 1] |= v >>> 8; }; // starting at p, write the minimum number of bits (>8) that can hold v to d var wbits16 = function (d, p, v) { v <<= p & 7; var o = (p / 8) | 0; d[o] |= v; d[o + 1] |= v >>> 8; d[o + 2] |= v >>> 16; }; // creates code lengths from a frequency table var hTree = function (d, mb) { // Need extra info to make a tree var t = []; for (var i = 0; i < d.length; ++i) { if (d[i]) t.push({ s: i, f: d[i] }); } var s = t.length; var t2 = t.slice(); if (!s) return [et, 0]; if (s == 1) { var v = new u8(t[0].s + 1); v[t[0].s] = 1; return [v, 1]; } t.sort(function (a, b) { return a.f - b.f; }); // after i2 reaches last ind, will be stopped // freq must be greater than largest possible number of symbols t.push({ s: -1, f: 25001 }); var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2; t[0] = { s: -1, f: l.f + r.f, l: l, r: r }; // efficient algorithm from UZIP.js // i0 is lookbehind, i2 is lookahead - after processing two low-freq // symbols that combined have high freq, will start processing i2 (high-freq, // non-composite) symbols instead // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/ while (i1 != s - 1) { l = t[t[i0].f < t[i2].f ? i0++ : i2++]; r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++]; t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r }; } var maxSym = t2[0].s; for (var i = 1; i < s; ++i) { if (t2[i].s > maxSym) maxSym = t2[i].s; } // code lengths var tr = new u16(maxSym + 1); // max bits in tree var mbt = ln(t[i1 - 1], tr, 0); if (mbt > mb) { // more algorithms from UZIP.js // TODO: find out how this code works (debt) // ind debt var i = 0, dt = 0; // left cost var lft = mbt - mb, cst = 1 << lft; t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; }); for (; i < s; ++i) { var i2_1 = t2[i].s; if (tr[i2_1] > mb) { dt += cst - (1 << (mbt - tr[i2_1])); tr[i2_1] = mb; } else break; } dt >>>= lft; while (dt > 0) { var i2_2 = t2[i].s; if (tr[i2_2] < mb) dt -= 1 << (mb - tr[i2_2]++ - 1); else ++i; } for (; i >= 0 && dt; --i) { var i2_3 = t2[i].s; if (tr[i2_3] == mb) { --tr[i2_3]; ++dt; } } mbt = mb; } return [new u8(tr), mbt]; }; // get the max length and assign length codes var ln = function (n, l, d) { return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : (l[n.s] = d); }; // length codes generation var lc = function (c) { var s = c.length; // Note that the semicolon was intentional while (s && !c[--s]) ; var cl = new u16(++s); // ind num streak var cli = 0, cln = c[0], cls = 1; var w = function (v) { cl[cli++] = v; }; for (var i = 1; i <= s; ++i) { if (c[i] == cln && i != s) ++cls; else { if (!cln && cls > 2) { for (; cls > 138; cls -= 138) w(32754); if (cls > 2) { w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305); cls = 0; } } else if (cls > 3) { w(cln), --cls; for (; cls > 6; cls -= 6) w(8304); if (cls > 2) w(((cls - 3) << 5) | 8208), cls = 0; } while (cls--) w(cln); cls = 1; cln = c[i]; } } return [cl.subarray(0, cli), s]; }; // calculate the length of output from tree, code lengths var clen = function (cf, cl) { var l = 0; for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i]; return l; }; // writes a fixed block // returns the new bit pos var wfblk = function (out, pos, dat) { // no need to write 00 as type: TypedArray defaults to 0 var s = dat.length; var o = shft(pos + 2); out[o] = s & 255; out[o + 1] = s >>> 8; out[o + 2] = out[o] ^ 255; out[o + 3] = out[o + 1] ^ 255; for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i]; return (o + 4 + s) * 8; }; // writes a block var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) { wbits(out, p++, final); ++lf[256]; var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1]; var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1]; var _c = lc(dlt), lclt = _c[0], nlc = _c[1]; var _d = lc(ddt), lcdt = _d[0], ndc = _d[1]; var lcfreq = new u16(19); for (var i = 0; i < lclt.length; ++i) lcfreq[lclt[i] & 31]++; for (var i = 0; i < lcdt.length; ++i) lcfreq[lcdt[i] & 31]++; var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1]; var nlcc = 19; for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc) ; var flen = (bl + 5) << 3; var ftlen = clen(lf, flt) + clen(df, fdt) + eb; var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]); if (flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl)); var lm, ll, dm, dl; wbits(out, p, 1 + (dtlen < ftlen)), p += 2; if (dtlen < ftlen) { lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt; var llm = hMap(lct, mlcb, 0); wbits(out, p, nlc - 257); wbits(out, p + 5, ndc - 1); wbits(out, p + 10, nlcc - 4); p += 14; for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]); p += 3 * nlcc; var lcts = [lclt, lcdt]; for (var it = 0; it < 2; ++it) { var clct = lcts[it]; for (var i = 0; i < clct.length; ++i) { var len = clct[i] & 31; wbits(out, p, llm[len]), p += lct[len]; if (len > 15) wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12; } } } else { lm = flm, ll = flt, dm = fdm, dl = fdt; } for (var i = 0; i < li; ++i) { if (syms[i] > 255) { var len = (syms[i] >>> 18) & 31; wbits16(out, p, lm[len + 257]), p += ll[len + 257]; if (len > 7) wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len]; var dst = syms[i] & 31; wbits16(out, p, dm[dst]), p += dl[dst]; if (dst > 3) wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst]; } else { wbits16(out, p, lm[syms[i]]), p += ll[syms[i]]; } } wbits16(out, p, lm[256]); return p + ll[256]; }; // deflate options (nice << 13) | chain var deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]); // empty var et = /*#__PURE__*/ new u8(0); // compresses data into a raw DEFLATE buffer var dflt = function (dat, lvl, plvl, pre, post, lst) { var s = dat.length; var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post); // writing to this writes to the output buffer var w = o.subarray(pre, o.length - post); var pos = 0; if (!lvl || s < 8) { for (var i = 0; i <= s; i += 65535) { // end var e = i + 65535; if (e < s) { // write full block pos = wfblk(w, pos, dat.subarray(i, e)); } else { // write final block w[i] = lst; pos = wfblk(w, pos, dat.subarray(i, s)); } } } else { var opt = deo[lvl - 1]; var n = opt >>> 13, c = opt & 8191; var msk_1 = (1 << plvl) - 1; // prev 2-byte val map curr 2-byte val map var prev = new u16(32768), head = new u16(msk_1 + 1); var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1; var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; }; // 24576 is an arbitrary number of maximum symbols per block // 424 buffer for last block var syms = new u32(25000); // length/literal freq distance freq var lf = new u16(288), df = new u16(32); // l/lcnt exbits index l/lind waitdx bitpos var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0; for (; i < s; ++i) { // hash value // deopt when i > s - 3 - at end, deopt acceptable var hv = hsh(i); // index mod 32768 previous index mod var imod = i & 32767, pimod = head[hv]; prev[imod] = pimod; head[hv] = imod; // We always should modify head and prev, but only add symbols if // this data is not yet processed ("wait" for wait index) if (wi <= i) { // bytes remaining var rem = s - i; if ((lc_1 > 7000 || li > 24576) && rem > 423) { pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos); li = lc_1 = eb = 0, bs = i; for (var j = 0; j < 286; ++j) lf[j] = 0; for (var j = 0; j < 30; ++j) df[j] = 0; } // len dist chain var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767; if (rem > 2 && hv == hsh(i - dif)) { var maxn = Math.min(n, rem) - 1; var maxd = Math.min(32767, i); // max possible length // not capped at dif because decompressors implement "rolling" index population var ml = Math.min(258, rem); while (dif <= maxd && --ch_1 && imod != pimod) { if (dat[i + l] == dat[i + l - dif]) { var nl = 0; for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl) ; if (nl > l) { l = nl, d = dif; // break out early when we reach "nice" (we are satisfied enough) if (nl > maxn) break; // now, find the rarest 2-byte sequence within this // length of literals and search for that instead. // Much faster than just using the start var mmd = Math.min(dif, nl - 2); var md = 0; for (var j = 0; j < mmd; ++j) { var ti = (i - dif + j + 32768) & 32767; var pti = prev[ti]; var cd = (ti - pti + 32768) & 32767; if (cd > md) md = cd, pimod = ti; } } } // check the previous match imod = pimod, pimod = prev[imod]; dif += (imod - pimod + 32768) & 32767; } } // d will be nonzero only when a match was found if (d) { // store both dist and len data in one Uint32 // Make sure this is recognized as a len/dist with 28th bit (2^28) syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d]; var lin = revfl[l] & 31, din = revfd[d] & 31; eb += fleb[lin] + fdeb[din]; ++lf[257 + lin]; ++df[din]; wi = i + l; ++lc_1; } else { syms[li++] = dat[i]; ++lf[dat[i]]; } } } pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos); // this is the easiest way to avoid needing to maintain state if (!lst && pos & 7) pos = wfblk(w, pos + 1, et); } return slc(o, 0, pre + shft(pos) + post); }; // CRC32 table var crct = /*#__PURE__*/ (function () { var t = new Int32Array(256); for (var i = 0; i < 256; ++i) { var c = i, k = 9; while (--k) c = ((c & 1) && -306674912) ^ (c >>> 1); t[i] = c; } return t; })(); // CRC32 var crc = function () { var c = -1; return { p: function (d) { // closures have awful performance var cr = c; for (var i = 0; i < d.length; ++i) cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8); c = cr; }, d: function () { return ~c; } }; }; // Alder32 var adler = function () { var a = 1, b = 0; return { p: function (d) { // closures have awful performance var n = a, m = b; var l = d.length | 0; for (var i = 0; i != l;) { var e = Math.min(i + 2655, l); for (; i < e; ++i) m += n += d[i]; n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16); } a = n, b = m; }, d: function () { a %= 65521, b %= 65521; return (a & 255) << 24 | (a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8); } }; }; ; // deflate with opts var dopt = function (dat, opt, pre, post, st) { return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st); }; // Walmart object spread var mrg = function (a, b) { var o = {}; for (var k in a) o[k] = a[k]; for (var k in b) o[k] = b[k]; return o; }; // worker clone // This is possibly the craziest part of the entire codebase, despite how simple it may seem. // The only parameter to this function is a closure that returns an array of variables outside of the function scope. // We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization. // We will return an object mapping of true variable name to value (basically, the current scope as a JS object). // The reason we can't just use the original variable names is minifiers mangling the toplevel scope. // This took me three weeks to figure out how to do. var wcln = function (fn, fnStr, td) { var dt = fn(); var st = fn.toString(); var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/ /g, '').split(','); for (var i = 0; i < dt.length; ++i) { var v = dt[i], k = ks[i]; if (typeof v == 'function') { fnStr += ';' + k + '='; var st_1 = v.toString(); if (v.prototype) { // for global objects if (st_1.indexOf('[native code]') != -1) { var spInd = st_1.indexOf(' ', 8) + 1; fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd)); } else { fnStr += st_1; for (var t in v.prototype) fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString(); } } else fnStr += st_1; } else td[k] = v; } return [fnStr, td]; }; var ch = []; // clone bufs var cbfs = function (v) { var tl = []; for (var k in v) { if (v[k] instanceof u8 || v[k] instanceof u16 || v[k] instanceof u32) tl.push((v[k] = new v[k].constructor(v[k])).buffer); } return tl; }; // use a worker to execute code var wrkr = function (fns, init, id, cb) { var _a; if (!ch[id]) { var fnStr = '', td_1 = {}, m = fns.length - 1; for (var i = 0; i < m; ++i) _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1]; ch[id] = wcln(fns[m], fnStr, td_1); } var td = mrg({}, ch[id][1]); return node_worker_1["default"](ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb); }; // base async inflate fn var bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gu8]; }; var bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; }; // gzip extra var gze = function () { return [gzh, gzhl, wbytes, crc, crct]; }; // gunzip extra var guze = function () { return [gzs, gzl]; }; // zlib extra var zle = function () { return [zlh, wbytes, adler]; }; // unzlib extra var zule = function () { return [zlv]; }; // post buf var pbf = function (msg) { return postMessage(msg, [msg.buffer]); }; // get u8 var gu8 = function (o) { return o && o.size && new u8(o.size); }; // async helper var cbify = function (dat, opts, fns, init, id, cb) { var w = wrkr(fns, init, id, function (err, dat) { w.terminate(); cb(err, dat); }); w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []); return function () { w.terminate(); }; }; // auto stream var astrm = function (strm) { strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); }; return function (ev) { return strm.push(ev.data[0], ev.data[1]); }; }; // async stream attach var astrmify = function (fns, strm, opts, init, id) { var t; var w = wrkr(fns, init, id, function (err, dat) { if (err) w.terminate(), strm.ondata.call(strm, err); else { if (dat[1]) w.terminate(); strm.ondata.call(strm, err, dat[0], dat[1]); } }); w.postMessage(opts); strm.push = function (d, f) { if (!strm.ondata) err(5); if (t) strm.ondata(err(4, 0, 1), null, !!f); w.postMessage([d, t = f], [d.buffer]); }; strm.terminate = function () { w.terminate(); }; }; // read 2 bytes var b2 = function (d, b) { return d[b] | (d[b + 1] << 8); }; // read 4 bytes var b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; }; var b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); }; // write bytes var wbytes = function (d, b, v) { for (; v; ++b) d[b] = v, v >>>= 8; }; // gzip header var gzh = function (c, o) { var fn = o.filename; c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix if (o.mtime != 0) wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000)); if (fn) { c[3] = 8; for (var i = 0; i <= fn.length; ++i) c[i + 10] = fn.charCodeAt(i); } }; // gzip footer: -8 to -4 = CRC, -4 to -0 is length // gzip start var gzs = function (d) { if (d[0] != 31 || d[1] != 139 || d[2] != 8) err(6, 'invalid gzip data'); var flg = d[3]; var st = 10; if (flg & 4) st += d[10] | (d[11] << 8) + 2; for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++]) ; return st + (flg & 2); }; // gzip length var gzl = function (d) { var l = d.length; return ((d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) | (d[l - 1] << 24)) >>> 0; }; // gzip header length var gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); }; // zlib header var zlh = function (c, o) { var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2; c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1); }; // zlib valid var zlv = function (d) { if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31)) err(6, 'invalid zlib data'); if (d[1] & 32) err(6, 'invalid zlib data: preset dictionaries not supported'); }; function AsyncCmpStrm(opts, cb) { if (!cb && typeof opts == 'function') cb = opts, opts = {}; this.ondata = cb; return opts; } // zlib footer: -4 to -0 is Adler32 /** * Streaming DEFLATE compression */ var Deflate = /*#__PURE__*/ (function () { function Deflate(opts, cb) { if (!cb && typeof opts == 'function') cb = opts, opts = {}; this.ondata = cb; this.o = opts || {}; } Deflate.prototype.p = function (c, f) { this.ondata(dopt(c, this.o, 0, 0, !f), f); }; /** * Pushes a chunk to be deflated * @param chunk The chunk to push * @param final Whether this is the last chunk */ Deflate.prototype.push = function (chunk, final) { if (!this.ondata) err(5); if (this.d) err(4); this.d = final; this.p(chunk, final || false); }; return Deflate; }()); exports.Deflate = Deflate; /** * Asynchronous streaming DEFLATE compression */ var AsyncDeflate = /*#__PURE__*/ (function () { function AsyncDeflate(opts, cb) { astrmify([ bDflt, function () { return [astrm, Deflate]; } ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) { var strm = new Deflate(ev.data); onmessage = astrm(strm); }, 6); } return AsyncDeflate; }()); exports.AsyncDeflate = AsyncDeflate; function deflate(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bDflt, ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb); } exports.deflate = deflate; /** * Compresses data with DEFLATE without any wrapper * @param data The data to compress * @param opts The compression options * @returns The deflated version of the data */ function deflateSync(data, opts) { return dopt(data, opts || {}, 0, 0); } exports.deflateSync = deflateSync; /** * Streaming DEFLATE decompression */ var Inflate = /*#__PURE__*/ (function () { /** * Creates an inflation stream * @param cb The callback to call whenever data is inflated */ function Inflate(cb) { this.s = {}; this.p = new u8(0); this.ondata = cb; } Inflate.prototype.e = function (c) { if (!this.ondata) err(5); if (this.d) err(4); var l = this.p.length; var n = new u8(l + c.length); n.set(this.p), n.set(c, l), this.p = n; }; Inflate.prototype.c = function (final) { this.d = this.s.i = final || false; var bts = this.s.b; var dt = inflt(this.p, this.o, this.s); this.ondata(slc(dt, bts, this.s.b), this.d); this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length; this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7; }; /** * Pushes a chunk to be inflated * @param chunk The chunk to push * @param final Whether this is the final chunk */ Inflate.prototype.push = function (chunk, final) { this.e(chunk), this.c(final); }; return Inflate; }()); exports.Inflate = Inflate; /** * Asynchronous streaming DEFLATE decompression */ var AsyncInflate = /*#__PURE__*/ (function () { /** * Creates an asynchronous inflation stream * @param cb The callback to call whenever data is deflated */ function AsyncInflate(cb) { this.ondata = cb; astrmify([ bInflt, function () { return [astrm, Inflate]; } ], this, 0, function () { var strm = new Inflate(); onmessage = astrm(strm); }, 7); } return AsyncInflate; }()); exports.AsyncInflate = AsyncInflate; function inflate(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bInflt ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb); } exports.inflate = inflate; /** * Expands DEFLATE data with no wrapper * @param data The data to decompress * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length. * @returns The decompressed version of the data */ function inflateSync(data, out) { return inflt(data, out); } exports.inflateSync = inflateSync; // before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize. /** * Streaming GZIP compression */ var Gzip = /*#__PURE__*/ (function () { function Gzip(opts, cb) { this.c = crc(); this.l = 0; this.v = 1; Deflate.call(this, opts, cb); } /** * Pushes a chunk to be GZIPped * @param chunk The chunk to push * @param final Whether this is the last chunk */ Gzip.prototype.push = function (chunk, final) { Deflate.prototype.push.call(this, chunk, final); }; Gzip.prototype.p = function (c, f) { this.c.p(c); this.l += c.length; var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f); if (this.v) gzh(raw, this.o), this.v = 0; if (f) wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l); this.ondata(raw, f); }; return Gzip; }()); exports.Gzip = Gzip; exports.Compress = Gzip; /** * Asynchronous streaming GZIP compression */ var AsyncGzip = /*#__PURE__*/ (function () { function AsyncGzip(opts, cb) { astrmify([ bDflt, gze, function () { return [astrm, Deflate, Gzip]; } ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) { var strm = new Gzip(ev.data); onmessage = astrm(strm); }, 8); } return AsyncGzip; }()); exports.AsyncGzip = AsyncGzip; exports.AsyncCompress = AsyncGzip; function gzip(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bDflt, gze, function () { return [gzipSync]; } ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb); } exports.gzip = gzip; exports.compress = gzip; /** * Compresses data with GZIP * @param data The data to compress * @param opts The compression options * @returns The gzipped version of the data */ function gzipSync(data, opts) { if (!opts) opts = {}; var c = crc(), l = data.length; c.p(data); var d = dopt(data, opts, gzhl(opts), 8), s = d.length; return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d; } exports.gzipSync = gzipSync; exports.compressSync = gzipSync; /** * Streaming GZIP decompression */ var Gunzip = /*#__PURE__*/ (function () { /** * Creates a GUNZIP stream * @param cb The callback to call whenever data is inflated */ function Gunzip(cb) { this.v = 1; Inflate.call(this, cb); } /** * Pushes a chunk to be GUNZIPped * @param chunk The chunk to push * @param final Whether this is the last chunk */ Gunzip.prototype.push = function (chunk, final) { Inflate.prototype.e.call(this, chunk); if (this.v) { var s = this.p.length > 3 ? gzs(this.p) : 4; if (s >= this.p.length && !final) return; this.p = this.p.subarray(s), this.v = 0; } if (final) { if (this.p.length < 8) err(6, 'invalid gzip data'); this.p = this.p.subarray(0, -8); } // necessary to prevent TS from using the closure value // This allows for workerization to function correctly Inflate.prototype.c.call(this, final); }; return Gunzip; }()); exports.Gunzip = Gunzip; /** * Asynchronous streaming GZIP decompression */ var AsyncGunzip = /*#__PURE__*/ (function () { /** * Creates an asynchronous GUNZIP stream * @param cb The callback to call whenever data is deflated */ function AsyncGunzip(cb) { this.ondata = cb; astrmify([ bInflt, guze, function () { return [astrm, Inflate, Gunzip]; } ], this, 0, function () { var strm = new Gunzip(); onmessage = astrm(strm); }, 9); } return AsyncGunzip; }()); exports.AsyncGunzip = AsyncGunzip; function gunzip(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bInflt, guze, function () { return [gunzipSync]; } ], function (ev) { return pbf(gunzipSync(ev.data[0])); }, 3, cb); } exports.gunzip = gunzip; /** * Expands GZIP data * @param data The data to decompress * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory. * @returns The decompressed version of the data */ function gunzipSync(data, out) { return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data))); } exports.gunzipSync = gunzipSync; /** * Streaming Zlib compression */ var Zlib = /*#__PURE__*/ (function () { function Zlib(opts, cb) { this.c = adler(); this.v = 1; Deflate.call(this, opts, cb); } /** * Pushes a chunk to be zlibbed * @param chunk The chunk to push * @param final Whether this is the last chunk */ Zlib.prototype.push = function (chunk, final) { Deflate.prototype.push.call(this, chunk, final); }; Zlib.prototype.p = function (c, f) { this.c.p(c); var raw = dopt(c, this.o, this.v && 2, f && 4, !f); if (this.v) zlh(raw, this.o), this.v = 0; if (f) wbytes(raw, raw.length - 4, this.c.d()); this.ondata(raw, f); }; return Zlib; }()); exports.Zlib = Zlib; /** * Asynchronous streaming Zlib compression */ var AsyncZlib = /*#__PURE__*/ (function () { function AsyncZlib(opts, cb) { astrmify([ bDflt, zle, function () { return [astrm, Deflate, Zlib]; } ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) { var strm = new Zlib(ev.data); onmessage = astrm(strm); }, 10); } return AsyncZlib; }()); exports.AsyncZlib = AsyncZlib; function zlib(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bDflt, zle, function () { return [zlibSync]; } ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb); } exports.zlib = zlib; /** * Compress data with Zlib * @param data The data to compress * @param opts The compression options * @returns The zlib-compressed version of the data */ function zlibSync(data, opts) { if (!opts) opts = {}; var a = adler(); a.p(data); var d = dopt(data, opts, 2, 4); return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d; } exports.zlibSync = zlibSync; /** * Streaming Zlib decompression */ var Unzlib = /*#__PURE__*/ (function () { /** * Creates a Zlib decompression stream * @param cb The callback to call whenever data is inflated */ function Unzlib(cb) { this.v = 1; Inflate.call(this, cb); } /** * Pushes a chunk to be unzlibbed * @param chunk The chunk to push * @param final Whether this is the last chunk */ Unzlib.prototype.push = function (chunk, final) { Inflate.prototype.e.call(this, chunk); if (this.v) { if (this.p.length < 2 && !final) return; this.p = this.p.subarray(2), this.v = 0; } if (final) { if (this.p.length < 4) err(6, 'invalid zlib data'); this.p = this.p.subarray(0, -4); } // necessary to prevent TS from using the closure value // This allows for workerization to function correctly Inflate.prototype.c.call(this, final); }; return Unzlib; }()); exports.Unzlib = Unzlib; /** * Asynchronous streaming Zlib decompression */ var AsyncUnzlib = /*#__PURE__*/ (function () { /** * Creates an asynchronous Zlib decompression stream * @param cb The callback to call whenever data is deflated */ function AsyncUnzlib(cb) { this.ondata = cb; astrmify([ bInflt, zule, function () { return [astrm, Inflate, Unzlib]; } ], this, 0, function () { var strm = new Unzlib(); onmessage = astrm(strm); }, 11); } return AsyncUnzlib; }()); exports.AsyncUnzlib = AsyncUnzlib; function unzlib(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return cbify(data, opts, [ bInflt, zule, function () { return [unzlibSync]; } ], function (ev) { return pbf(unzlibSync(ev.data[0], gu8(ev.data[1]))); }, 5, cb); } exports.unzlib = unzlib; /** * Expands Zlib data * @param data The data to decompress * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length. * @returns The decompressed version of the data */ function unzlibSync(data, out) { return inflt((zlv(data), data.subarray(2, -4)), out); } exports.unzlibSync = unzlibSync; /** * Streaming GZIP, Zlib, or raw DEFLATE decompression */ var Decompress = /*#__PURE__*/ (function () { /** * Creates a decompression stream * @param cb The callback to call whenever data is decompressed */ function Decompress(cb) { this.G = Gunzip; this.I = Inflate; this.Z = Unzlib; this.ondata = cb; } /** * Pushes a chunk to be decompressed * @param chunk The chunk to push * @param final Whether this is the last chunk */ Decompress.prototype.push = function (chunk, final) { if (!this.ondata) err(5); if (!this.s) { if (this.p && this.p.length) { var n = new u8(this.p.length + chunk.length); n.set(this.p), n.set(chunk, this.p.length); } else this.p = chunk; if (this.p.length > 2) { var _this_1 = this; var cb = function () { _this_1.ondata.apply(_this_1, arguments); }; this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8) ? new this.G(cb) : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31)) ? new this.I(cb) : new this.Z(cb); this.s.push(this.p, final); this.p = null; } } else this.s.push(chunk, final); }; return Decompress; }()); exports.Decompress = Decompress; /** * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression */ var AsyncDecompress = /*#__PURE__*/ (function () { /** * Creates an asynchronous decompression stream * @param cb The callback to call whenever data is decompressed */ function AsyncDecompress(cb) { this.G = AsyncGunzip; this.I = AsyncInflate; this.Z = AsyncUnzlib; this.ondata = cb; } /** * Pushes a chunk to be decompressed * @param chunk The chunk to push * @param final Whether this is the last chunk */ AsyncDecompress.prototype.push = function (chunk, final) { Decompress.prototype.push.call(this, chunk, final); }; return AsyncDecompress; }()); exports.AsyncDecompress = AsyncDecompress; function decompress(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); return (data[0] == 31 && data[1] == 139 && data[2] == 8) ? gunzip(data, opts, cb) : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31)) ? inflate(data, opts, cb) : unzlib(data, opts, cb); } exports.decompress = decompress; /** * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format * @param data The data to decompress * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length. * @returns The decompressed version of the data */ function decompressSync(data, out) { return (data[0] == 31 && data[1] == 139 && data[2] == 8) ? gunzipSync(data, out) : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31)) ? inflateSync(data, out) : unzlibSync(data, out); } exports.decompressSync = decompressSync; // flatten a directory structure var fltn = function (d, p, t, o) { for (var k in d) { var val = d[k], n = p + k; if (val instanceof u8) t[n] = [val, o]; else if (Array.isArray(val)) t[n] = [val[0], mrg(o, val[1])]; else fltn(val, n + '/', t, o); } }; // text encoder var te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder(); // text decoder var td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder(); // text decoder stream var tds = 0; try { td.decode(et, { stream: true }); tds = 1; } catch (e) { } // decode UTF8 var dutf8 = function (d) { for (var r = '', i = 0;;) { var c = d[i++]; var eb = (c > 127) + (c > 223) + (c > 239); if (i + eb > d.length) return [r, slc(d, i - 1)]; if (!eb) r += String.fromCharCode(c); else if (eb == 3) { c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536, r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023)); } else if (eb & 1) r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63)); else r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)); } }; /** * Streaming UTF-8 decoding */ var DecodeUTF8 = /*#__PURE__*/ (function () { /** * Creates a UTF-8 decoding stream * @param cb The callback to call whenever data is decoded */ function DecodeUTF8(cb) { this.ondata = cb; if (tds) this.t = new TextDecoder(); else this.p = et; } /** * Pushes a chunk to be decoded from UTF-8 binary * @param chunk The chunk to push * @param final Whether this is the last chunk */ DecodeUTF8.prototype.push = function (chunk, final) { if (!this.ondata) err(5); final = !!final; if (this.t) { this.ondata(this.t.decode(chunk, { stream: true }), final); if (final) { if (this.t.decode().length) err(8); this.t = null; } return; } if (!this.p) err(4); var dat = new u8(this.p.length + chunk.length); dat.set(this.p); dat.set(chunk, this.p.length); var _a = dutf8(dat), ch = _a[0], np = _a[1]; if (final) { if (np.length) err(8); this.p = null; } else this.p = np; this.ondata(ch, final); }; return DecodeUTF8; }()); exports.DecodeUTF8 = DecodeUTF8; /** * Streaming UTF-8 encoding */ var EncodeUTF8 = /*#__PURE__*/ (function () { /** * Creates a UTF-8 decoding stream * @param cb The callback to call whenever data is encoded */ function EncodeUTF8(cb) { this.ondata = cb; } /** * Pushes a chunk to be encoded to UTF-8 * @param chunk The string data to push * @param final Whether this is the last chunk */ EncodeUTF8.prototype.push = function (chunk, final) { if (!this.ondata) err(5); if (this.d) err(4); this.ondata(strToU8(chunk), this.d = final || false); }; return EncodeUTF8; }()); exports.EncodeUTF8 = EncodeUTF8; /** * Converts a string into a Uint8Array for use with compression/decompression methods * @param str The string to encode * @param latin1 Whether or not to interpret the data as Latin-1. This should * not need to be true unless decoding a binary string. * @returns The string encoded in UTF-8/Latin-1 binary */ function strToU8(str, latin1) { if (latin1) { var ar_1 = new u8(str.length); for (var i = 0; i < str.length; ++i) ar_1[i] = str.charCodeAt(i); return ar_1; } if (te) return te.encode(str); var l = str.length; var ar = new u8(str.length + (str.length >> 1)); var ai = 0; var w = function (v) { ar[ai++] = v; }; for (var i = 0; i < l; ++i) { if (ai + 5 > ar.length) { var n = new u8(ai + 8 + ((l - i) << 1)); n.set(ar); ar = n; } var c = str.charCodeAt(i); if (c < 128 || latin1) w(c); else if (c < 2048) w(192 | (c >> 6)), w(128 | (c & 63)); else if (c > 55295 && c < 57344) c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023), w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63)); else w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63)); } return slc(ar, 0, ai); } exports.strToU8 = strToU8; /** * Converts a Uint8Array to a string * @param dat The data to decode to string * @param latin1 Whether or not to interpret the data as Latin-1. This should * not need to be true unless encoding to binary string. * @returns The original UTF-8/Latin-1 string */ function strFromU8(dat, latin1) { if (latin1) { var r = ''; for (var i = 0; i < dat.length; i += 16384) r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384)); return r; } else if (td) return td.decode(dat); else { var _a = dutf8(dat), out = _a[0], ext = _a[1]; if (ext.length) err(8); return out; } } exports.strFromU8 = strFromU8; ; // deflate bit flag var dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; }; // skip local zip header var slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); }; // read zip header var zh = function (d, b, z) { var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20); var _a = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)], sc = _a[0], su = _a[1], off = _a[2]; return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off]; }; // read zip64 extra field var z64e = function (d, b) { for (; b2(d, b) != 1; b += 4 + b2(d, b + 2)) ; return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)]; }; // extra field length var exfl = function (ex) { var le = 0; if (ex) { for (var k in ex) { var l = ex[k].length; if (l > 65535) err(9); le += l + 4; } } return le; }; // write zip header var wzh = function (d, b, f, fn, u, c, ce, co) { var fl = fn.length, ex = f.extra, col = co && co.length; var exl = exfl(ex); wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4; if (ce != null) d[b++] = 20, d[b++] = f.os; d[b] = 20, b += 2; // spec compliance? what's that? d[b++] = (f.flag << 1) | (c == null && 8), d[b++] = u && 8; d[b++] = f.compression & 255, d[b++] = f.compression >> 8; var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980; if (y < 0 || y > 119) err(10); wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1)), b += 4; if (c != null) { wbytes(d, b, f.crc); wbytes(d, b + 4, c); wbytes(d, b + 8, f.size); } wbytes(d, b + 12, fl); wbytes(d, b + 14, exl), b += 16; if (ce != null) { wbytes(d, b, col); wbytes(d, b + 6, f.attrs); wbytes(d, b + 10, ce), b += 14; } d.set(fn, b); b += fl; if (exl) { for (var k in ex) { var exf = ex[k], l = exf.length; wbytes(d, b, +k); wbytes(d, b + 2, l); d.set(exf, b + 4), b += 4 + l; } } if (col) d.set(co, b), b += col; return b; }; // write zip footer (end of central directory) var wzf = function (o, b, c, d, e) { wbytes(o, b, 0x6054B50); // skip disk wbytes(o, b + 8, c); wbytes(o, b + 10, c); wbytes(o, b + 12, d); wbytes(o, b + 16, e); }; /** * A pass-through stream to keep data uncompressed in a ZIP archive. */ var ZipPassThrough = /*#__PURE__*/ (function () { /** * Creates a pass-through stream that can be added to ZIP archives * @param filename The filename to associate with this data stream */ function ZipPassThrough(filename) { this.filename = filename; this.c = crc(); this.size = 0; this.compression = 0; } /** * Processes a chunk and pushes to the output stream. You can override this * method in a subclass for custom behavior, but by default this passes * the data through. You must call this.ondata(err, chunk, final) at some * point in this method. * @param chunk The chunk to process * @param final Whether this is the last chunk */ ZipPassThrough.prototype.process = function (chunk, final) { this.ondata(null, chunk, final); }; /** * Pushes a chunk to be added. If you are subclassing this with a custom * compression algorithm, note that you must push data from the source * file only, pre-compression. * @param chunk The chunk to push * @param final Whether this is the last chunk */ ZipPassThrough.prototype.push = function (chunk, final) { if (!this.ondata) err(5); this.c.p(chunk); this.size += chunk.length; if (final) this.crc = this.c.d(); this.process(chunk, final || false); }; return ZipPassThrough; }()); exports.ZipPassThrough = ZipPassThrough; // I don't extend because TypeScript extension adds 1kB of runtime bloat /** * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate * for better performance */ var ZipDeflate = /*#__PURE__*/ (function () { /** * Creates a DEFLATE stream that can be added to ZIP archives * @param filename The filename to associate with this data stream * @param opts The compression options */ function ZipDeflate(filename, opts) { var _this_1 = this; if (!opts) opts = {}; ZipPassThrough.call(this, filename); this.d = new Deflate(opts, function (dat, final) { _this_1.ondata(null, dat, final); }); this.compression = 8; this.flag = dbf(opts.level); } ZipDeflate.prototype.process = function (chunk, final) { try { this.d.push(chunk, final); } catch (e) { this.ondata(e, null, final); } }; /** * Pushes a chunk to be deflated * @param chunk The chunk to push * @param final Whether this is the last chunk */ ZipDeflate.prototype.push = function (chunk, final) { ZipPassThrough.prototype.push.call(this, chunk, final); }; return ZipDeflate; }()); exports.ZipDeflate = ZipDeflate; /** * Asynchronous streaming DEFLATE compression for ZIP archives */ var AsyncZipDeflate = /*#__PURE__*/ (function () { /** * Creates a DEFLATE stream that can be added to ZIP archives * @param filename The filename to associate with this data stream * @param opts The compression options */ function AsyncZipDeflate(filename, opts) { var _this_1 = this; if (!opts) opts = {}; ZipPassThrough.call(this, filename); this.d = new AsyncDeflate(opts, function (err, dat, final) { _this_1.ondata(err, dat, final); }); this.compression = 8; this.flag = dbf(opts.level); this.terminate = this.d.terminate; } AsyncZipDeflate.prototype.process = function (chunk, final) { this.d.push(chunk, final); }; /** * Pushes a chunk to be deflated * @param chunk The chunk to push * @param final Whether this is the last chunk */ AsyncZipDeflate.prototype.push = function (chunk, final) { ZipPassThrough.prototype.push.call(this, chunk, final); }; return AsyncZipDeflate; }()); exports.AsyncZipDeflate = AsyncZipDeflate; // TODO: Better tree shaking /** * A zippable archive to which files can incrementally be added */ var Zip = /*#__PURE__*/ (function () { /** * Creates an empty ZIP archive to which files can be added * @param cb The callback to call whenever data for the generated ZIP archive * is available */ function Zip(cb) { this.ondata = cb; this.u = []; this.d = 1; } /** * Adds a file to the ZIP archive * @param file The file stream to add */ Zip.prototype.add = function (file) { var _this_1 = this; if (!this.ondata) err(5); // finishing or finished if (this.d & 2) this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false); else { var f = strToU8(file.filename), fl_1 = f.length; var com = file.comment, o = com && strToU8(com); var u = fl_1 != file.filename.length || (o && (com.length != o.length)); var hl_1 = fl_1 + exfl(file.extra) + 30; if (fl_1 > 65535) this.ondata(err(11, 0, 1), null, false); var header = new u8(hl_1); wzh(header, 0, file, f, u); var chks_1 = [header]; var pAll_1 = function () { for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) { var chk = chks_2[_i]; _this_1.ondata(null, chk, false); } chks_1 = []; }; var tr_1 = this.d; this.d = 0; var ind_1 = this.u.length; var uf_1 = mrg(file, { f: f, u: u, o: o, t: function () { if (file.terminate) file.terminate(); }, r: function () { pAll_1(); if (tr_1) { var nxt = _this_1.u[ind_1 + 1]; if (nxt) nxt.r(); else _this_1.d = 1; } tr_1 = 1; } }); var cl_1 = 0; file.ondata = function (err, dat, final) { if (err) { _this_1.ondata(err, dat, final); _this_1.terminate(); } else { cl_1 += dat.length; chks_1.push(dat); if (final) { var dd = new u8(16); wbytes(dd, 0, 0x8074B50); wbytes(dd, 4, file.crc); wbytes(dd, 8, cl_1); wbytes(dd, 12, file.size); chks_1.push(dd); uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size; if (tr_1) uf_1.r(); tr_1 = 1; } else if (tr_1) pAll_1(); } }; this.u.push(uf_1); } }; /** * Ends the process of adding files and prepares to emit the final chunks. * This *must* be called after adding all desired files for the resulting * ZIP file to work properly. */ Zip.prototype.end = function () { var _this_1 = this; if (this.d & 2) { this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true); return; } if (this.d) this.e(); else this.u.push({ r: function () { if (!(_this_1.d & 1)) return; _this_1.u.splice(-1, 1); _this_1.e(); }, t: function () { } }); this.d = 3; }; Zip.prototype.e = function () { var bt = 0, l = 0, tl = 0; for (var _i = 0, _a = this.u; _i < _a.length; _i++) { var f = _a[_i]; tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0); } var out = new u8(tl + 22); for (var _b = 0, _c = this.u; _b < _c.length; _b++) { var f = _c[_b]; wzh(out, bt, f, f.f, f.u, f.c, l, f.o); bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b; } wzf(out, bt, this.u.length, tl, l); this.ondata(null, out, true); this.d = 2; }; /** * A method to terminate any internal workers used by the stream. Subsequent * calls to add() will fail. */ Zip.prototype.terminate = function () { for (var _i = 0, _a = this.u; _i < _a.length; _i++) { var f = _a[_i]; f.t(); } this.d = 2; }; return Zip; }()); exports.Zip = Zip; function zip(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); var r = {}; fltn(data, '', r, opts); var k = Object.keys(r); var lft = k.length, o = 0, tot = 0; var slft = lft, files = new Array(lft); var term = []; var tAll = function () { for (var i = 0; i < term.length; ++i) term[i](); }; var cbd = function (a, b) { mt(function () { cb(a, b); }); }; mt(function () { cbd = cb; }); var cbf = function () { var out = new u8(tot + 22), oe = o, cdl = tot - o; tot = 0; for (var i = 0; i < slft; ++i) { var f = files[i]; try { var l = f.c.length; wzh(out, tot, f, f.f, f.u, l); var badd = 30 + f.f.length + exfl(f.extra); var loc = tot + badd; out.set(f.c, loc); wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l; } catch (e) { return cbd(e, null); } } wzf(out, o, files.length, cdl, oe); cbd(null, out); }; if (!lft) cbf(); var _loop_1 = function (i) { var fn = k[i]; var _a = r[fn], file = _a[0], p = _a[1]; var c = crc(), size = file.length; c.p(file); var f = strToU8(fn), s = f.length; var com = p.comment, m = com && strToU8(com), ms = m && m.length; var exl = exfl(p.extra); var compression = p.level == 0 ? 0 : 8; var cbl = function (e, d) { if (e) { tAll(); cbd(e, null); } else { var l = d.length; files[i] = mrg(p, { size: size, crc: c.d(), c: d, f: f, m: m, u: s != fn.length || (m && (com.length != ms)), compression: compression }); o += 30 + s + exl + l; tot += 76 + 2 * (s + exl) + (ms || 0) + l; if (!--lft) cbf(); } }; if (s > 65535) cbl(err(11, 0, 1), null); if (!compression) cbl(null, file); else if (size < 160000) { try { cbl(null, deflateSync(file, p)); } catch (e) { cbl(e, null); } } else term.push(deflate(file, p, cbl)); }; // Cannot use lft because it can decrease for (var i = 0; i < slft; ++i) { _loop_1(i); } return tAll; } exports.zip = zip; /** * Synchronously creates a ZIP file. Prefer using `zip` for better performance * with more than one file. * @param data The directory structure for the ZIP archive * @param opts The main options, merged with per-file options * @returns The generated ZIP archive */ function zipSync(data, opts) { if (!opts) opts = {}; var r = {}; var files = []; fltn(data, '', r, opts); var o = 0; var tot = 0; for (var fn in r) { var _a = r[fn], file = _a[0], p = _a[1]; var compression = p.level == 0 ? 0 : 8; var f = strToU8(fn), s = f.length; var com = p.comment, m = com && strToU8(com), ms = m && m.length; var exl = exfl(p.extra); if (s > 65535) err(11); var d = compression ? deflateSync(file, p) : file, l = d.length; var c = crc(); c.p(file); files.push(mrg(p, { size: file.length, crc: c.d(), c: d, f: f, m: m, u: s != fn.length || (m && (com.length != ms)), o: o, compression: compression })); o += 30 + s + exl + l; tot += 76 + 2 * (s + exl) + (ms || 0) + l; } var out = new u8(tot + 22), oe = o, cdl = tot - o; for (var i = 0; i < files.length; ++i) { var f = files[i]; wzh(out, f.o, f, f.f, f.u, f.c.length); var badd = 30 + f.f.length + exfl(f.extra); out.set(f.c, f.o + badd); wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0); } wzf(out, o, files.length, cdl, oe); return out; } exports.zipSync = zipSync; /** * Streaming pass-through decompression for ZIP archives */ var UnzipPassThrough = /*#__PURE__*/ (function () { function UnzipPassThrough() { } UnzipPassThrough.prototype.push = function (data, final) { this.ondata(null, data, final); }; UnzipPassThrough.compression = 0; return UnzipPassThrough; }()); exports.UnzipPassThrough = UnzipPassThrough; /** * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for * better performance. */ var UnzipInflate = /*#__PURE__*/ (function () { /** * Creates a DEFLATE decompression that can be used in ZIP archives */ function UnzipInflate() { var _this_1 = this; this.i = new Inflate(function (dat, final) { _this_1.ondata(null, dat, final); }); } UnzipInflate.prototype.push = function (data, final) { try { this.i.push(data, final); } catch (e) { this.ondata(e, null, final); } }; UnzipInflate.compression = 8; return UnzipInflate; }()); exports.UnzipInflate = UnzipInflate; /** * Asynchronous streaming DEFLATE decompression for ZIP archives */ var AsyncUnzipInflate = /*#__PURE__*/ (function () { /** * Creates a DEFLATE decompression that can be used in ZIP archives */ function AsyncUnzipInflate(_, sz) { var _this_1 = this; if (sz < 320000) { this.i = new Inflate(function (dat, final) { _this_1.ondata(null, dat, final); }); } else { this.i = new AsyncInflate(function (err, dat, final) { _this_1.ondata(err, dat, final); }); this.terminate = this.i.terminate; } } AsyncUnzipInflate.prototype.push = function (data, final) { if (this.i.terminate) data = slc(data, 0); this.i.push(data, final); }; AsyncUnzipInflate.compression = 8; return AsyncUnzipInflate; }()); exports.AsyncUnzipInflate = AsyncUnzipInflate; /** * A ZIP archive decompression stream that emits files as they are discovered */ var Unzip = /*#__PURE__*/ (function () { /** * Creates a ZIP decompression stream * @param cb The callback to call whenever a file in the ZIP archive is found */ function Unzip(cb) { this.onfile = cb; this.k = []; this.o = { 0: UnzipPassThrough }; this.p = et; } /** * Pushes a chunk to be unzipped * @param chunk The chunk to push * @param final Whether this is the last chunk */ Unzip.prototype.push = function (chunk, final) { var _this_1 = this; if (!this.onfile) err(5); if (!this.p) err(4); if (this.c > 0) { var len = Math.min(this.c, chunk.length); var toAdd = chunk.subarray(0, len); this.c -= len; if (this.d) this.d.push(toAdd, !this.c); else this.k[0].push(toAdd); chunk = chunk.subarray(len); if (chunk.length) return this.push(chunk, final); } else { var f = 0, i = 0, is = void 0, buf = void 0; if (!this.p.length) buf = chunk; else if (!chunk.length) buf = this.p; else { buf = new u8(this.p.length + chunk.length); buf.set(this.p), buf.set(chunk, this.p.length); } var l = buf.length, oc = this.c, add = oc && this.d; var _loop_2 = function () { var _a; var sig = b4(buf, i); if (sig == 0x4034B50) { f = 1, is = i; this_1.d = null; this_1.c = 0; var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28); if (l > i + 30 + fnl + es) { var chks_3 = []; this_1.k.unshift(chks_3); f = 2; var sc_1 = b4(buf, i + 18), su_1 = b4(buf, i + 22); var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u); if (sc_1 == 4294967295) { _a = dd ? [-2] : z64e(buf, i), sc_1 = _a[0], su_1 = _a[1]; } else if (dd) sc_1 = -1; i += es; this_1.c = sc_1; var d_1; var file_1 = { name: fn_1, compression: cmp_1, start: function () { if (!file_1.ondata) err(5); if (!sc_1) file_1.ondata(null, et, true); else { var ctr = _this_1.o[cmp_1]; if (!ctr) file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false); d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1); d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); }; for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) { var dat = chks_4[_i]; d_1.push(dat, false); } if (_this_1.k[0] == chks_3 && _this_1.c) _this_1.d = d_1; else d_1.push(et, true); } }, terminate: function () { if (d_1 && d_1.terminate) d_1.terminate(); } }; if (sc_1 >= 0) file_1.size = sc_1, file_1.originalSize = su_1; this_1.onfile(file_1); } return "break"; } else if (oc) { if (sig == 0x8074B50) { is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0; return "break"; } else if (sig == 0x2014B50) { is = i -= 4, f = 3, this_1.c = 0; return "break"; } } }; var this_1 = this; for (; i < l - 4; ++i) { var state_1 = _loop_2(); if (state_1 === "break") break; } this.p = et; if (oc < 0) { var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i); if (add) add.push(dat, !!f); else this.k[+(f == 2)].push(dat); } if (f & 2) return this.push(buf.subarray(i), final); this.p = buf.subarray(i); } if (final) { if (this.c) err(13); this.p = null; } }; /** * Registers a decoder with the stream, allowing for files compressed with * the compression type provided to be expanded correctly * @param decoder The decoder constructor */ Unzip.prototype.register = function (decoder) { this.o[decoder.compression] = decoder; }; return Unzip; }()); exports.Unzip = Unzip; var mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); }; function unzip(data, opts, cb) { if (!cb) cb = opts, opts = {}; if (typeof cb != 'function') err(7); var term = []; var tAll = function () { for (var i = 0; i < term.length; ++i) term[i](); }; var files = {}; var cbd = function (a, b) { mt(function () { cb(a, b); }); }; mt(function () { cbd = cb; }); var e = data.length - 22; for (; b4(data, e) != 0x6054B50; --e) { if (!e || data.length - e > 65558) { cbd(err(13, 0, 1), null); return tAll; } } ; var lft = b2(data, e + 8); if (lft) { var c = lft; var o = b4(data, e + 16); var z = o == 4294967295; if (z) { e = b4(data, e - 12); if (b4(data, e) != 0x6064B50) { cbd(err(13, 0, 1), null); return tAll; } c = lft = b4(data, e + 32); o = b4(data, e + 48); } var fltr = opts && opts.filter; var _loop_3 = function (i) { var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off); o = no; var cbl = function (e, d) { if (e) { tAll(); cbd(e, null); } else { if (d) files[fn] = d; if (!--lft) cbd(null, files); } }; if (!fltr || fltr({ name: fn, size: sc, originalSize: su, compression: c_1 })) { if (!c_1) cbl(null, slc(data, b, b + sc)); else if (c_1 == 8) { var infl = data.subarray(b, b + sc); if (sc < 320000) { try { cbl(null, inflateSync(infl, new u8(su))); } catch (e) { cbl(e, null); } } else term.push(inflate(infl, { size: su }, cbl)); } else cbl(err(14, 'unknown compression type ' + c_1, 1), null); } else cbl(null, null); }; for (var i = 0; i < c; ++i) { _loop_3(i); } } else cbd(null, {}); return tAll; } exports.unzip = unzip; /** * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better * performance with more than one file. * @param data The raw compressed ZIP file * @param opts The ZIP extraction options * @returns The decompressed files */ function unzipSync(data, opts) { var files = {}; var e = data.length - 22; for (; b4(data, e) != 0x6054B50; --e) { if (!e || data.length - e > 65558) err(13); } ; var c = b2(data, e + 8); if (!c) return {}; var o = b4(data, e + 16); var z = o == 4294967295; if (z) { e = b4(data, e - 12); if (b4(data, e) != 0x6064B50) err(13); c = b4(data, e + 32); o = b4(data, e + 48); } var fltr = opts && opts.filter; for (var i = 0; i < c; ++i) { var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off); o = no; if (!fltr || fltr({ name: fn, size: sc, originalSize: su, compression: c_2 })) { if (!c_2) files[fn] = slc(data, b, b + sc); else if (c_2 == 8) files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su)); else err(14, 'unknown compression type ' + c_2); } } return files; } exports.unzipSync = unzipSync; /***/ }), /***/ "./node_modules/fflate/lib/worker.cjs": /***/ ((__unused_webpack_module, exports) => { "use strict"; var ch2 = {}; exports["default"] = (function (c, id, msg, transfer, cb) { var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([ c + ';addEventListener("error",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})' ], { type: 'text/javascript' })))); w.onmessage = function (e) { var d = e.data, ed = d.$e$; if (ed) { var err = new Error(ed[0]); err['code'] = ed[1]; err.stack = ed[2]; cb(err, null); } else cb(null, d); }; w.postMessage(msg, transfer); return w; }); /***/ }), /***/ "./node_modules/idb-keyval/dist/index.js": /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "clear": () => (/* binding */ clear), "createStore": () => (/* binding */ createStore), "del": () => (/* binding */ del), "delMany": () => (/* binding */ delMany), "entries": () => (/* binding */ entries), "get": () => (/* binding */ get), "getMany": () => (/* binding */ getMany), "keys": () => (/* binding */ keys), "promisifyRequest": () => (/* binding */ promisifyRequest), "set": () => (/* binding */ set), "setMany": () => (/* binding */ setMany), "update": () => (/* binding */ update), "values": () => (/* binding */ values) }); ;// CONCATENATED MODULE: ./node_modules/safari-14-idb-fix/dist/index.js /** * Work around Safari 14 IndexedDB open bug. * * Safari has a horrible bug where IDB requests can hang while the browser is starting up. https://bugs.webkit.org/show_bug.cgi?id=226547 * The only solution is to keep nudging it until it's awake. */ function idbReady() { var isSafari = !navigator.userAgentData && /Safari\//.test(navigator.userAgent) && !/Chrom(e|ium)\//.test(navigator.userAgent); // No point putting other browsers or older versions of Safari through this mess. if (!isSafari || !indexedDB.databases) return Promise.resolve(); var intervalId; return new Promise(function (resolve) { var tryIdb = function () { return indexedDB.databases().finally(resolve); }; intervalId = setInterval(tryIdb, 100); tryIdb(); }).finally(function () { return clearInterval(intervalId); }); } /* harmony default export */ const dist = (idbReady); ;// CONCATENATED MODULE: ./node_modules/idb-keyval/dist/index.js function promisifyRequest(request) { return new Promise((resolve, reject) => { // @ts-ignore - file size hacks request.oncomplete = request.onsuccess = () => resolve(request.result); // @ts-ignore - file size hacks request.onabort = request.onerror = () => reject(request.error); }); } function createStore(dbName, storeName) { const dbp = dist().then(() => { const request = indexedDB.open(dbName); request.onupgradeneeded = () => request.result.createObjectStore(storeName); return promisifyRequest(request); }); return (txMode, callback) => dbp.then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName))); } let defaultGetStoreFunc; function defaultGetStore() { if (!defaultGetStoreFunc) { defaultGetStoreFunc = createStore('keyval-store', 'keyval'); } return defaultGetStoreFunc; } /** * Get a value by its key. * * @param key * @param customStore Method to get a custom store. Use with caution (see the docs). */ function get(key, customStore = defaultGetStore()) { return customStore('readonly', (store) => promisifyRequest(store.get(key))); } /** * Set a value with a key. * * @param key * @param value * @param customStore Method to get a custom store. Use with caution (see the docs). */ function set(key, value, customStore = defaultGetStore()) { return customStore('readwrite', (store) => { store.put(value, key); return promisifyRequest(store.transaction); }); } /** * Set multiple values at once. This is faster than calling set() multiple times. * It's also atomic – if one of the pairs can't be added, none will be added. * * @param entries Array of entries, where each entry is an array of `[key, value]`. * @param customStore Method to get a custom store. Use with caution (see the docs). */ function setMany(entries, customStore = defaultGetStore()) { return customStore('readwrite', (store) => { entries.forEach((entry) => store.put(entry[1], entry[0])); return promisifyRequest(store.transaction); }); } /** * Get multiple values by their keys * * @param keys * @param customStore Method to get a custom store. Use with caution (see the docs). */ function getMany(keys, customStore = defaultGetStore()) { return customStore('readonly', (store) => Promise.all(keys.map((key) => promisifyRequest(store.get(key))))); } /** * Update a value. This lets you see the old value and update it as an atomic operation. * * @param key * @param updater A callback that takes the old value and returns a new value. * @param customStore Method to get a custom store. Use with caution (see the docs). */ function update(key, updater, customStore = defaultGetStore()) { return customStore('readwrite', (store) => // Need to create the promise manually. // If I try to chain promises, the transaction closes in browsers // that use a promise polyfill (IE10/11). new Promise((resolve, reject) => { store.get(key).onsuccess = function () { try { store.put(updater(this.result), key); resolve(promisifyRequest(store.transaction)); } catch (err) { reject(err); } }; })); } /** * Delete a particular key from the store. * * @param key * @param customStore Method to get a custom store. Use with caution (see the docs). */ function del(key, customStore = defaultGetStore()) { return customStore('readwrite', (store) => { store.delete(key); return promisifyRequest(store.transaction); }); } /** * Delete multiple keys at once. * * @param keys List of keys to delete. * @param customStore Method to get a custom store. Use with caution (see the docs). */ function delMany(keys, customStore = defaultGetStore()) { return customStore('readwrite', (store) => { keys.forEach((key) => store.delete(key)); return promisifyRequest(store.transaction); }); } /** * Clear all values in the store. * * @param customStore Method to get a custom store. Use with caution (see the docs). */ function clear(customStore = defaultGetStore()) { return customStore('readwrite', (store) => { store.clear(); return promisifyRequest(store.transaction); }); } function eachCursor(customStore, callback) { return customStore('readonly', (store) => { // This would be store.getAllKeys(), but it isn't supported by Edge or Safari. // And openKeyCursor isn't supported by Safari. store.openCursor().onsuccess = function () { if (!this.result) return; callback(this.result); this.result.continue(); }; return promisifyRequest(store.transaction); }); } /** * Get all keys in the store. * * @param customStore Method to get a custom store. Use with caution (see the docs). */ function keys(customStore = defaultGetStore()) { const items = []; return eachCursor(customStore, (cursor) => items.push(cursor.key)).then(() => items); } /** * Get all values in the store. * * @param customStore Method to get a custom store. Use with caution (see the docs). */ function values(customStore = defaultGetStore()) { const items = []; return eachCursor(customStore, (cursor) => items.push(cursor.value)).then(() => items); } /** * Get all entries in the store. Each entry is an array of `[key, value]`. * * @param customStore Method to get a custom store. Use with caution (see the docs). */ function entries(customStore = defaultGetStore()) { const items = []; return eachCursor(customStore, (cursor) => items.push([cursor.key, cursor.value])).then(() => items); } /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be in strict mode. (() => { "use strict"; var exports = __webpack_exports__; var __webpack_unused_export__; __webpack_unused_export__ = ({ value: true }); const routers_1 = __webpack_require__("./src/routers.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const log_1 = __webpack_require__("./src/log.ts"); const global_1 = __webpack_require__("./src/global.ts"); const detect_1 = __webpack_require__("./src/detect.ts"); function printEnvironments() { log_1.log.info("[Init]开始载入小说下载器……"); Object.entries(detect_1.environments).forEach((kv) => log_1.log.info("[Init]" + kv.join(":"))); } async function run() { const ruleClass = await (0, routers_1.getRule)(); await ruleClass.run(); } function addButton() { const buttonStyleText = `position: fixed; top: 15%; right: 5%; z-index: 2147483647; border-style: none; text-align:center; vertical-align:baseline; background-color: rgba(128, 128, 128, 0.2); padding: 5px; border-radius: 12px; min-width: auto; min-height: auto;`; const button = document.createElement("button"); button.id = "novel-downloader"; button.style.cssText = buttonStyleText; const img = document.createElement("img"); img.src = setting_1.icon0; img.style.cssText = "height: 2em;"; button.onclick = function () { if (window.downloading) { alert("正在下载中,请耐心等待……"); } else { img.src = setting_1.icon1; run().then(() => { img.src = setting_1.icon0; }); } }; button.appendChild(img); document.body.appendChild(button); } async function debug() { const rule = await (0, routers_1.getRule)(); const book = await rule.bookParse(); unsafeWindow.rule = rule; unsafeWindow.book = book; unsafeWindow.saveAs = saveAs; return; } function main() { printEnvironments(); (0, global_1.init)(); addButton(); if (setting_1.enaleDebug) { setTimeout(debug, 3000); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", (event) => { main(); }); } else { main(); } })(); /******/ })() ;