您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一个可扩展的通用型小说下载器。
当前为
// ==UserScript== // @name 小说下载器 // @version 4.4.9.311 // @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 *://m.shuquge.com/s/*.html // @match *://m.shuquge.com/d/*.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.bz01.org/*_*/ // @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/*/ // @match *://www.tycqxs.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 sina.com.cn // @connect * // @require https://cdn.jsdelivr.net/npm/[email protected]/crypto-js.js#sha256-8L3yX9qPmvWSDIIHB3WGTH4RZusxVA0DDmuAo4LjnOE= // @require https://cdn.jsdelivr.net/npm/[email protected]/browser/nunjucks.min.js#sha256-+CJElYLgP9RjEvMt/VTU1+qF8CuntjliUUBKp26fPck= // ==/UserScript== /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/@mozilla/readability/Readability-readerable.js": /***/ ((module) => { /* eslint-env es6:false */ /* * Copyright (c) 2010 Arc90 Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This code is heavily based on Arc90's readability.js (1.7.1) script * available at: http://code.google.com/p/arc90labs-readability */ var REGEXPS = { // NOTE: These two regular expressions are duplicated in // Readability.js. Please keep both copies in sync. unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i, okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i, }; function isNodeVisible(node) { // Have to null-check node.style and node.className.indexOf to deal with SVG and MathML nodes. return (!node.style || node.style.display != "none") && !node.hasAttribute("hidden") //check for "fallback-image" so that wikimedia math images are displayed && (!node.hasAttribute("aria-hidden") || node.getAttribute("aria-hidden") != "true" || (node.className && node.className.indexOf && node.className.indexOf("fallback-image") !== -1)); } /** * Decides whether or not the document is reader-able without parsing the whole thing. * @param {Object} options Configuration object. * @param {number} [options.minContentLength=140] The minimum node content length used to decide if the document is readerable. * @param {number} [options.minScore=20] The minumum cumulated 'score' used to determine if the document is readerable. * @param {Function} [options.visibilityChecker=isNodeVisible] The function used to determine if a node is visible. * @return {boolean} Whether or not we suspect Readability.parse() will suceeed at returning an article object. */ function isProbablyReaderable(doc, options = {}) { // For backward compatibility reasons 'options' can either be a configuration object or the function used // to determine if a node is visible. if (typeof options == "function") { options = { visibilityChecker: options }; } var defaultOptions = { minScore: 20, minContentLength: 140, visibilityChecker: isNodeVisible }; options = Object.assign(defaultOptions, options); var nodes = doc.querySelectorAll("p, pre"); // Get <div> nodes which have <br> node(s) and append them into the `nodes` variable. // Some articles' DOM structures might look like // <div> // Sentences<br> // <br> // Sentences<br> // </div> var brNodes = doc.querySelectorAll("div > br"); if (brNodes.length) { var set = new Set(nodes); [].forEach.call(brNodes, function (node) { set.add(node.parentNode); }); nodes = Array.from(set); } var score = 0; // This is a little cheeky, we use the accumulator 'score' to decide what to return from // this callback: return [].some.call(nodes, function (node) { if (!options.visibilityChecker(node)) { return false; } var matchString = node.className + " " + node.id; if (REGEXPS.unlikelyCandidates.test(matchString) && !REGEXPS.okMaybeItsACandidate.test(matchString)) { return false; } if (node.matches("li p")) { return false; } var textContentLength = node.textContent.trim().length; if (textContentLength < options.minContentLength) { return false; } score += Math.sqrt(textContentLength - options.minContentLength); if (score > options.minScore) { return true; } return false; }); } if (true) { module.exports = isProbablyReaderable; } /***/ }), /***/ "./node_modules/@mozilla/readability/Readability.js": /***/ ((module) => { /*eslint-env es6:false*/ /* * Copyright (c) 2010 Arc90 Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This code is heavily based on Arc90's readability.js (1.7.1) script * available at: http://code.google.com/p/arc90labs-readability */ /** * Public constructor. * @param {HTMLDocument} doc The document to parse. * @param {Object} options The options object. */ function Readability(doc, options) { // In some older versions, people passed a URI as the first argument. Cope: if (options && options.documentElement) { doc = options; options = arguments[2]; } else if (!doc || !doc.documentElement) { throw new Error("First argument to Readability constructor should be a document object."); } options = options || {}; this._doc = doc; this._docJSDOMParser = this._doc.firstChild.__JSDOMParser__; this._articleTitle = null; this._articleByline = null; this._articleDir = null; this._articleSiteName = null; this._attempts = []; // Configurable options this._debug = !!options.debug; this._maxElemsToParse = options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE; this._nbTopCandidates = options.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES; this._charThreshold = options.charThreshold || this.DEFAULT_CHAR_THRESHOLD; this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(options.classesToPreserve || []); this._keepClasses = !!options.keepClasses; this._serializer = options.serializer || function(el) { return el.innerHTML; }; this._disableJSONLD = !!options.disableJSONLD; // Start with all flags set this._flags = this.FLAG_STRIP_UNLIKELYS | this.FLAG_WEIGHT_CLASSES | this.FLAG_CLEAN_CONDITIONALLY; // Control whether log messages are sent to the console if (this._debug) { let logNode = function(node) { if (node.nodeType == node.TEXT_NODE) { return `${node.nodeName} ("${node.textContent}")`; } let attrPairs = Array.from(node.attributes || [], function(attr) { return `${attr.name}="${attr.value}"`; }).join(" "); return `<${node.localName} ${attrPairs}>`; }; this.log = function () { if (typeof dump !== "undefined") { var msg = Array.prototype.map.call(arguments, function(x) { return (x && x.nodeName) ? logNode(x) : x; }).join(" "); dump("Reader: (Readability) " + msg + "\n"); } else if (typeof console !== "undefined") { let args = Array.from(arguments, arg => { if (arg && arg.nodeType == this.ELEMENT_NODE) { return logNode(arg); } return arg; }); args.unshift("Reader: (Readability)"); console.log.apply(console, args); } }; } else { this.log = function () {}; } } Readability.prototype = { FLAG_STRIP_UNLIKELYS: 0x1, FLAG_WEIGHT_CLASSES: 0x2, FLAG_CLEAN_CONDITIONALLY: 0x4, // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType ELEMENT_NODE: 1, TEXT_NODE: 3, // Max number of nodes supported by this parser. Default: 0 (no limit) DEFAULT_MAX_ELEMS_TO_PARSE: 0, // The number of top candidates to consider when analysing how // tight the competition is among candidates. DEFAULT_N_TOP_CANDIDATES: 5, // Element tags to score by default. DEFAULT_TAGS_TO_SCORE: "section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","), // The default number of chars an article must have in order to return a result DEFAULT_CHAR_THRESHOLD: 500, // All of the regular expressions in use within readability. // Defined up here so we don't instantiate them repeatedly in loops. REGEXPS: { // NOTE: These two regular expressions are duplicated in // Readability-readerable.js. Please keep both copies in sync. unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i, okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i, positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i, negative: /-ad-|hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i, extraneous: /print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i, byline: /byline|author|dateline|writtenby|p-author/i, replaceFonts: /<(\/?)font[^>]*>/gi, normalize: /\s{2,}/g, videos: /\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i, shareElements: /(\b|_)(share|sharedaddy)(\b|_)/i, nextLink: /(next|weiter|continue|>([^\|]|$)|»([^\|]|$))/i, prevLink: /(prev|earl|old|new|<|«)/i, tokenize: /\W+/g, whitespace: /^\s*$/, hasContent: /\S$/, hashUrl: /^#.+/, srcsetUrl: /(\S+)(\s+[\d.]+[xw])?(\s*(?:,|$))/g, b64DataUrl: /^data:\s*([^\s;,]+)\s*;\s*base64\s*,/i, // See: https://schema.org/Article jsonLdArticleTypes: /^Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|AskPublicNewsArticle|BackgroundNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|SatiricalArticle|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference$/ }, UNLIKELY_ROLES: [ "menu", "menubar", "complementary", "navigation", "alert", "alertdialog", "dialog" ], DIV_TO_P_ELEMS: new Set([ "BLOCKQUOTE", "DL", "DIV", "IMG", "OL", "P", "PRE", "TABLE", "UL" ]), ALTER_TO_DIV_EXCEPTIONS: ["DIV", "ARTICLE", "SECTION", "P"], PRESENTATIONAL_ATTRIBUTES: [ "align", "background", "bgcolor", "border", "cellpadding", "cellspacing", "frame", "hspace", "rules", "style", "valign", "vspace" ], DEPRECATED_SIZE_ATTRIBUTE_ELEMS: [ "TABLE", "TH", "TD", "HR", "PRE" ], // The commented out elements qualify as phrasing content but tend to be // removed by readability when put into paragraphs, so we ignore them here. PHRASING_ELEMS: [ // "CANVAS", "IFRAME", "SVG", "VIDEO", "ABBR", "AUDIO", "B", "BDO", "BR", "BUTTON", "CITE", "CODE", "DATA", "DATALIST", "DFN", "EM", "EMBED", "I", "IMG", "INPUT", "KBD", "LABEL", "MARK", "MATH", "METER", "NOSCRIPT", "OBJECT", "OUTPUT", "PROGRESS", "Q", "RUBY", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRONG", "SUB", "SUP", "TEXTAREA", "TIME", "VAR", "WBR" ], // These are the classes that readability sets itself. CLASSES_TO_PRESERVE: [ "page" ], // These are the list of HTML entities that need to be escaped. HTML_ESCAPE_MAP: { "lt": "<", "gt": ">", "amp": "&", "quot": '"', "apos": "'", }, /** * Run any post-process modifications to article content as necessary. * * @param Element * @return void **/ _postProcessContent: function(articleContent) { // Readability cannot open relative uris so we convert them to absolute uris. this._fixRelativeUris(articleContent); this._simplifyNestedElements(articleContent); if (!this._keepClasses) { // Remove classes. this._cleanClasses(articleContent); } }, /** * Iterates over a NodeList, calls `filterFn` for each node and removes node * if function returned `true`. * * If function is not passed, removes all the nodes in node list. * * @param NodeList nodeList The nodes to operate on * @param Function filterFn the function to use as a filter * @return void */ _removeNodes: function(nodeList, filterFn) { // Avoid ever operating on live node lists. if (this._docJSDOMParser && nodeList._isLiveNodeList) { throw new Error("Do not pass live node lists to _removeNodes"); } for (var i = nodeList.length - 1; i >= 0; i--) { var node = nodeList[i]; var parentNode = node.parentNode; if (parentNode) { if (!filterFn || filterFn.call(this, node, i, nodeList)) { parentNode.removeChild(node); } } } }, /** * Iterates over a NodeList, and calls _setNodeTag for each node. * * @param NodeList nodeList The nodes to operate on * @param String newTagName the new tag name to use * @return void */ _replaceNodeTags: function(nodeList, newTagName) { // Avoid ever operating on live node lists. if (this._docJSDOMParser && nodeList._isLiveNodeList) { throw new Error("Do not pass live node lists to _replaceNodeTags"); } for (const node of nodeList) { this._setNodeTag(node, newTagName); } }, /** * Iterate over a NodeList, which doesn't natively fully implement the Array * interface. * * For convenience, the current object context is applied to the provided * iterate function. * * @param NodeList nodeList The NodeList. * @param Function fn The iterate function. * @return void */ _forEachNode: function(nodeList, fn) { Array.prototype.forEach.call(nodeList, fn, this); }, /** * Iterate over a NodeList, and return the first node that passes * the supplied test function * * For convenience, the current object context is applied to the provided * test function. * * @param NodeList nodeList The NodeList. * @param Function fn The test function. * @return void */ _findNode: function(nodeList, fn) { return Array.prototype.find.call(nodeList, fn, this); }, /** * Iterate over a NodeList, return true if any of the provided iterate * function calls returns true, false otherwise. * * For convenience, the current object context is applied to the * provided iterate function. * * @param NodeList nodeList The NodeList. * @param Function fn The iterate function. * @return Boolean */ _someNode: function(nodeList, fn) { return Array.prototype.some.call(nodeList, fn, this); }, /** * Iterate over a NodeList, return true if all of the provided iterate * function calls return true, false otherwise. * * For convenience, the current object context is applied to the * provided iterate function. * * @param NodeList nodeList The NodeList. * @param Function fn The iterate function. * @return Boolean */ _everyNode: function(nodeList, fn) { return Array.prototype.every.call(nodeList, fn, this); }, /** * Concat all nodelists passed as arguments. * * @return ...NodeList * @return Array */ _concatNodeLists: function() { var slice = Array.prototype.slice; var args = slice.call(arguments); var nodeLists = args.map(function(list) { return slice.call(list); }); return Array.prototype.concat.apply([], nodeLists); }, _getAllNodesWithTag: function(node, tagNames) { if (node.querySelectorAll) { return node.querySelectorAll(tagNames.join(",")); } return [].concat.apply([], tagNames.map(function(tag) { var collection = node.getElementsByTagName(tag); return Array.isArray(collection) ? collection : Array.from(collection); })); }, /** * Removes the class="" attribute from every element in the given * subtree, except those that match CLASSES_TO_PRESERVE and * the classesToPreserve array from the options object. * * @param Element * @return void */ _cleanClasses: function(node) { var classesToPreserve = this._classesToPreserve; var className = (node.getAttribute("class") || "") .split(/\s+/) .filter(function(cls) { return classesToPreserve.indexOf(cls) != -1; }) .join(" "); if (className) { node.setAttribute("class", className); } else { node.removeAttribute("class"); } for (node = node.firstElementChild; node; node = node.nextElementSibling) { this._cleanClasses(node); } }, /** * Converts each <a> and <img> uri in the given element to an absolute URI, * ignoring #ref URIs. * * @param Element * @return void */ _fixRelativeUris: function(articleContent) { var baseURI = this._doc.baseURI; var documentURI = this._doc.documentURI; function toAbsoluteURI(uri) { // Leave hash links alone if the base URI matches the document URI: if (baseURI == documentURI && uri.charAt(0) == "#") { return uri; } // Otherwise, resolve against base URI: try { return new URL(uri, baseURI).href; } catch (ex) { // Something went wrong, just return the original: } return uri; } var links = this._getAllNodesWithTag(articleContent, ["a"]); this._forEachNode(links, function(link) { var href = link.getAttribute("href"); if (href) { // Remove links with javascript: URIs, since // they won't work after scripts have been removed from the page. if (href.indexOf("javascript:") === 0) { // if the link only contains simple text content, it can be converted to a text node if (link.childNodes.length === 1 && link.childNodes[0].nodeType === this.TEXT_NODE) { var text = this._doc.createTextNode(link.textContent); link.parentNode.replaceChild(text, link); } else { // if the link has multiple children, they should all be preserved var container = this._doc.createElement("span"); while (link.childNodes.length > 0) { container.appendChild(link.childNodes[0]); } link.parentNode.replaceChild(container, link); } } else { link.setAttribute("href", toAbsoluteURI(href)); } } }); var medias = this._getAllNodesWithTag(articleContent, [ "img", "picture", "figure", "video", "audio", "source" ]); this._forEachNode(medias, function(media) { var src = media.getAttribute("src"); var poster = media.getAttribute("poster"); var srcset = media.getAttribute("srcset"); if (src) { media.setAttribute("src", toAbsoluteURI(src)); } if (poster) { media.setAttribute("poster", toAbsoluteURI(poster)); } if (srcset) { var newSrcset = srcset.replace(this.REGEXPS.srcsetUrl, function(_, p1, p2, p3) { return toAbsoluteURI(p1) + (p2 || "") + p3; }); media.setAttribute("srcset", newSrcset); } }); }, _simplifyNestedElements: function(articleContent) { var node = articleContent; while (node) { if (node.parentNode && ["DIV", "SECTION"].includes(node.tagName) && !(node.id && node.id.startsWith("readability"))) { if (this._isElementWithoutContent(node)) { node = this._removeAndGetNext(node); continue; } else if (this._hasSingleTagInsideElement(node, "DIV") || this._hasSingleTagInsideElement(node, "SECTION")) { var child = node.children[0]; for (var i = 0; i < node.attributes.length; i++) { child.setAttribute(node.attributes[i].name, node.attributes[i].value); } node.parentNode.replaceChild(child, node); node = child; continue; } } node = this._getNextNode(node); } }, /** * Get the article title as an H1. * * @return string **/ _getArticleTitle: function() { var doc = this._doc; var curTitle = ""; var origTitle = ""; try { curTitle = origTitle = doc.title.trim(); // If they had an element with id "title" in their HTML if (typeof curTitle !== "string") curTitle = origTitle = this._getInnerText(doc.getElementsByTagName("title")[0]); } catch (e) {/* ignore exceptions setting the title. */} var titleHadHierarchicalSeparators = false; function wordCount(str) { return str.split(/\s+/).length; } // If there's a separator in the title, first remove the final part if ((/ [\|\-\\\/>»] /).test(curTitle)) { titleHadHierarchicalSeparators = / [\\\/>»] /.test(curTitle); curTitle = origTitle.replace(/(.*)[\|\-\\\/>»] .*/gi, "$1"); // If the resulting title is too short (3 words or fewer), remove // the first part instead: if (wordCount(curTitle) < 3) curTitle = origTitle.replace(/[^\|\-\\\/>»]*[\|\-\\\/>»](.*)/gi, "$1"); } else if (curTitle.indexOf(": ") !== -1) { // Check if we have an heading containing this exact string, so we // could assume it's the full title. var headings = this._concatNodeLists( doc.getElementsByTagName("h1"), doc.getElementsByTagName("h2") ); var trimmedTitle = curTitle.trim(); var match = this._someNode(headings, function(heading) { return heading.textContent.trim() === trimmedTitle; }); // If we don't, let's extract the title out of the original title string. if (!match) { curTitle = origTitle.substring(origTitle.lastIndexOf(":") + 1); // If the title is now too short, try the first colon instead: if (wordCount(curTitle) < 3) { curTitle = origTitle.substring(origTitle.indexOf(":") + 1); // But if we have too many words before the colon there's something weird // with the titles and the H tags so let's just use the original title instead } else if (wordCount(origTitle.substr(0, origTitle.indexOf(":"))) > 5) { curTitle = origTitle; } } } else if (curTitle.length > 150 || curTitle.length < 15) { var hOnes = doc.getElementsByTagName("h1"); if (hOnes.length === 1) curTitle = this._getInnerText(hOnes[0]); } curTitle = curTitle.trim().replace(this.REGEXPS.normalize, " "); // If we now have 4 words or fewer as our title, and either no // 'hierarchical' separators (\, /, > or ») were found in the original // title or we decreased the number of words by more than 1 word, use // the original title. var curTitleWordCount = wordCount(curTitle); if (curTitleWordCount <= 4 && (!titleHadHierarchicalSeparators || curTitleWordCount != wordCount(origTitle.replace(/[\|\-\\\/>»]+/g, "")) - 1)) { curTitle = origTitle; } return curTitle; }, /** * Prepare the HTML document for readability to scrape it. * This includes things like stripping javascript, CSS, and handling terrible markup. * * @return void **/ _prepDocument: function() { var doc = this._doc; // Remove all style tags in head this._removeNodes(this._getAllNodesWithTag(doc, ["style"])); if (doc.body) { this._replaceBrs(doc.body); } this._replaceNodeTags(this._getAllNodesWithTag(doc, ["font"]), "SPAN"); }, /** * Finds the next node, starting from the given node, and ignoring * whitespace in between. If the given node is an element, the same node is * returned. */ _nextNode: function (node) { var next = node; while (next && (next.nodeType != this.ELEMENT_NODE) && this.REGEXPS.whitespace.test(next.textContent)) { next = next.nextSibling; } return next; }, /** * Replaces 2 or more successive <br> elements with a single <p>. * Whitespace between <br> elements are ignored. For example: * <div>foo<br>bar<br> <br><br>abc</div> * will become: * <div>foo<br>bar<p>abc</p></div> */ _replaceBrs: function (elem) { this._forEachNode(this._getAllNodesWithTag(elem, ["br"]), function(br) { var next = br.nextSibling; // Whether 2 or more <br> elements have been found and replaced with a // <p> block. var replaced = false; // If we find a <br> chain, remove the <br>s until we hit another node // or non-whitespace. This leaves behind the first <br> in the chain // (which will be replaced with a <p> later). while ((next = this._nextNode(next)) && (next.tagName == "BR")) { replaced = true; var brSibling = next.nextSibling; next.parentNode.removeChild(next); next = brSibling; } // If we removed a <br> chain, replace the remaining <br> with a <p>. Add // all sibling nodes as children of the <p> until we hit another <br> // chain. if (replaced) { var p = this._doc.createElement("p"); br.parentNode.replaceChild(p, br); next = p.nextSibling; while (next) { // If we've hit another <br><br>, we're done adding children to this <p>. if (next.tagName == "BR") { var nextElem = this._nextNode(next.nextSibling); if (nextElem && nextElem.tagName == "BR") break; } if (!this._isPhrasingContent(next)) break; // Otherwise, make this node a child of the new <p>. var sibling = next.nextSibling; p.appendChild(next); next = sibling; } while (p.lastChild && this._isWhitespace(p.lastChild)) { p.removeChild(p.lastChild); } if (p.parentNode.tagName === "P") this._setNodeTag(p.parentNode, "DIV"); } }); }, _setNodeTag: function (node, tag) { this.log("_setNodeTag", node, tag); if (this._docJSDOMParser) { node.localName = tag.toLowerCase(); node.tagName = tag.toUpperCase(); return node; } var replacement = node.ownerDocument.createElement(tag); while (node.firstChild) { replacement.appendChild(node.firstChild); } node.parentNode.replaceChild(replacement, node); if (node.readability) replacement.readability = node.readability; for (var i = 0; i < node.attributes.length; i++) { try { replacement.setAttribute(node.attributes[i].name, node.attributes[i].value); } catch (ex) { /* it's possible for setAttribute() to throw if the attribute name * isn't a valid XML Name. Such attributes can however be parsed from * source in HTML docs, see https://github.com/whatwg/html/issues/4275, * so we can hit them here and then throw. We don't care about such * attributes so we ignore them. */ } } return replacement; }, /** * Prepare the article node for display. Clean out any inline styles, * iframes, forms, strip extraneous <p> tags, etc. * * @param Element * @return void **/ _prepArticle: function(articleContent) { this._cleanStyles(articleContent); // Check for data tables before we continue, to avoid removing items in // those tables, which will often be isolated even though they're // visually linked to other content-ful elements (text, images, etc.). this._markDataTables(articleContent); this._fixLazyImages(articleContent); // Clean out junk from the article content this._cleanConditionally(articleContent, "form"); this._cleanConditionally(articleContent, "fieldset"); this._clean(articleContent, "object"); this._clean(articleContent, "embed"); this._clean(articleContent, "footer"); this._clean(articleContent, "link"); this._clean(articleContent, "aside"); // Clean out elements with little content that have "share" in their id/class combinations from final top candidates, // which means we don't remove the top candidates even they have "share". var shareElementThreshold = this.DEFAULT_CHAR_THRESHOLD; this._forEachNode(articleContent.children, function (topCandidate) { this._cleanMatchedNodes(topCandidate, function (node, matchString) { return this.REGEXPS.shareElements.test(matchString) && node.textContent.length < shareElementThreshold; }); }); this._clean(articleContent, "iframe"); this._clean(articleContent, "input"); this._clean(articleContent, "textarea"); this._clean(articleContent, "select"); this._clean(articleContent, "button"); this._cleanHeaders(articleContent); // Do these last as the previous stuff may have removed junk // that will affect these this._cleanConditionally(articleContent, "table"); this._cleanConditionally(articleContent, "ul"); this._cleanConditionally(articleContent, "div"); // replace H1 with H2 as H1 should be only title that is displayed separately this._replaceNodeTags(this._getAllNodesWithTag(articleContent, ["h1"]), "h2"); // Remove extra paragraphs this._removeNodes(this._getAllNodesWithTag(articleContent, ["p"]), function (paragraph) { var imgCount = paragraph.getElementsByTagName("img").length; var embedCount = paragraph.getElementsByTagName("embed").length; var objectCount = paragraph.getElementsByTagName("object").length; // At this point, nasty iframes have been removed, only remain embedded video ones. var iframeCount = paragraph.getElementsByTagName("iframe").length; var totalCount = imgCount + embedCount + objectCount + iframeCount; return totalCount === 0 && !this._getInnerText(paragraph, false); }); this._forEachNode(this._getAllNodesWithTag(articleContent, ["br"]), function(br) { var next = this._nextNode(br.nextSibling); if (next && next.tagName == "P") br.parentNode.removeChild(br); }); // Remove single-cell tables this._forEachNode(this._getAllNodesWithTag(articleContent, ["table"]), function(table) { var tbody = this._hasSingleTagInsideElement(table, "TBODY") ? table.firstElementChild : table; if (this._hasSingleTagInsideElement(tbody, "TR")) { var row = tbody.firstElementChild; if (this._hasSingleTagInsideElement(row, "TD")) { var cell = row.firstElementChild; cell = this._setNodeTag(cell, this._everyNode(cell.childNodes, this._isPhrasingContent) ? "P" : "DIV"); table.parentNode.replaceChild(cell, table); } } }); }, /** * Initialize a node with the readability object. Also checks the * className/id for special names to add to its score. * * @param Element * @return void **/ _initializeNode: function(node) { node.readability = {"contentScore": 0}; switch (node.tagName) { case "DIV": node.readability.contentScore += 5; break; case "PRE": case "TD": case "BLOCKQUOTE": node.readability.contentScore += 3; break; case "ADDRESS": case "OL": case "UL": case "DL": case "DD": case "DT": case "LI": case "FORM": node.readability.contentScore -= 3; break; case "H1": case "H2": case "H3": case "H4": case "H5": case "H6": case "TH": node.readability.contentScore -= 5; break; } node.readability.contentScore += this._getClassWeight(node); }, _removeAndGetNext: function(node) { var nextNode = this._getNextNode(node, true); node.parentNode.removeChild(node); return nextNode; }, /** * Traverse the DOM from node to node, starting at the node passed in. * Pass true for the second parameter to indicate this node itself * (and its kids) are going away, and we want the next node over. * * Calling this in a loop will traverse the DOM depth-first. */ _getNextNode: function(node, ignoreSelfAndKids) { // First check for kids if those aren't being ignored if (!ignoreSelfAndKids && node.firstElementChild) { return node.firstElementChild; } // Then for siblings... if (node.nextElementSibling) { return node.nextElementSibling; } // And finally, move up the parent chain *and* find a sibling // (because this is depth-first traversal, we will have already // seen the parent nodes themselves). do { node = node.parentNode; } while (node && !node.nextElementSibling); return node && node.nextElementSibling; }, // compares second text to first one // 1 = same text, 0 = completely different text // works the way that it splits both texts into words and then finds words that are unique in second text // the result is given by the lower length of unique parts _textSimilarity: function(textA, textB) { var tokensA = textA.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean); var tokensB = textB.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean); if (!tokensA.length || !tokensB.length) { return 0; } var uniqTokensB = tokensB.filter(token => !tokensA.includes(token)); var distanceB = uniqTokensB.join(" ").length / tokensB.join(" ").length; return 1 - distanceB; }, _checkByline: function(node, matchString) { if (this._articleByline) { return false; } if (node.getAttribute !== undefined) { var rel = node.getAttribute("rel"); var itemprop = node.getAttribute("itemprop"); } if ((rel === "author" || (itemprop && itemprop.indexOf("author") !== -1) || this.REGEXPS.byline.test(matchString)) && this._isValidByline(node.textContent)) { this._articleByline = node.textContent.trim(); return true; } return false; }, _getNodeAncestors: function(node, maxDepth) { maxDepth = maxDepth || 0; var i = 0, ancestors = []; while (node.parentNode) { ancestors.push(node.parentNode); if (maxDepth && ++i === maxDepth) break; node = node.parentNode; } return ancestors; }, /*** * grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is * most likely to be the stuff a user wants to read. Then return it wrapped up in a div. * * @param page a document to run upon. Needs to be a full document, complete with body. * @return Element **/ _grabArticle: function (page) { this.log("**** grabArticle ****"); var doc = this._doc; var isPaging = page !== null; page = page ? page : this._doc.body; // We can't grab an article if we don't have a page! if (!page) { this.log("No body found in document. Abort."); return null; } var pageCacheHtml = page.innerHTML; while (true) { this.log("Starting grabArticle loop"); var stripUnlikelyCandidates = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS); // First, node prepping. Trash nodes that look cruddy (like ones with the // class name "comment", etc), and turn divs into P tags where they have been // used inappropriately (as in, where they contain no other block level elements.) var elementsToScore = []; var node = this._doc.documentElement; let shouldRemoveTitleHeader = true; while (node) { var matchString = node.className + " " + node.id; if (!this._isProbablyVisible(node)) { this.log("Removing hidden node - " + matchString); node = this._removeAndGetNext(node); continue; } // Check to see if this node is a byline, and remove it if it is. if (this._checkByline(node, matchString)) { node = this._removeAndGetNext(node); continue; } if (shouldRemoveTitleHeader && this._headerDuplicatesTitle(node)) { this.log("Removing header: ", node.textContent.trim(), this._articleTitle.trim()); shouldRemoveTitleHeader = false; node = this._removeAndGetNext(node); continue; } // Remove unlikely candidates if (stripUnlikelyCandidates) { if (this.REGEXPS.unlikelyCandidates.test(matchString) && !this.REGEXPS.okMaybeItsACandidate.test(matchString) && !this._hasAncestorTag(node, "table") && !this._hasAncestorTag(node, "code") && node.tagName !== "BODY" && node.tagName !== "A") { this.log("Removing unlikely candidate - " + matchString); node = this._removeAndGetNext(node); continue; } if (this.UNLIKELY_ROLES.includes(node.getAttribute("role"))) { this.log("Removing content with role " + node.getAttribute("role") + " - " + matchString); node = this._removeAndGetNext(node); continue; } } // Remove DIV, SECTION, and HEADER nodes without any content(e.g. text, image, video, or iframe). if ((node.tagName === "DIV" || node.tagName === "SECTION" || node.tagName === "HEADER" || node.tagName === "H1" || node.tagName === "H2" || node.tagName === "H3" || node.tagName === "H4" || node.tagName === "H5" || node.tagName === "H6") && this._isElementWithoutContent(node)) { node = this._removeAndGetNext(node); continue; } if (this.DEFAULT_TAGS_TO_SCORE.indexOf(node.tagName) !== -1) { elementsToScore.push(node); } // Turn all divs that don't have children block level elements into p's if (node.tagName === "DIV") { // Put phrasing content into paragraphs. var p = null; var childNode = node.firstChild; while (childNode) { var nextSibling = childNode.nextSibling; if (this._isPhrasingContent(childNode)) { if (p !== null) { p.appendChild(childNode); } else if (!this._isWhitespace(childNode)) { p = doc.createElement("p"); node.replaceChild(p, childNode); p.appendChild(childNode); } } else if (p !== null) { while (p.lastChild && this._isWhitespace(p.lastChild)) { p.removeChild(p.lastChild); } p = null; } childNode = nextSibling; } // Sites like http://mobile.slate.com encloses each paragraph with a DIV // element. DIVs with only a P element inside and no text content can be // safely converted into plain P elements to avoid confusing the scoring // algorithm with DIVs with are, in practice, paragraphs. if (this._hasSingleTagInsideElement(node, "P") && this._getLinkDensity(node) < 0.25) { var newNode = node.children[0]; node.parentNode.replaceChild(newNode, node); node = newNode; elementsToScore.push(node); } else if (!this._hasChildBlockElement(node)) { node = this._setNodeTag(node, "P"); elementsToScore.push(node); } } node = this._getNextNode(node); } /** * Loop through all paragraphs, and assign a score to them based on how content-y they look. * Then add their score to their parent node. * * A score is determined by things like number of commas, class names, etc. Maybe eventually link density. **/ var candidates = []; this._forEachNode(elementsToScore, function(elementToScore) { if (!elementToScore.parentNode || typeof(elementToScore.parentNode.tagName) === "undefined") return; // If this paragraph is less than 25 characters, don't even count it. var innerText = this._getInnerText(elementToScore); if (innerText.length < 25) return; // Exclude nodes with no ancestor. var ancestors = this._getNodeAncestors(elementToScore, 5); if (ancestors.length === 0) return; var contentScore = 0; // Add a point for the paragraph itself as a base. contentScore += 1; // Add points for any commas within this paragraph. contentScore += innerText.split(",").length; // For every 100 characters in this paragraph, add another point. Up to 3 points. contentScore += Math.min(Math.floor(innerText.length / 100), 3); // Initialize and score ancestors. this._forEachNode(ancestors, function(ancestor, level) { if (!ancestor.tagName || !ancestor.parentNode || typeof(ancestor.parentNode.tagName) === "undefined") return; if (typeof(ancestor.readability) === "undefined") { this._initializeNode(ancestor); candidates.push(ancestor); } // Node score divider: // - parent: 1 (no division) // - grandparent: 2 // - great grandparent+: ancestor level * 3 if (level === 0) var scoreDivider = 1; else if (level === 1) scoreDivider = 2; else scoreDivider = level * 3; ancestor.readability.contentScore += contentScore / scoreDivider; }); }); // After we've calculated scores, loop through all of the possible // candidate nodes we found and find the one with the highest score. var topCandidates = []; for (var c = 0, cl = candidates.length; c < cl; c += 1) { var candidate = candidates[c]; // Scale the final candidates score based on link density. Good content // should have a relatively small link density (5% or less) and be mostly // unaffected by this operation. var candidateScore = candidate.readability.contentScore * (1 - this._getLinkDensity(candidate)); candidate.readability.contentScore = candidateScore; this.log("Candidate:", candidate, "with score " + candidateScore); for (var t = 0; t < this._nbTopCandidates; t++) { var aTopCandidate = topCandidates[t]; if (!aTopCandidate || candidateScore > aTopCandidate.readability.contentScore) { topCandidates.splice(t, 0, candidate); if (topCandidates.length > this._nbTopCandidates) topCandidates.pop(); break; } } } var topCandidate = topCandidates[0] || null; var neededToCreateTopCandidate = false; var parentOfTopCandidate; // If we still have no top candidate, just use the body as a last resort. // We also have to copy the body node so it is something we can modify. if (topCandidate === null || topCandidate.tagName === "BODY") { // Move all of the page's children into topCandidate topCandidate = doc.createElement("DIV"); neededToCreateTopCandidate = true; // Move everything (not just elements, also text nodes etc.) into the container // so we even include text directly in the body: var kids = page.childNodes; while (kids.length) { this.log("Moving child out:", kids[0]); topCandidate.appendChild(kids[0]); } page.appendChild(topCandidate); this._initializeNode(topCandidate); } else if (topCandidate) { // Find a better top candidate node if it contains (at least three) nodes which belong to `topCandidates` array // and whose scores are quite closed with current `topCandidate` node. var alternativeCandidateAncestors = []; for (var i = 1; i < topCandidates.length; i++) { if (topCandidates[i].readability.contentScore / topCandidate.readability.contentScore >= 0.75) { alternativeCandidateAncestors.push(this._getNodeAncestors(topCandidates[i])); } } var MINIMUM_TOPCANDIDATES = 3; if (alternativeCandidateAncestors.length >= MINIMUM_TOPCANDIDATES) { parentOfTopCandidate = topCandidate.parentNode; while (parentOfTopCandidate.tagName !== "BODY") { var listsContainingThisAncestor = 0; for (var ancestorIndex = 0; ancestorIndex < alternativeCandidateAncestors.length && listsContainingThisAncestor < MINIMUM_TOPCANDIDATES; ancestorIndex++) { listsContainingThisAncestor += Number(alternativeCandidateAncestors[ancestorIndex].includes(parentOfTopCandidate)); } if (listsContainingThisAncestor >= MINIMUM_TOPCANDIDATES) { topCandidate = parentOfTopCandidate; break; } parentOfTopCandidate = parentOfTopCandidate.parentNode; } } if (!topCandidate.readability) { this._initializeNode(topCandidate); } // Because of our bonus system, parents of candidates might have scores // themselves. They get half of the node. There won't be nodes with higher // scores than our topCandidate, but if we see the score going *up* in the first // few steps up the tree, that's a decent sign that there might be more content // lurking in other places that we want to unify in. The sibling stuff // below does some of that - but only if we've looked high enough up the DOM // tree. parentOfTopCandidate = topCandidate.parentNode; var lastScore = topCandidate.readability.contentScore; // The scores shouldn't get too low. var scoreThreshold = lastScore / 3; while (parentOfTopCandidate.tagName !== "BODY") { if (!parentOfTopCandidate.readability) { parentOfTopCandidate = parentOfTopCandidate.parentNode; continue; } var parentScore = parentOfTopCandidate.readability.contentScore; if (parentScore < scoreThreshold) break; if (parentScore > lastScore) { // Alright! We found a better parent to use. topCandidate = parentOfTopCandidate; break; } lastScore = parentOfTopCandidate.readability.contentScore; parentOfTopCandidate = parentOfTopCandidate.parentNode; } // If the top candidate is the only child, use parent instead. This will help sibling // joining logic when adjacent content is actually located in parent's sibling node. parentOfTopCandidate = topCandidate.parentNode; while (parentOfTopCandidate.tagName != "BODY" && parentOfTopCandidate.children.length == 1) { topCandidate = parentOfTopCandidate; parentOfTopCandidate = topCandidate.parentNode; } if (!topCandidate.readability) { this._initializeNode(topCandidate); } } // Now that we have the top candidate, look through its siblings for content // that might also be related. Things like preambles, content split by ads // that we removed, etc. var articleContent = doc.createElement("DIV"); if (isPaging) articleContent.id = "readability-content"; var siblingScoreThreshold = Math.max(10, topCandidate.readability.contentScore * 0.2); // Keep potential top candidate's parent node to try to get text direction of it later. parentOfTopCandidate = topCandidate.parentNode; var siblings = parentOfTopCandidate.children; for (var s = 0, sl = siblings.length; s < sl; s++) { var sibling = siblings[s]; var append = false; this.log("Looking at sibling node:", sibling, sibling.readability ? ("with score " + sibling.readability.contentScore) : ""); this.log("Sibling has score", sibling.readability ? sibling.readability.contentScore : "Unknown"); if (sibling === topCandidate) { append = true; } else { var contentBonus = 0; // Give a bonus if sibling nodes and top candidates have the example same classname if (sibling.className === topCandidate.className && topCandidate.className !== "") contentBonus += topCandidate.readability.contentScore * 0.2; if (sibling.readability && ((sibling.readability.contentScore + contentBonus) >= siblingScoreThreshold)) { append = true; } else if (sibling.nodeName === "P") { var linkDensity = this._getLinkDensity(sibling); var nodeContent = this._getInnerText(sibling); var nodeLength = nodeContent.length; if (nodeLength > 80 && linkDensity < 0.25) { append = true; } else if (nodeLength < 80 && nodeLength > 0 && linkDensity === 0 && nodeContent.search(/\.( |$)/) !== -1) { append = true; } } } if (append) { this.log("Appending node:", sibling); if (this.ALTER_TO_DIV_EXCEPTIONS.indexOf(sibling.nodeName) === -1) { // We have a node that isn't a common block level element, like a form or td tag. // Turn it into a div so it doesn't get filtered out later by accident. this.log("Altering sibling:", sibling, "to div."); sibling = this._setNodeTag(sibling, "DIV"); } articleContent.appendChild(sibling); // siblings is a reference to the children array, and // sibling is removed from the array when we call appendChild(). // As a result, we must revisit this index since the nodes // have been shifted. s -= 1; sl -= 1; } } if (this._debug) this.log("Article content pre-prep: " + articleContent.innerHTML); // So we have all of the content that we need. Now we clean it up for presentation. this._prepArticle(articleContent); if (this._debug) this.log("Article content post-prep: " + articleContent.innerHTML); if (neededToCreateTopCandidate) { // We already created a fake div thing, and there wouldn't have been any siblings left // for the previous loop, so there's no point trying to create a new div, and then // move all the children over. Just assign IDs and class names here. No need to append // because that already happened anyway. topCandidate.id = "readability-page-1"; topCandidate.className = "page"; } else { var div = doc.createElement("DIV"); div.id = "readability-page-1"; div.className = "page"; var children = articleContent.childNodes; while (children.length) { div.appendChild(children[0]); } articleContent.appendChild(div); } if (this._debug) this.log("Article content after paging: " + articleContent.innerHTML); var parseSuccessful = true; // Now that we've gone through the full algorithm, check to see if // we got any meaningful content. If we didn't, we may need to re-run // grabArticle with different flags set. This gives us a higher likelihood of // finding the content, and the sieve approach gives us a higher likelihood of // finding the -right- content. var textLength = this._getInnerText(articleContent, true).length; if (textLength < this._charThreshold) { parseSuccessful = false; page.innerHTML = pageCacheHtml; if (this._flagIsActive(this.FLAG_STRIP_UNLIKELYS)) { this._removeFlag(this.FLAG_STRIP_UNLIKELYS); this._attempts.push({articleContent: articleContent, textLength: textLength}); } else if (this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) { this._removeFlag(this.FLAG_WEIGHT_CLASSES); this._attempts.push({articleContent: articleContent, textLength: textLength}); } else if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) { this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY); this._attempts.push({articleContent: articleContent, textLength: textLength}); } else { this._attempts.push({articleContent: articleContent, textLength: textLength}); // No luck after removing flags, just return the longest text we found during the different loops this._attempts.sort(function (a, b) { return b.textLength - a.textLength; }); // But first check if we actually have something if (!this._attempts[0].textLength) { return null; } articleContent = this._attempts[0].articleContent; parseSuccessful = true; } } if (parseSuccessful) { // Find out text direction from ancestors of final top candidate. var ancestors = [parentOfTopCandidate, topCandidate].concat(this._getNodeAncestors(parentOfTopCandidate)); this._someNode(ancestors, function(ancestor) { if (!ancestor.tagName) return false; var articleDir = ancestor.getAttribute("dir"); if (articleDir) { this._articleDir = articleDir; return true; } return false; }); return articleContent; } } }, /** * Check whether the input string could be a byline. * This verifies that the input is a string, and that the length * is less than 100 chars. * * @param possibleByline {string} - a string to check whether its a byline. * @return Boolean - whether the input string is a byline. */ _isValidByline: function(byline) { if (typeof byline == "string" || byline instanceof String) { byline = byline.trim(); return (byline.length > 0) && (byline.length < 100); } return false; }, /** * Converts some of the common HTML entities in string to their corresponding characters. * * @param str {string} - a string to unescape. * @return string without HTML entity. */ _unescapeHtmlEntities: function(str) { if (!str) { return str; } var htmlEscapeMap = this.HTML_ESCAPE_MAP; return str.replace(/&(quot|amp|apos|lt|gt);/g, function(_, tag) { return htmlEscapeMap[tag]; }).replace(/&#(?:x([0-9a-z]{1,4})|([0-9]{1,4}));/gi, function(_, hex, numStr) { var num = parseInt(hex || numStr, hex ? 16 : 10); return String.fromCharCode(num); }); }, /** * Try to extract metadata from JSON-LD object. * For now, only Schema.org objects of type Article or its subtypes are supported. * @return Object with any metadata that could be extracted (possibly none) */ _getJSONLD: function (doc) { var scripts = this._getAllNodesWithTag(doc, ["script"]); var jsonLdElement = this._findNode(scripts, function(el) { return el.getAttribute("type") === "application/ld+json"; }); if (jsonLdElement) { try { // Strip CDATA markers if present var content = jsonLdElement.textContent.replace(/^\s*<!\[CDATA\[|\]\]>\s*$/g, ""); var parsed = JSON.parse(content); var metadata = {}; if ( !parsed["@context"] || !parsed["@context"].match(/^https?\:\/\/schema\.org$/) ) { return metadata; } if (!parsed["@type"] && Array.isArray(parsed["@graph"])) { parsed = parsed["@graph"].find(function(it) { return (it["@type"] || "").match( this.REGEXPS.jsonLdArticleTypes ); }); } if ( !parsed || !parsed["@type"] || !parsed["@type"].match(this.REGEXPS.jsonLdArticleTypes) ) { return metadata; } if (typeof parsed.name === "string") { metadata.title = parsed.name.trim(); } else if (typeof parsed.headline === "string") { metadata.title = parsed.headline.trim(); } if (parsed.author) { if (typeof parsed.author.name === "string") { metadata.byline = parsed.author.name.trim(); } else if (Array.isArray(parsed.author) && parsed.author[0] && typeof parsed.author[0].name === "string") { metadata.byline = parsed.author .filter(function(author) { return author && typeof author.name === "string"; }) .map(function(author) { return author.name.trim(); }) .join(", "); } } if (typeof parsed.description === "string") { metadata.excerpt = parsed.description.trim(); } if ( parsed.publisher && typeof parsed.publisher.name === "string" ) { metadata.siteName = parsed.publisher.name.trim(); } return metadata; } catch (err) { this.log(err.message); } } return {}; }, /** * Attempts to get excerpt and byline metadata for the article. * * @param {Object} jsonld — object containing any metadata that * could be extracted from JSON-LD object. * * @return Object with optional "excerpt" and "byline" properties */ _getArticleMetadata: function(jsonld) { var metadata = {}; var values = {}; var metaElements = this._doc.getElementsByTagName("meta"); // property is a space-separated list of values var propertyPattern = /\s*(dc|dcterm|og|twitter)\s*:\s*(author|creator|description|title|site_name)\s*/gi; // name is a single value var namePattern = /^\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\s*[\.:]\s*)?(author|creator|description|title|site_name)\s*$/i; // Find description tags. this._forEachNode(metaElements, function(element) { var elementName = element.getAttribute("name"); var elementProperty = element.getAttribute("property"); var content = element.getAttribute("content"); if (!content) { return; } var matches = null; var name = null; if (elementProperty) { matches = elementProperty.match(propertyPattern); if (matches) { // Convert to lowercase, and remove any whitespace // so we can match below. name = matches[0].toLowerCase().replace(/\s/g, ""); // multiple authors values[name] = content.trim(); } } if (!matches && elementName && namePattern.test(elementName)) { name = elementName; if (content) { // Convert to lowercase, remove any whitespace, and convert dots // to colons so we can match below. name = name.toLowerCase().replace(/\s/g, "").replace(/\./g, ":"); values[name] = content.trim(); } } }); // get title metadata.title = jsonld.title || values["dc:title"] || values["dcterm:title"] || values["og:title"] || values["weibo:article:title"] || values["weibo:webpage:title"] || values["title"] || values["twitter:title"]; if (!metadata.title) { metadata.title = this._getArticleTitle(); } // get author metadata.byline = jsonld.byline || values["dc:creator"] || values["dcterm:creator"] || values["author"]; // get description metadata.excerpt = jsonld.excerpt || values["dc:description"] || values["dcterm:description"] || values["og:description"] || values["weibo:article:description"] || values["weibo:webpage:description"] || values["description"] || values["twitter:description"]; // get site name metadata.siteName = jsonld.siteName || values["og:site_name"]; // in many sites the meta value is escaped with HTML entities, // so here we need to unescape it metadata.title = this._unescapeHtmlEntities(metadata.title); metadata.byline = this._unescapeHtmlEntities(metadata.byline); metadata.excerpt = this._unescapeHtmlEntities(metadata.excerpt); metadata.siteName = this._unescapeHtmlEntities(metadata.siteName); return metadata; }, /** * Check if node is image, or if node contains exactly only one image * whether as a direct child or as its descendants. * * @param Element **/ _isSingleImage: function(node) { if (node.tagName === "IMG") { return true; } if (node.children.length !== 1 || node.textContent.trim() !== "") { return false; } return this._isSingleImage(node.children[0]); }, /** * Find all <noscript> that are located after <img> nodes, and which contain only one * <img> element. Replace the first image with the image from inside the <noscript> tag, * and remove the <noscript> tag. This improves the quality of the images we use on * some sites (e.g. Medium). * * @param Element **/ _unwrapNoscriptImages: function(doc) { // Find img without source or attributes that might contains image, and remove it. // This is done to prevent a placeholder img is replaced by img from noscript in next step. var imgs = Array.from(doc.getElementsByTagName("img")); this._forEachNode(imgs, function(img) { for (var i = 0; i < img.attributes.length; i++) { var attr = img.attributes[i]; switch (attr.name) { case "src": case "srcset": case "data-src": case "data-srcset": return; } if (/\.(jpg|jpeg|png|webp)/i.test(attr.value)) { return; } } img.parentNode.removeChild(img); }); // Next find noscript and try to extract its image var noscripts = Array.from(doc.getElementsByTagName("noscript")); this._forEachNode(noscripts, function(noscript) { // Parse content of noscript and make sure it only contains image var tmp = doc.createElement("div"); tmp.innerHTML = noscript.innerHTML; if (!this._isSingleImage(tmp)) { return; } // If noscript has previous sibling and it only contains image, // replace it with noscript content. However we also keep old // attributes that might contains image. var prevElement = noscript.previousElementSibling; if (prevElement && this._isSingleImage(prevElement)) { var prevImg = prevElement; if (prevImg.tagName !== "IMG") { prevImg = prevElement.getElementsByTagName("img")[0]; } var newImg = tmp.getElementsByTagName("img")[0]; for (var i = 0; i < prevImg.attributes.length; i++) { var attr = prevImg.attributes[i]; if (attr.value === "") { continue; } if (attr.name === "src" || attr.name === "srcset" || /\.(jpg|jpeg|png|webp)/i.test(attr.value)) { if (newImg.getAttribute(attr.name) === attr.value) { continue; } var attrName = attr.name; if (newImg.hasAttribute(attrName)) { attrName = "data-old-" + attrName; } newImg.setAttribute(attrName, attr.value); } } noscript.parentNode.replaceChild(tmp.firstElementChild, prevElement); } }); }, /** * Removes script tags from the document. * * @param Element **/ _removeScripts: function(doc) { this._removeNodes(this._getAllNodesWithTag(doc, ["script"]), function(scriptNode) { scriptNode.nodeValue = ""; scriptNode.removeAttribute("src"); return true; }); this._removeNodes(this._getAllNodesWithTag(doc, ["noscript"])); }, /** * Check if this node has only whitespace and a single element with given tag * Returns false if the DIV node contains non-empty text nodes * or if it contains no element with given tag or more than 1 element. * * @param Element * @param string tag of child element **/ _hasSingleTagInsideElement: function(element, tag) { // There should be exactly 1 element child with given tag if (element.children.length != 1 || element.children[0].tagName !== tag) { return false; } // And there should be no text nodes with real content return !this._someNode(element.childNodes, function(node) { return node.nodeType === this.TEXT_NODE && this.REGEXPS.hasContent.test(node.textContent); }); }, _isElementWithoutContent: function(node) { return node.nodeType === this.ELEMENT_NODE && node.textContent.trim().length == 0 && (node.children.length == 0 || node.children.length == node.getElementsByTagName("br").length + node.getElementsByTagName("hr").length); }, /** * Determine whether element has any children block level elements. * * @param Element */ _hasChildBlockElement: function (element) { return this._someNode(element.childNodes, function(node) { return this.DIV_TO_P_ELEMS.has(node.tagName) || this._hasChildBlockElement(node); }); }, /*** * Determine if a node qualifies as phrasing content. * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content **/ _isPhrasingContent: function(node) { return node.nodeType === this.TEXT_NODE || this.PHRASING_ELEMS.indexOf(node.tagName) !== -1 || ((node.tagName === "A" || node.tagName === "DEL" || node.tagName === "INS") && this._everyNode(node.childNodes, this._isPhrasingContent)); }, _isWhitespace: function(node) { return (node.nodeType === this.TEXT_NODE && node.textContent.trim().length === 0) || (node.nodeType === this.ELEMENT_NODE && node.tagName === "BR"); }, /** * Get the inner text of a node - cross browser compatibly. * This also strips out any excess whitespace to be found. * * @param Element * @param Boolean normalizeSpaces (default: true) * @return string **/ _getInnerText: function(e, normalizeSpaces) { normalizeSpaces = (typeof normalizeSpaces === "undefined") ? true : normalizeSpaces; var textContent = e.textContent.trim(); if (normalizeSpaces) { return textContent.replace(this.REGEXPS.normalize, " "); } return textContent; }, /** * Get the number of times a string s appears in the node e. * * @param Element * @param string - what to split on. Default is "," * @return number (integer) **/ _getCharCount: function(e, s) { s = s || ","; return this._getInnerText(e).split(s).length - 1; }, /** * Remove the style attribute on every e and under. * TODO: Test if getElementsByTagName(*) is faster. * * @param Element * @return void **/ _cleanStyles: function(e) { if (!e || e.tagName.toLowerCase() === "svg") return; // Remove `style` and deprecated presentational attributes for (var i = 0; i < this.PRESENTATIONAL_ATTRIBUTES.length; i++) { e.removeAttribute(this.PRESENTATIONAL_ATTRIBUTES[i]); } if (this.DEPRECATED_SIZE_ATTRIBUTE_ELEMS.indexOf(e.tagName) !== -1) { e.removeAttribute("width"); e.removeAttribute("height"); } var cur = e.firstElementChild; while (cur !== null) { this._cleanStyles(cur); cur = cur.nextElementSibling; } }, /** * Get the density of links as a percentage of the content * This is the amount of text that is inside a link divided by the total text in the node. * * @param Element * @return number (float) **/ _getLinkDensity: function(element) { var textLength = this._getInnerText(element).length; if (textLength === 0) return 0; var linkLength = 0; // XXX implement _reduceNodeList? this._forEachNode(element.getElementsByTagName("a"), function(linkNode) { var href = linkNode.getAttribute("href"); var coefficient = href && this.REGEXPS.hashUrl.test(href) ? 0.3 : 1; linkLength += this._getInnerText(linkNode).length * coefficient; }); return linkLength / textLength; }, /** * Get an elements class/id weight. Uses regular expressions to tell if this * element looks good or bad. * * @param Element * @return number (Integer) **/ _getClassWeight: function(e) { if (!this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) return 0; var weight = 0; // Look for a special classname if (typeof(e.className) === "string" && e.className !== "") { if (this.REGEXPS.negative.test(e.className)) weight -= 25; if (this.REGEXPS.positive.test(e.className)) weight += 25; } // Look for a special ID if (typeof(e.id) === "string" && e.id !== "") { if (this.REGEXPS.negative.test(e.id)) weight -= 25; if (this.REGEXPS.positive.test(e.id)) weight += 25; } return weight; }, /** * Clean a node of all elements of type "tag". * (Unless it's a youtube/vimeo video. People love movies.) * * @param Element * @param string tag to clean * @return void **/ _clean: function(e, tag) { var isEmbed = ["object", "embed", "iframe"].indexOf(tag) !== -1; this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(element) { // Allow youtube and vimeo videos through as people usually want to see those. if (isEmbed) { // First, check the elements attributes to see if any of them contain youtube or vimeo for (var i = 0; i < element.attributes.length; i++) { if (this.REGEXPS.videos.test(element.attributes[i].value)) { return false; } } // For embed with <object> tag, check inner HTML as well. if (element.tagName === "object" && this.REGEXPS.videos.test(element.innerHTML)) { return false; } } return true; }); }, /** * Check if a given node has one of its ancestor tag name matching the * provided one. * @param HTMLElement node * @param String tagName * @param Number maxDepth * @param Function filterFn a filter to invoke to determine whether this node 'counts' * @return Boolean */ _hasAncestorTag: function(node, tagName, maxDepth, filterFn) { maxDepth = maxDepth || 3; tagName = tagName.toUpperCase(); var depth = 0; while (node.parentNode) { if (maxDepth > 0 && depth > maxDepth) return false; if (node.parentNode.tagName === tagName && (!filterFn || filterFn(node.parentNode))) return true; node = node.parentNode; depth++; } return false; }, /** * Return an object indicating how many rows and columns this table has. */ _getRowAndColumnCount: function(table) { var rows = 0; var columns = 0; var trs = table.getElementsByTagName("tr"); for (var i = 0; i < trs.length; i++) { var rowspan = trs[i].getAttribute("rowspan") || 0; if (rowspan) { rowspan = parseInt(rowspan, 10); } rows += (rowspan || 1); // Now look for column-related info var columnsInThisRow = 0; var cells = trs[i].getElementsByTagName("td"); for (var j = 0; j < cells.length; j++) { var colspan = cells[j].getAttribute("colspan") || 0; if (colspan) { colspan = parseInt(colspan, 10); } columnsInThisRow += (colspan || 1); } columns = Math.max(columns, columnsInThisRow); } return {rows: rows, columns: columns}; }, /** * Look for 'data' (as opposed to 'layout') tables, for which we use * similar checks as * https://searchfox.org/mozilla-central/rev/f82d5c549f046cb64ce5602bfd894b7ae807c8f8/accessible/generic/TableAccessible.cpp#19 */ _markDataTables: function(root) { var tables = root.getElementsByTagName("table"); for (var i = 0; i < tables.length; i++) { var table = tables[i]; var role = table.getAttribute("role"); if (role == "presentation") { table._readabilityDataTable = false; continue; } var datatable = table.getAttribute("datatable"); if (datatable == "0") { table._readabilityDataTable = false; continue; } var summary = table.getAttribute("summary"); if (summary) { table._readabilityDataTable = true; continue; } var caption = table.getElementsByTagName("caption")[0]; if (caption && caption.childNodes.length > 0) { table._readabilityDataTable = true; continue; } // If the table has a descendant with any of these tags, consider a data table: var dataTableDescendants = ["col", "colgroup", "tfoot", "thead", "th"]; var descendantExists = function(tag) { return !!table.getElementsByTagName(tag)[0]; }; if (dataTableDescendants.some(descendantExists)) { this.log("Data table because found data-y descendant"); table._readabilityDataTable = true; continue; } // Nested tables indicate a layout table: if (table.getElementsByTagName("table")[0]) { table._readabilityDataTable = false; continue; } var sizeInfo = this._getRowAndColumnCount(table); if (sizeInfo.rows >= 10 || sizeInfo.columns > 4) { table._readabilityDataTable = true; continue; } // Now just go by size entirely: table._readabilityDataTable = sizeInfo.rows * sizeInfo.columns > 10; } }, /* convert images and figures that have properties like data-src into images that can be loaded without JS */ _fixLazyImages: function (root) { this._forEachNode(this._getAllNodesWithTag(root, ["img", "picture", "figure"]), function (elem) { // In some sites (e.g. Kotaku), they put 1px square image as base64 data uri in the src attribute. // So, here we check if the data uri is too short, just might as well remove it. if (elem.src && this.REGEXPS.b64DataUrl.test(elem.src)) { // Make sure it's not SVG, because SVG can have a meaningful image in under 133 bytes. var parts = this.REGEXPS.b64DataUrl.exec(elem.src); if (parts[1] === "image/svg+xml") { return; } // Make sure this element has other attributes which contains image. // If it doesn't, then this src is important and shouldn't be removed. var srcCouldBeRemoved = false; for (var i = 0; i < elem.attributes.length; i++) { var attr = elem.attributes[i]; if (attr.name === "src") { continue; } if (/\.(jpg|jpeg|png|webp)/i.test(attr.value)) { srcCouldBeRemoved = true; break; } } // Here we assume if image is less than 100 bytes (or 133B after encoded to base64) // it will be too small, therefore it might be placeholder image. if (srcCouldBeRemoved) { var b64starts = elem.src.search(/base64\s*/i) + 7; var b64length = elem.src.length - b64starts; if (b64length < 133) { elem.removeAttribute("src"); } } } // also check for "null" to work around https://github.com/jsdom/jsdom/issues/2580 if ((elem.src || (elem.srcset && elem.srcset != "null")) && elem.className.toLowerCase().indexOf("lazy") === -1) { return; } for (var j = 0; j < elem.attributes.length; j++) { attr = elem.attributes[j]; if (attr.name === "src" || attr.name === "srcset") { continue; } var copyTo = null; if (/\.(jpg|jpeg|png|webp)\s+\d/.test(attr.value)) { copyTo = "srcset"; } else if (/^\s*\S+\.(jpg|jpeg|png|webp)\S*\s*$/.test(attr.value)) { copyTo = "src"; } if (copyTo) { //if this is an img or picture, set the attribute directly if (elem.tagName === "IMG" || elem.tagName === "PICTURE") { elem.setAttribute(copyTo, attr.value); } else if (elem.tagName === "FIGURE" && !this._getAllNodesWithTag(elem, ["img", "picture"]).length) { //if the item is a <figure> that does not contain an image or picture, create one and place it inside the figure //see the nytimes-3 testcase for an example var img = this._doc.createElement("img"); img.setAttribute(copyTo, attr.value); elem.appendChild(img); } } } }); }, _getTextDensity: function(e, tags) { var textLength = this._getInnerText(e, true).length; if (textLength === 0) { return 0; } var childrenLength = 0; var children = this._getAllNodesWithTag(e, tags); this._forEachNode(children, (child) => childrenLength += this._getInnerText(child, true).length); return childrenLength / textLength; }, /** * Clean an element of all tags of type "tag" if they look fishy. * "Fishy" is an algorithm based on content length, classnames, link density, number of images & embeds, etc. * * @return void **/ _cleanConditionally: function(e, tag) { if (!this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) return; // Gather counts for other typical elements embedded within. // Traverse backwards so we can remove nodes at the same time // without effecting the traversal. // // TODO: Consider taking into account original contentScore here. this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(node) { // First check if this node IS data table, in which case don't remove it. var isDataTable = function(t) { return t._readabilityDataTable; }; var isList = tag === "ul" || tag === "ol"; if (!isList) { var listLength = 0; var listNodes = this._getAllNodesWithTag(node, ["ul", "ol"]); this._forEachNode(listNodes, (list) => listLength += this._getInnerText(list).length); isList = listLength / this._getInnerText(node).length > 0.9; } if (tag === "table" && isDataTable(node)) { return false; } // Next check if we're inside a data table, in which case don't remove it as well. if (this._hasAncestorTag(node, "table", -1, isDataTable)) { return false; } if (this._hasAncestorTag(node, "code")) { return false; } var weight = this._getClassWeight(node); this.log("Cleaning Conditionally", node); var contentScore = 0; if (weight + contentScore < 0) { return true; } if (this._getCharCount(node, ",") < 10) { // If there are not very many commas, and the number of // non-paragraph elements is more than paragraphs or other // ominous signs, remove the element. var p = node.getElementsByTagName("p").length; var img = node.getElementsByTagName("img").length; var li = node.getElementsByTagName("li").length - 100; var input = node.getElementsByTagName("input").length; var headingDensity = this._getTextDensity(node, ["h1", "h2", "h3", "h4", "h5", "h6"]); var embedCount = 0; var embeds = this._getAllNodesWithTag(node, ["object", "embed", "iframe"]); for (var i = 0; i < embeds.length; i++) { // If this embed has attribute that matches video regex, don't delete it. for (var j = 0; j < embeds[i].attributes.length; j++) { if (this.REGEXPS.videos.test(embeds[i].attributes[j].value)) { return false; } } // For embed with <object> tag, check inner HTML as well. if (embeds[i].tagName === "object" && this.REGEXPS.videos.test(embeds[i].innerHTML)) { return false; } embedCount++; } var linkDensity = this._getLinkDensity(node); var contentLength = this._getInnerText(node).length; var haveToRemove = (img > 1 && p / img < 0.5 && !this._hasAncestorTag(node, "figure")) || (!isList && li > p) || (input > Math.floor(p/3)) || (!isList && headingDensity < 0.9 && contentLength < 25 && (img === 0 || img > 2) && !this._hasAncestorTag(node, "figure")) || (!isList && weight < 25 && linkDensity > 0.2) || (weight >= 25 && linkDensity > 0.5) || ((embedCount === 1 && contentLength < 75) || embedCount > 1); return haveToRemove; } return false; }); }, /** * Clean out elements that match the specified conditions * * @param Element * @param Function determines whether a node should be removed * @return void **/ _cleanMatchedNodes: function(e, filter) { var endOfSearchMarkerNode = this._getNextNode(e, true); var next = this._getNextNode(e); while (next && next != endOfSearchMarkerNode) { if (filter.call(this, next, next.className + " " + next.id)) { next = this._removeAndGetNext(next); } else { next = this._getNextNode(next); } } }, /** * Clean out spurious headers from an Element. * * @param Element * @return void **/ _cleanHeaders: function(e) { let headingNodes = this._getAllNodesWithTag(e, ["h1", "h2"]); this._removeNodes(headingNodes, function(node) { let shouldRemove = this._getClassWeight(node) < 0; if (shouldRemove) { this.log("Removing header with low class weight:", node); } return shouldRemove; }); }, /** * Check if this node is an H1 or H2 element whose content is mostly * the same as the article title. * * @param Element the node to check. * @return boolean indicating whether this is a title-like header. */ _headerDuplicatesTitle: function(node) { if (node.tagName != "H1" && node.tagName != "H2") { return false; } var heading = this._getInnerText(node, false); this.log("Evaluating similarity of header:", heading, this._articleTitle); return this._textSimilarity(this._articleTitle, heading) > 0.75; }, _flagIsActive: function(flag) { return (this._flags & flag) > 0; }, _removeFlag: function(flag) { this._flags = this._flags & ~flag; }, _isProbablyVisible: function(node) { // Have to null-check node.style and node.className.indexOf to deal with SVG and MathML nodes. return (!node.style || node.style.display != "none") && !node.hasAttribute("hidden") //check for "fallback-image" so that wikimedia math images are displayed && (!node.hasAttribute("aria-hidden") || node.getAttribute("aria-hidden") != "true" || (node.className && node.className.indexOf && node.className.indexOf("fallback-image") !== -1)); }, /** * Runs readability. * * Workflow: * 1. Prep the document by removing script tags, css, etc. * 2. Build readability's DOM tree. * 3. Grab the article content from the current dom tree. * 4. Replace the current DOM tree with the new one. * 5. Read peacefully. * * @return void **/ parse: function () { // Avoid parsing too large documents, as per configuration option if (this._maxElemsToParse > 0) { var numTags = this._doc.getElementsByTagName("*").length; if (numTags > this._maxElemsToParse) { throw new Error("Aborting parsing document; " + numTags + " elements found"); } } // Unwrap image from noscript this._unwrapNoscriptImages(this._doc); // Extract JSON-LD metadata before removing scripts var jsonLd = this._disableJSONLD ? {} : this._getJSONLD(this._doc); // Remove script tags from the document. this._removeScripts(this._doc); this._prepDocument(); var metadata = this._getArticleMetadata(jsonLd); this._articleTitle = metadata.title; var articleContent = this._grabArticle(); if (!articleContent) return null; this.log("Grabbed: " + articleContent.innerHTML); this._postProcessContent(articleContent); // If we haven't found an excerpt in the article's metadata, use the article's // first paragraph as the excerpt. This is used for displaying a preview of // the article's content. if (!metadata.excerpt) { var paragraphs = articleContent.getElementsByTagName("p"); if (paragraphs.length > 0) { metadata.excerpt = paragraphs[0].textContent.trim(); } } var textContent = articleContent.textContent; return { title: this._articleTitle, byline: metadata.byline || this._articleByline, dir: this._articleDir, content: this._serializer(articleContent), textContent: textContent, length: textContent.length, excerpt: metadata.excerpt, siteName: metadata.siteName || this._articleSiteName }; } }; if (true) { module.exports = Readability; } /***/ }), /***/ "./node_modules/@mozilla/readability/index.js": /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var Readability = __webpack_require__("./node_modules/@mozilla/readability/Readability.js"); var isProbablyReaderable = __webpack_require__("./node_modules/@mozilla/readability/Readability-readerable.js"); module.exports = { Readability: Readability, isProbablyReaderable: isProbablyReaderable }; /***/ }), /***/ "./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "BASE_TRANSITION": () => (/* reexport */ BASE_TRANSITION), "CAMELIZE": () => (/* reexport */ CAMELIZE), "CAPITALIZE": () => (/* reexport */ CAPITALIZE), "CREATE_BLOCK": () => (/* reexport */ CREATE_BLOCK), "CREATE_COMMENT": () => (/* reexport */ CREATE_COMMENT), "CREATE_ELEMENT_BLOCK": () => (/* reexport */ CREATE_ELEMENT_BLOCK), "CREATE_ELEMENT_VNODE": () => (/* reexport */ CREATE_ELEMENT_VNODE), "CREATE_SLOTS": () => (/* reexport */ CREATE_SLOTS), "CREATE_STATIC": () => (/* reexport */ CREATE_STATIC), "CREATE_TEXT": () => (/* reexport */ CREATE_TEXT), "CREATE_VNODE": () => (/* reexport */ CREATE_VNODE), "DOMDirectiveTransforms": () => (/* binding */ DOMDirectiveTransforms), "DOMNodeTransforms": () => (/* binding */ DOMNodeTransforms), "FRAGMENT": () => (/* reexport */ FRAGMENT), "GUARD_REACTIVE_PROPS": () => (/* reexport */ GUARD_REACTIVE_PROPS), "IS_MEMO_SAME": () => (/* reexport */ IS_MEMO_SAME), "IS_REF": () => (/* reexport */ IS_REF), "KEEP_ALIVE": () => (/* reexport */ KEEP_ALIVE), "MERGE_PROPS": () => (/* reexport */ MERGE_PROPS), "NORMALIZE_CLASS": () => (/* reexport */ NORMALIZE_CLASS), "NORMALIZE_PROPS": () => (/* reexport */ NORMALIZE_PROPS), "NORMALIZE_STYLE": () => (/* reexport */ NORMALIZE_STYLE), "OPEN_BLOCK": () => (/* reexport */ OPEN_BLOCK), "POP_SCOPE_ID": () => (/* reexport */ POP_SCOPE_ID), "PUSH_SCOPE_ID": () => (/* reexport */ PUSH_SCOPE_ID), "RENDER_LIST": () => (/* reexport */ RENDER_LIST), "RENDER_SLOT": () => (/* reexport */ RENDER_SLOT), "RESOLVE_COMPONENT": () => (/* reexport */ RESOLVE_COMPONENT), "RESOLVE_DIRECTIVE": () => (/* reexport */ RESOLVE_DIRECTIVE), "RESOLVE_DYNAMIC_COMPONENT": () => (/* reexport */ RESOLVE_DYNAMIC_COMPONENT), "RESOLVE_FILTER": () => (/* reexport */ RESOLVE_FILTER), "SET_BLOCK_TRACKING": () => (/* reexport */ SET_BLOCK_TRACKING), "SUSPENSE": () => (/* reexport */ SUSPENSE), "TELEPORT": () => (/* reexport */ TELEPORT), "TO_DISPLAY_STRING": () => (/* reexport */ TO_DISPLAY_STRING), "TO_HANDLERS": () => (/* reexport */ TO_HANDLERS), "TO_HANDLER_KEY": () => (/* reexport */ TO_HANDLER_KEY), "TRANSITION": () => (/* binding */ TRANSITION), "TRANSITION_GROUP": () => (/* binding */ TRANSITION_GROUP), "UNREF": () => (/* reexport */ UNREF), "V_MODEL_CHECKBOX": () => (/* binding */ V_MODEL_CHECKBOX), "V_MODEL_DYNAMIC": () => (/* binding */ V_MODEL_DYNAMIC), "V_MODEL_RADIO": () => (/* binding */ V_MODEL_RADIO), "V_MODEL_SELECT": () => (/* binding */ V_MODEL_SELECT), "V_MODEL_TEXT": () => (/* binding */ V_MODEL_TEXT), "V_ON_WITH_KEYS": () => (/* binding */ V_ON_WITH_KEYS), "V_ON_WITH_MODIFIERS": () => (/* binding */ V_ON_WITH_MODIFIERS), "V_SHOW": () => (/* binding */ V_SHOW), "WITH_CTX": () => (/* reexport */ WITH_CTX), "WITH_DIRECTIVES": () => (/* reexport */ WITH_DIRECTIVES), "WITH_MEMO": () => (/* reexport */ WITH_MEMO), "advancePositionWithClone": () => (/* reexport */ advancePositionWithClone), "advancePositionWithMutation": () => (/* reexport */ advancePositionWithMutation), "assert": () => (/* reexport */ assert), "baseCompile": () => (/* reexport */ baseCompile), "baseParse": () => (/* reexport */ baseParse), "buildProps": () => (/* reexport */ buildProps), "buildSlots": () => (/* reexport */ buildSlots), "checkCompatEnabled": () => (/* reexport */ checkCompatEnabled), "compile": () => (/* binding */ compile), "createArrayExpression": () => (/* reexport */ createArrayExpression), "createAssignmentExpression": () => (/* reexport */ createAssignmentExpression), "createBlockStatement": () => (/* reexport */ createBlockStatement), "createCacheExpression": () => (/* reexport */ createCacheExpression), "createCallExpression": () => (/* reexport */ createCallExpression), "createCompilerError": () => (/* reexport */ createCompilerError), "createCompoundExpression": () => (/* reexport */ createCompoundExpression), "createConditionalExpression": () => (/* reexport */ createConditionalExpression), "createDOMCompilerError": () => (/* binding */ createDOMCompilerError), "createForLoopParams": () => (/* reexport */ createForLoopParams), "createFunctionExpression": () => (/* reexport */ createFunctionExpression), "createIfStatement": () => (/* reexport */ createIfStatement), "createInterpolation": () => (/* reexport */ createInterpolation), "createObjectExpression": () => (/* reexport */ createObjectExpression), "createObjectProperty": () => (/* reexport */ createObjectProperty), "createReturnStatement": () => (/* reexport */ createReturnStatement), "createRoot": () => (/* reexport */ createRoot), "createSequenceExpression": () => (/* reexport */ createSequenceExpression), "createSimpleExpression": () => (/* reexport */ createSimpleExpression), "createStructuralDirectiveTransform": () => (/* reexport */ createStructuralDirectiveTransform), "createTemplateLiteral": () => (/* reexport */ createTemplateLiteral), "createTransformContext": () => (/* reexport */ createTransformContext), "createVNodeCall": () => (/* reexport */ createVNodeCall), "extractIdentifiers": () => (/* reexport */ extractIdentifiers), "findDir": () => (/* reexport */ findDir), "findProp": () => (/* reexport */ findProp), "generate": () => (/* reexport */ generate), "generateCodeFrame": () => (/* reexport */ shared_esm_bundler.generateCodeFrame), "getBaseTransformPreset": () => (/* reexport */ getBaseTransformPreset), "getInnerRange": () => (/* reexport */ getInnerRange), "getMemoedVNodeCall": () => (/* reexport */ getMemoedVNodeCall), "getVNodeBlockHelper": () => (/* reexport */ getVNodeBlockHelper), "getVNodeHelper": () => (/* reexport */ getVNodeHelper), "hasDynamicKeyVBind": () => (/* reexport */ hasDynamicKeyVBind), "hasScopeRef": () => (/* reexport */ hasScopeRef), "helperNameMap": () => (/* reexport */ helperNameMap), "injectProp": () => (/* reexport */ injectProp), "isBindKey": () => (/* reexport */ isBindKey), "isBuiltInType": () => (/* reexport */ isBuiltInType), "isCoreComponent": () => (/* reexport */ isCoreComponent), "isFunctionType": () => (/* reexport */ isFunctionType), "isInDestructureAssignment": () => (/* reexport */ isInDestructureAssignment), "isMemberExpression": () => (/* reexport */ isMemberExpression), "isMemberExpressionBrowser": () => (/* reexport */ isMemberExpressionBrowser), "isMemberExpressionNode": () => (/* reexport */ isMemberExpressionNode), "isReferencedIdentifier": () => (/* reexport */ isReferencedIdentifier), "isSimpleIdentifier": () => (/* reexport */ isSimpleIdentifier), "isSlotOutlet": () => (/* reexport */ isSlotOutlet), "isStaticExp": () => (/* reexport */ isStaticExp), "isStaticProperty": () => (/* reexport */ isStaticProperty), "isStaticPropertyKey": () => (/* reexport */ isStaticPropertyKey), "isTemplateNode": () => (/* reexport */ isTemplateNode), "isText": () => (/* reexport */ isText), "isVSlot": () => (/* reexport */ isVSlot), "locStub": () => (/* reexport */ locStub), "makeBlock": () => (/* reexport */ makeBlock), "noopDirectiveTransform": () => (/* reexport */ noopDirectiveTransform), "parse": () => (/* binding */ parse), "parserOptions": () => (/* binding */ parserOptions), "processExpression": () => (/* reexport */ processExpression), "processFor": () => (/* reexport */ processFor), "processIf": () => (/* reexport */ processIf), "processSlotOutlet": () => (/* reexport */ processSlotOutlet), "registerRuntimeHelpers": () => (/* reexport */ registerRuntimeHelpers), "resolveComponentType": () => (/* reexport */ resolveComponentType), "toValidAssetId": () => (/* reexport */ toValidAssetId), "trackSlotScopes": () => (/* reexport */ trackSlotScopes), "trackVForSlotScopes": () => (/* reexport */ trackVForSlotScopes), "transform": () => (/* reexport */ transform), "transformBind": () => (/* reexport */ transformBind), "transformElement": () => (/* reexport */ transformElement), "transformExpression": () => (/* reexport */ transformExpression), "transformModel": () => (/* reexport */ transformModel), "transformOn": () => (/* reexport */ transformOn), "transformStyle": () => (/* binding */ transformStyle), "traverseNode": () => (/* reexport */ traverseNode), "walkBlockDeclarations": () => (/* reexport */ walkBlockDeclarations), "walkFunctionParams": () => (/* reexport */ walkFunctionParams), "walkIdentifiers": () => (/* reexport */ walkIdentifiers), "warnDeprecation": () => (/* reexport */ warnDeprecation) }); // EXTERNAL MODULE: ./node_modules/@vue/shared/dist/shared.esm-bundler.js var shared_esm_bundler = __webpack_require__("./node_modules/@vue/shared/dist/shared.esm-bundler.js"); ;// CONCATENATED MODULE: ./node_modules/@vue/compiler-core/dist/compiler-core.esm-bundler.js function defaultOnError(error) { throw error; } function defaultOnWarn(msg) { ( false) && 0; } function createCompilerError(code, loc, messages, additionalMessage) { const msg = false ? 0 : code; const error = new SyntaxError(String(msg)); error.code = code; error.loc = loc; return error; } const errorMessages = { // parse errors [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.', [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.', [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.', [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.', [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.", [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.', [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.', [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.', [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.', [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.', [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.', [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.', [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '<' to print '<'.", [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.', [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.', [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.', [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.", [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).', [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).', [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.", [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.", [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`, [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.", // Vue-specific parse errors [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.', [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.', [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.', [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' + 'Note that dynamic directive argument cannot contain spaces.', [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.', // transform errors [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`, [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`, [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`, [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`, [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`, [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`, [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`, [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`, [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`, [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` + `When there are multiple named slots, all slots should use <template> ` + `syntax to avoid scope ambiguity.`, [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `, [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` + `default slot. These children will be ignored.`, [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`, [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`, [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`, [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`, [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `, [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`, // generic errors [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`, [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`, [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`, [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`, // just to fulfill types [50 /* __EXTEND_POINT__ */]: `` }; const FRAGMENT = Symbol(( false) ? 0 : ``); const TELEPORT = Symbol(( false) ? 0 : ``); const SUSPENSE = Symbol(( false) ? 0 : ``); const KEEP_ALIVE = Symbol(( false) ? 0 : ``); const BASE_TRANSITION = Symbol(( false) ? 0 : ``); const OPEN_BLOCK = Symbol(( false) ? 0 : ``); const CREATE_BLOCK = Symbol(( false) ? 0 : ``); const CREATE_ELEMENT_BLOCK = Symbol(( false) ? 0 : ``); const CREATE_VNODE = Symbol(( false) ? 0 : ``); const CREATE_ELEMENT_VNODE = Symbol(( false) ? 0 : ``); const CREATE_COMMENT = Symbol(( false) ? 0 : ``); const CREATE_TEXT = Symbol(( false) ? 0 : ``); const CREATE_STATIC = Symbol(( false) ? 0 : ``); const RESOLVE_COMPONENT = Symbol(( false) ? 0 : ``); const RESOLVE_DYNAMIC_COMPONENT = Symbol(( false) ? 0 : ``); const RESOLVE_DIRECTIVE = Symbol(( false) ? 0 : ``); const RESOLVE_FILTER = Symbol(( false) ? 0 : ``); const WITH_DIRECTIVES = Symbol(( false) ? 0 : ``); const RENDER_LIST = Symbol(( false) ? 0 : ``); const RENDER_SLOT = Symbol(( false) ? 0 : ``); const CREATE_SLOTS = Symbol(( false) ? 0 : ``); const TO_DISPLAY_STRING = Symbol(( false) ? 0 : ``); const MERGE_PROPS = Symbol(( false) ? 0 : ``); const NORMALIZE_CLASS = Symbol(( false) ? 0 : ``); const NORMALIZE_STYLE = Symbol(( false) ? 0 : ``); const NORMALIZE_PROPS = Symbol(( false) ? 0 : ``); const GUARD_REACTIVE_PROPS = Symbol(( false) ? 0 : ``); const TO_HANDLERS = Symbol(( false) ? 0 : ``); const CAMELIZE = Symbol(( false) ? 0 : ``); const CAPITALIZE = Symbol(( false) ? 0 : ``); const TO_HANDLER_KEY = Symbol(( false) ? 0 : ``); const SET_BLOCK_TRACKING = Symbol(( false) ? 0 : ``); const PUSH_SCOPE_ID = Symbol(( false) ? 0 : ``); const POP_SCOPE_ID = Symbol(( false) ? 0 : ``); const WITH_CTX = Symbol(( false) ? 0 : ``); const UNREF = Symbol(( false) ? 0 : ``); const IS_REF = Symbol(( false) ? 0 : ``); const WITH_MEMO = Symbol(( false) ? 0 : ``); const IS_MEMO_SAME = Symbol(( false) ? 0 : ``); // Name mapping for runtime helpers that need to be imported from 'vue' in // generated code. Make sure these are correctly exported in the runtime! // Using `any` here because TS doesn't allow symbols as index type. const helperNameMap = { [FRAGMENT]: `Fragment`, [TELEPORT]: `Teleport`, [SUSPENSE]: `Suspense`, [KEEP_ALIVE]: `KeepAlive`, [BASE_TRANSITION]: `BaseTransition`, [OPEN_BLOCK]: `openBlock`, [CREATE_BLOCK]: `createBlock`, [CREATE_ELEMENT_BLOCK]: `createElementBlock`, [CREATE_VNODE]: `createVNode`, [CREATE_ELEMENT_VNODE]: `createElementVNode`, [CREATE_COMMENT]: `createCommentVNode`, [CREATE_TEXT]: `createTextVNode`, [CREATE_STATIC]: `createStaticVNode`, [RESOLVE_COMPONENT]: `resolveComponent`, [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`, [RESOLVE_DIRECTIVE]: `resolveDirective`, [RESOLVE_FILTER]: `resolveFilter`, [WITH_DIRECTIVES]: `withDirectives`, [RENDER_LIST]: `renderList`, [RENDER_SLOT]: `renderSlot`, [CREATE_SLOTS]: `createSlots`, [TO_DISPLAY_STRING]: `toDisplayString`, [MERGE_PROPS]: `mergeProps`, [NORMALIZE_CLASS]: `normalizeClass`, [NORMALIZE_STYLE]: `normalizeStyle`, [NORMALIZE_PROPS]: `normalizeProps`, [GUARD_REACTIVE_PROPS]: `guardReactiveProps`, [TO_HANDLERS]: `toHandlers`, [CAMELIZE]: `camelize`, [CAPITALIZE]: `capitalize`, [TO_HANDLER_KEY]: `toHandlerKey`, [SET_BLOCK_TRACKING]: `setBlockTracking`, [PUSH_SCOPE_ID]: `pushScopeId`, [POP_SCOPE_ID]: `popScopeId`, [WITH_CTX]: `withCtx`, [UNREF]: `unref`, [IS_REF]: `isRef`, [WITH_MEMO]: `withMemo`, [IS_MEMO_SAME]: `isMemoSame` }; function registerRuntimeHelpers(helpers) { Object.getOwnPropertySymbols(helpers).forEach(s => { helperNameMap[s] = helpers[s]; }); } // AST Utilities --------------------------------------------------------------- // Some expressions, e.g. sequence and conditional expressions, are never // associated with template nodes, so their source locations are just a stub. // Container types like CompoundExpression also don't need a real location. const locStub = { source: '', start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }; function createRoot(children, loc = locStub) { return { type: 0 /* ROOT */, children, helpers: [], components: [], directives: [], hoists: [], imports: [], cached: 0, temps: 0, codegenNode: undefined, loc }; } function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) { if (context) { if (isBlock) { context.helper(OPEN_BLOCK); context.helper(getVNodeBlockHelper(context.inSSR, isComponent)); } else { context.helper(getVNodeHelper(context.inSSR, isComponent)); } if (directives) { context.helper(WITH_DIRECTIVES); } } return { type: 13 /* VNODE_CALL */, tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent, loc }; } function createArrayExpression(elements, loc = locStub) { return { type: 17 /* JS_ARRAY_EXPRESSION */, loc, elements }; } function createObjectExpression(properties, loc = locStub) { return { type: 15 /* JS_OBJECT_EXPRESSION */, loc, properties }; } function createObjectProperty(key, value) { return { type: 16 /* JS_PROPERTY */, loc: locStub, key: (0,shared_esm_bundler.isString)(key) ? createSimpleExpression(key, true) : key, value }; } function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) { return { type: 4 /* SIMPLE_EXPRESSION */, loc, content, isStatic, constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType }; } function createInterpolation(content, loc) { return { type: 5 /* INTERPOLATION */, loc, content: (0,shared_esm_bundler.isString)(content) ? createSimpleExpression(content, false, loc) : content }; } function createCompoundExpression(children, loc = locStub) { return { type: 8 /* COMPOUND_EXPRESSION */, loc, children }; } function createCallExpression(callee, args = [], loc = locStub) { return { type: 14 /* JS_CALL_EXPRESSION */, loc, callee, arguments: args }; } function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) { return { type: 18 /* JS_FUNCTION_EXPRESSION */, params, returns, newline, isSlot, loc }; } function createConditionalExpression(test, consequent, alternate, newline = true) { return { type: 19 /* JS_CONDITIONAL_EXPRESSION */, test, consequent, alternate, newline, loc: locStub }; } function createCacheExpression(index, value, isVNode = false) { return { type: 20 /* JS_CACHE_EXPRESSION */, index, value, isVNode, loc: locStub }; } function createBlockStatement(body) { return { type: 21 /* JS_BLOCK_STATEMENT */, body, loc: locStub }; } function createTemplateLiteral(elements) { return { type: 22 /* JS_TEMPLATE_LITERAL */, elements, loc: locStub }; } function createIfStatement(test, consequent, alternate) { return { type: 23 /* JS_IF_STATEMENT */, test, consequent, alternate, loc: locStub }; } function createAssignmentExpression(left, right) { return { type: 24 /* JS_ASSIGNMENT_EXPRESSION */, left, right, loc: locStub }; } function createSequenceExpression(expressions) { return { type: 25 /* JS_SEQUENCE_EXPRESSION */, expressions, loc: locStub }; } function createReturnStatement(returns) { return { type: 26 /* JS_RETURN_STATEMENT */, returns, loc: locStub }; } const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic; const isBuiltInType = (tag, expected) => tag === expected || tag === (0,shared_esm_bundler.hyphenate)(expected); function isCoreComponent(tag) { if (isBuiltInType(tag, 'Teleport')) { return TELEPORT; } else if (isBuiltInType(tag, 'Suspense')) { return SUSPENSE; } else if (isBuiltInType(tag, 'KeepAlive')) { return KEEP_ALIVE; } else if (isBuiltInType(tag, 'BaseTransition')) { return BASE_TRANSITION; } } const nonIdentifierRE = /^\d|[^\$\w]/; const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name); const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/; const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/; const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g; /** * Simple lexer to check if an expression is a member expression. This is * lax and only checks validity at the root level (i.e. does not validate exps * inside square brackets), but it's ok since these are only used on template * expressions and false positives are invalid expressions in the first place. */ const isMemberExpressionBrowser = (path) => { // remove whitespaces around . or [ first path = path.trim().replace(whitespaceRE, s => s.trim()); let state = 0 /* inMemberExp */; let stateStack = []; let currentOpenBracketCount = 0; let currentOpenParensCount = 0; let currentStringType = null; for (let i = 0; i < path.length; i++) { const char = path.charAt(i); switch (state) { case 0 /* inMemberExp */: if (char === '[') { stateStack.push(state); state = 1 /* inBrackets */; currentOpenBracketCount++; } else if (char === '(') { stateStack.push(state); state = 2 /* inParens */; currentOpenParensCount++; } else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) { return false; } break; case 1 /* inBrackets */: if (char === `'` || char === `"` || char === '`') { stateStack.push(state); state = 3 /* inString */; currentStringType = char; } else if (char === `[`) { currentOpenBracketCount++; } else if (char === `]`) { if (!--currentOpenBracketCount) { state = stateStack.pop(); } } break; case 2 /* inParens */: if (char === `'` || char === `"` || char === '`') { stateStack.push(state); state = 3 /* inString */; currentStringType = char; } else if (char === `(`) { currentOpenParensCount++; } else if (char === `)`) { // if the exp ends as a call then it should not be considered valid if (i === path.length - 1) { return false; } if (!--currentOpenParensCount) { state = stateStack.pop(); } } break; case 3 /* inString */: if (char === currentStringType) { state = stateStack.pop(); currentStringType = null; } break; } } return !currentOpenBracketCount && !currentOpenParensCount; }; const isMemberExpressionNode = shared_esm_bundler.NOOP ; const isMemberExpression = isMemberExpressionBrowser ; function getInnerRange(loc, offset, length) { const source = loc.source.slice(offset, offset + length); const newLoc = { source, start: advancePositionWithClone(loc.start, loc.source, offset), end: loc.end }; if (length != null) { newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length); } return newLoc; } function advancePositionWithClone(pos, source, numberOfCharacters = source.length) { return advancePositionWithMutation((0,shared_esm_bundler.extend)({}, pos), source, numberOfCharacters); } // advance by mutation without cloning (for performance reasons), since this // gets called a lot in the parser function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) { let linesCount = 0; let lastNewLinePos = -1; for (let i = 0; i < numberOfCharacters; i++) { if (source.charCodeAt(i) === 10 /* newline char code */) { linesCount++; lastNewLinePos = i; } } pos.offset += numberOfCharacters; pos.line += linesCount; pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos; return pos; } function assert(condition, msg) { /* istanbul ignore if */ if (!condition) { throw new Error(msg || `unexpected compiler condition`); } } function findDir(node, name, allowEmpty = false) { for (let i = 0; i < node.props.length; i++) { const p = node.props[i]; if (p.type === 7 /* DIRECTIVE */ && (allowEmpty || p.exp) && ((0,shared_esm_bundler.isString)(name) ? p.name === name : name.test(p.name))) { return p; } } } function findProp(node, name, dynamicOnly = false, allowEmpty = false) { for (let i = 0; i < node.props.length; i++) { const p = node.props[i]; if (p.type === 6 /* ATTRIBUTE */) { if (dynamicOnly) continue; if (p.name === name && (p.value || allowEmpty)) { return p; } } else if (p.name === 'bind' && (p.exp || allowEmpty) && isBindKey(p.arg, name)) { return p; } } } function isBindKey(arg, name) { return !!(arg && isStaticExp(arg) && arg.content === name); } function hasDynamicKeyVBind(node) { return node.props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && (!p.arg || // v-bind="obj" p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo] !p.arg.isStatic) // v-bind:[foo] ); } function isText(node) { return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */; } function isVSlot(p) { return p.type === 7 /* DIRECTIVE */ && p.name === 'slot'; } function isTemplateNode(node) { return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */); } function isSlotOutlet(node) { return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */; } function getVNodeHelper(ssr, isComponent) { return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE; } function getVNodeBlockHelper(ssr, isComponent) { return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK; } const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]); function getUnnormalizedProps(props, callPath = []) { if (props && !(0,shared_esm_bundler.isString)(props) && props.type === 14 /* JS_CALL_EXPRESSION */) { const callee = props.callee; if (!(0,shared_esm_bundler.isString)(callee) && propsHelperSet.has(callee)) { return getUnnormalizedProps(props.arguments[0], callPath.concat(props)); } } return [props, callPath]; } function injectProp(node, prop, context) { let propsWithInjection; const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2]; /** * 1. mergeProps(...) * 2. toHandlers(...) * 3. normalizeProps(...) * 4. normalizeProps(guardReactiveProps(...)) * * we need to get the real props before normalization */ let props = originalProps; let callPath = []; let parentCall; if (props && !(0,shared_esm_bundler.isString)(props) && props.type === 14 /* JS_CALL_EXPRESSION */) { const ret = getUnnormalizedProps(props); props = ret[0]; callPath = ret[1]; parentCall = callPath[callPath.length - 1]; } if (props == null || (0,shared_esm_bundler.isString)(props)) { propsWithInjection = createObjectExpression([prop]); } else if (props.type === 14 /* JS_CALL_EXPRESSION */) { // merged props... add ours // only inject key to object literal if it's the first argument so that // if doesn't override user provided keys const first = props.arguments[0]; if (!(0,shared_esm_bundler.isString)(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) { first.properties.unshift(prop); } else { if (props.callee === TO_HANDLERS) { // #2366 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [ createObjectExpression([prop]), props ]); } else { props.arguments.unshift(createObjectExpression([prop])); } } !propsWithInjection && (propsWithInjection = props); } else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) { let alreadyExists = false; // check existing key to avoid overriding user provided keys if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) { const propKeyName = prop.key.content; alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ && p.key.content === propKeyName); } if (!alreadyExists) { props.properties.unshift(prop); } propsWithInjection = props; } else { // single v-bind with expression, return a merged replacement propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [ createObjectExpression([prop]), props ]); // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`, // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`, // the `guardReactiveProps` will no longer be needed if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) { parentCall = callPath[callPath.length - 2]; } } if (node.type === 13 /* VNODE_CALL */) { if (parentCall) { parentCall.arguments[0] = propsWithInjection; } else { node.props = propsWithInjection; } } else { if (parentCall) { parentCall.arguments[0] = propsWithInjection; } else { node.arguments[2] = propsWithInjection; } } } function toValidAssetId(name, type) { // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => { return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString(); })}`; } // Check if a node contains expressions that reference current context scope ids function hasScopeRef(node, ids) { if (!node || Object.keys(ids).length === 0) { return false; } switch (node.type) { case 1 /* ELEMENT */: for (let i = 0; i < node.props.length; i++) { const p = node.props[i]; if (p.type === 7 /* DIRECTIVE */ && (hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) { return true; } } return node.children.some(c => hasScopeRef(c, ids)); case 11 /* FOR */: if (hasScopeRef(node.source, ids)) { return true; } return node.children.some(c => hasScopeRef(c, ids)); case 9 /* IF */: return node.branches.some(b => hasScopeRef(b, ids)); case 10 /* IF_BRANCH */: if (hasScopeRef(node.condition, ids)) { return true; } return node.children.some(c => hasScopeRef(c, ids)); case 4 /* SIMPLE_EXPRESSION */: return (!node.isStatic && isSimpleIdentifier(node.content) && !!ids[node.content]); case 8 /* COMPOUND_EXPRESSION */: return node.children.some(c => (0,shared_esm_bundler.isObject)(c) && hasScopeRef(c, ids)); case 5 /* INTERPOLATION */: case 12 /* TEXT_CALL */: return hasScopeRef(node.content, ids); case 2 /* TEXT */: case 3 /* COMMENT */: return false; default: if ((false)) {} return false; } } function getMemoedVNodeCall(node) { if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) { return node.arguments[1].returns; } else { return node; } } function makeBlock(node, { helper, removeHelper, inSSR }) { if (!node.isBlock) { node.isBlock = true; removeHelper(getVNodeHelper(inSSR, node.isComponent)); helper(OPEN_BLOCK); helper(getVNodeBlockHelper(inSSR, node.isComponent)); } } const deprecationData = { ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: { message: `Platform-native elements with "is" prop will no longer be ` + `treated as components in Vue 3 unless the "is" value is explicitly ` + `prefixed with "vue:".`, link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html` }, ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: { message: key => `.sync modifier for v-bind has been removed. Use v-model with ` + `argument instead. \`v-bind:${key}.sync\` should be changed to ` + `\`v-model:${key}\`.`, link: `https://v3.vuejs.org/guide/migration/v-model.html` }, ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: { message: `.prop modifier for v-bind has been removed and no longer necessary. ` + `Vue 3 will automatically set a binding as DOM property when appropriate.` }, ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: { message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` + `object spread: it will now overwrite an existing non-mergeable attribute ` + `that appears before v-bind in the case of conflict. ` + `To retain 2.x behavior, move v-bind to make it the first attribute. ` + `You can also suppress this warning if the usage is intended.`, link: `https://v3.vuejs.org/guide/migration/v-bind.html` }, ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: { message: `.native modifier for v-on has been removed as is no longer necessary.`, link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html` }, ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: { message: `v-if / v-for precedence when used on the same element has changed ` + `in Vue 3: v-if now takes higher precedence and will no longer have ` + `access to v-for scope variables. It is best to avoid the ambiguity ` + `with <template> tags or use a computed property that filters v-for ` + `data source.`, link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html` }, ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: { message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` + `Consider using function refs or refactor to avoid ref usage altogether.`, link: `https://v3.vuejs.org/guide/migration/array-refs.html` }, ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: { message: `<template> with no special directives will render as a native template ` + `element instead of its inner content in Vue 3.` }, ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: { message: `"inline-template" has been removed in Vue 3.`, link: `https://v3.vuejs.org/guide/migration/inline-template-attribute.html` }, ["COMPILER_FILTER" /* COMPILER_FILTERS */]: { message: `filters have been removed in Vue 3. ` + `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` + `Use method calls or computed properties instead.`, link: `https://v3.vuejs.org/guide/migration/filters.html` } }; function getCompatValue(key, context) { const config = context.options ? context.options.compatConfig : context.compatConfig; const value = config && config[key]; if (key === 'MODE') { return value || 3; // compiler defaults to v3 behavior } else { return value; } } function isCompatEnabled(key, context) { const mode = getCompatValue('MODE', context); const value = getCompatValue(key, context); // in v3 mode, only enable if explicitly set to true // otherwise enable for any non-false value return mode === 3 ? value === true : value !== false; } function checkCompatEnabled(key, context, loc, ...args) { const enabled = isCompatEnabled(key, context); if (false) {} return enabled; } function warnDeprecation(key, context, loc, ...args) { const val = getCompatValue(key, context); if (val === 'suppress-warning') { return; } const { message, link } = deprecationData[key]; const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`; const err = new SyntaxError(msg); err.code = key; if (loc) err.loc = loc; context.onWarn(err); } // The default decoder only provides escapes for characters reserved as part of // the template syntax, and is only used if the custom renderer did not provide // a platform-specific decoder. const decodeRE = /&(gt|lt|amp|apos|quot);/g; const decodeMap = { gt: '>', lt: '<', amp: '&', apos: "'", quot: '"' }; const defaultParserOptions = { delimiters: [`{{`, `}}`], getNamespace: () => 0 /* HTML */, getTextMode: () => 0 /* DATA */, isVoidTag: shared_esm_bundler.NO, isPreTag: shared_esm_bundler.NO, isCustomElement: shared_esm_bundler.NO, decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]), onError: defaultOnError, onWarn: defaultOnWarn, comments: ("production" !== 'production') }; function baseParse(content, options = {}) { const context = createParserContext(content, options); const start = getCursor(context); return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start)); } function createParserContext(content, rawOptions) { const options = (0,shared_esm_bundler.extend)({}, defaultParserOptions); let key; for (key in rawOptions) { // @ts-ignore options[key] = rawOptions[key] === undefined ? defaultParserOptions[key] : rawOptions[key]; } return { options, column: 1, line: 1, offset: 0, originalSource: content, source: content, inPre: false, inVPre: false, onWarn: options.onWarn }; } function parseChildren(context, mode, ancestors) { const parent = last(ancestors); const ns = parent ? parent.ns : 0 /* HTML */; const nodes = []; while (!isEnd(context, mode, ancestors)) { const s = context.source; let node = undefined; if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) { if (!context.inVPre && startsWith(s, context.options.delimiters[0])) { // '{{' node = parseInterpolation(context, mode); } else if (mode === 0 /* DATA */ && s[0] === '<') { // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state if (s.length === 1) { emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1); } else if (s[1] === '!') { // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state if (startsWith(s, '<!--')) { node = parseComment(context); } else if (startsWith(s, '<!DOCTYPE')) { // Ignore DOCTYPE by a limitation. node = parseBogusComment(context); } else if (startsWith(s, '<![CDATA[')) { if (ns !== 0 /* HTML */) { node = parseCDATA(context, ancestors); } else { emitError(context, 1 /* CDATA_IN_HTML_CONTENT */); node = parseBogusComment(context); } } else { emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */); node = parseBogusComment(context); } } else if (s[1] === '/') { // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state if (s.length === 2) { emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2); } else if (s[2] === '>') { emitError(context, 14 /* MISSING_END_TAG_NAME */, 2); advanceBy(context, 3); continue; } else if (/[a-z]/i.test(s[2])) { emitError(context, 23 /* X_INVALID_END_TAG */); parseTag(context, 1 /* End */, parent); continue; } else { emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2); node = parseBogusComment(context); } } else if (/[a-z]/i.test(s[1])) { node = parseElement(context, ancestors); // 2.x <template> with no directive compat if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) && node && node.tag === 'template' && !node.props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) { ( false) && 0; node = node.children; } } else if (s[1] === '?') { emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1); node = parseBogusComment(context); } else { emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1); } } } if (!node) { node = parseText(context, mode); } if ((0,shared_esm_bundler.isArray)(node)) { for (let i = 0; i < node.length; i++) { pushNode(nodes, node[i]); } } else { pushNode(nodes, node); } } // Whitespace handling strategy like v2 let removedWhitespace = false; if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) { const shouldCondense = context.options.whitespace !== 'preserve'; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (!context.inPre && node.type === 2 /* TEXT */) { if (!/[^\t\r\n\f ]/.test(node.content)) { const prev = nodes[i - 1]; const next = nodes[i + 1]; // Remove if: // - the whitespace is the first or last node, or: // - (condense mode) the whitespace is adjacent to a comment, or: // - (condense mode) the whitespace is between two elements AND contains newline if (!prev || !next || (shouldCondense && (prev.type === 3 /* COMMENT */ || next.type === 3 /* COMMENT */ || (prev.type === 1 /* ELEMENT */ && next.type === 1 /* ELEMENT */ && /[\r\n]/.test(node.content))))) { removedWhitespace = true; nodes[i] = null; } else { // Otherwise, the whitespace is condensed into a single space node.content = ' '; } } else if (shouldCondense) { // in condense mode, consecutive whitespaces in text are condensed // down to a single space. node.content = node.content.replace(/[\t\r\n\f ]+/g, ' '); } } // Remove comment nodes if desired by configuration. else if (node.type === 3 /* COMMENT */ && !context.options.comments) { removedWhitespace = true; nodes[i] = null; } } if (context.inPre && parent && context.options.isPreTag(parent.tag)) { // remove leading newline per html spec // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element const first = nodes[0]; if (first && first.type === 2 /* TEXT */) { first.content = first.content.replace(/^\r?\n/, ''); } } } return removedWhitespace ? nodes.filter(Boolean) : nodes; } function pushNode(nodes, node) { if (node.type === 2 /* TEXT */) { const prev = last(nodes); // Merge if both this and the previous node are text and those are // consecutive. This happens for cases like "a < b". if (prev && prev.type === 2 /* TEXT */ && prev.loc.end.offset === node.loc.start.offset) { prev.content += node.content; prev.loc.end = node.loc.end; prev.loc.source += node.loc.source; return; } } nodes.push(node); } function parseCDATA(context, ancestors) { advanceBy(context, 9); const nodes = parseChildren(context, 3 /* CDATA */, ancestors); if (context.source.length === 0) { emitError(context, 6 /* EOF_IN_CDATA */); } else { advanceBy(context, 3); } return nodes; } function parseComment(context) { const start = getCursor(context); let content; // Regular comment. const match = /--(\!)?>/.exec(context.source); if (!match) { content = context.source.slice(4); advanceBy(context, context.source.length); emitError(context, 7 /* EOF_IN_COMMENT */); } else { if (match.index <= 3) { emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */); } if (match[1]) { emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */); } content = context.source.slice(4, match.index); // Advancing with reporting nested comments. const s = context.source.slice(0, match.index); let prevIndex = 1, nestedIndex = 0; while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) { advanceBy(context, nestedIndex - prevIndex + 1); if (nestedIndex + 4 < s.length) { emitError(context, 16 /* NESTED_COMMENT */); } prevIndex = nestedIndex + 1; } advanceBy(context, match.index + match[0].length - prevIndex + 1); } return { type: 3 /* COMMENT */, content, loc: getSelection(context, start) }; } function parseBogusComment(context) { const start = getCursor(context); const contentStart = context.source[1] === '?' ? 1 : 2; let content; const closeIndex = context.source.indexOf('>'); if (closeIndex === -1) { content = context.source.slice(contentStart); advanceBy(context, context.source.length); } else { content = context.source.slice(contentStart, closeIndex); advanceBy(context, closeIndex + 1); } return { type: 3 /* COMMENT */, content, loc: getSelection(context, start) }; } function parseElement(context, ancestors) { // Start tag. const wasInPre = context.inPre; const wasInVPre = context.inVPre; const parent = last(ancestors); const element = parseTag(context, 0 /* Start */, parent); const isPreBoundary = context.inPre && !wasInPre; const isVPreBoundary = context.inVPre && !wasInVPre; if (element.isSelfClosing || context.options.isVoidTag(element.tag)) { // #4030 self-closing <pre> tag if (isPreBoundary) { context.inPre = false; } if (isVPreBoundary) { context.inVPre = false; } return element; } // Children. ancestors.push(element); const mode = context.options.getTextMode(element, parent); const children = parseChildren(context, mode, ancestors); ancestors.pop(); // 2.x inline-template compat { const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template'); if (inlineTemplateProp && checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) { const loc = getSelection(context, element.loc.end); inlineTemplateProp.value = { type: 2 /* TEXT */, content: loc.source, loc }; } } element.children = children; // End tag. if (startsWithEndTagOpen(context.source, element.tag)) { parseTag(context, 1 /* End */, parent); } else { emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start); if (context.source.length === 0 && element.tag.toLowerCase() === 'script') { const first = children[0]; if (first && startsWith(first.loc.source, '<!--')) { emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */); } } } element.loc = getSelection(context, element.loc.start); if (isPreBoundary) { context.inPre = false; } if (isVPreBoundary) { context.inVPre = false; } return element; } const isSpecialTemplateDirective = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)(`if,else,else-if,for,slot`); function parseTag(context, type, parent) { // Tag open. const start = getCursor(context); const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source); const tag = match[1]; const ns = context.options.getNamespace(tag, parent); advanceBy(context, match[0].length); advanceSpaces(context); // save current state in case we need to re-parse attributes with v-pre const cursor = getCursor(context); const currentSource = context.source; // check <pre> tag if (context.options.isPreTag(tag)) { context.inPre = true; } // Attributes. let props = parseAttributes(context, type); // check v-pre if (type === 0 /* Start */ && !context.inVPre && props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) { context.inVPre = true; // reset context (0,shared_esm_bundler.extend)(context, cursor); context.source = currentSource; // re-parse attrs and filter out v-pre itself props = parseAttributes(context, type).filter(p => p.name !== 'v-pre'); } // Tag close. let isSelfClosing = false; if (context.source.length === 0) { emitError(context, 9 /* EOF_IN_TAG */); } else { isSelfClosing = startsWith(context.source, '/>'); if (type === 1 /* End */ && isSelfClosing) { emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */); } advanceBy(context, isSelfClosing ? 2 : 1); } if (type === 1 /* End */) { return; } // 2.x deprecation checks if (false) {} let tagType = 0 /* ELEMENT */; if (!context.inVPre) { if (tag === 'slot') { tagType = 2 /* SLOT */; } else if (tag === 'template') { if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) { tagType = 3 /* TEMPLATE */; } } else if (isComponent(tag, props, context)) { tagType = 1 /* COMPONENT */; } } return { type: 1 /* ELEMENT */, ns, tag, tagType, props, isSelfClosing, children: [], loc: getSelection(context, start), codegenNode: undefined // to be created during transform phase }; } function isComponent(tag, props, context) { const options = context.options; if (options.isCustomElement(tag)) { return false; } if (tag === 'component' || /^[A-Z]/.test(tag) || isCoreComponent(tag) || (options.isBuiltInComponent && options.isBuiltInComponent(tag)) || (options.isNativeTag && !options.isNativeTag(tag))) { return true; } // at this point the tag should be a native tag, but check for potential "is" // casting for (let i = 0; i < props.length; i++) { const p = props[i]; if (p.type === 6 /* ATTRIBUTE */) { if (p.name === 'is' && p.value) { if (p.value.content.startsWith('vue:')) { return true; } else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) { return true; } } } else { // directive // v-is (TODO Deprecate) if (p.name === 'is') { return true; } else if ( // :is on plain element - only treat as component in compat mode p.name === 'bind' && isBindKey(p.arg, 'is') && true && checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) { return true; } } } } function parseAttributes(context, type) { const props = []; const attributeNames = new Set(); while (context.source.length > 0 && !startsWith(context.source, '>') && !startsWith(context.source, '/>')) { if (startsWith(context.source, '/')) { emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */); advanceBy(context, 1); advanceSpaces(context); continue; } if (type === 1 /* End */) { emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */); } const attr = parseAttribute(context, attributeNames); // Trim whitespace between class // https://github.com/vuejs/vue-next/issues/4251 if (attr.type === 6 /* ATTRIBUTE */ && attr.value && attr.name === 'class') { attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim(); } if (type === 0 /* Start */) { props.push(attr); } if (/^[^\t\r\n\f />]/.test(context.source)) { emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */); } advanceSpaces(context); } return props; } function parseAttribute(context, nameSet) { // Name. const start = getCursor(context); const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source); const name = match[0]; if (nameSet.has(name)) { emitError(context, 2 /* DUPLICATE_ATTRIBUTE */); } nameSet.add(name); if (name[0] === '=') { emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */); } { const pattern = /["'<]/g; let m; while ((m = pattern.exec(name))) { emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index); } } advanceBy(context, name.length); // Value let value = undefined; if (/^[\t\r\n\f ]*=/.test(context.source)) { advanceSpaces(context); advanceBy(context, 1); advanceSpaces(context); value = parseAttributeValue(context); if (!value) { emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */); } } const loc = getSelection(context, start); if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) { const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name); let isPropShorthand = startsWith(name, '.'); let dirName = match[1] || (isPropShorthand || startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot'); let arg; if (match[2]) { const isSlot = dirName === 'slot'; const startOffset = name.lastIndexOf(match[2]); const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length)); let content = match[2]; let isStatic = true; if (content.startsWith('[')) { isStatic = false; if (!content.endsWith(']')) { emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */); content = content.slice(1); } else { content = content.slice(1, content.length - 1); } } else if (isSlot) { // #1241 special case for v-slot: vuetify relies extensively on slot // names containing dots. v-slot doesn't have any modifiers and Vue 2.x // supports such usage so we are keeping it consistent with 2.x. content += match[3] || ''; } arg = { type: 4 /* SIMPLE_EXPRESSION */, content, isStatic, constType: isStatic ? 3 /* CAN_STRINGIFY */ : 0 /* NOT_CONSTANT */, loc }; } if (value && value.isQuoted) { const valueLoc = value.loc; valueLoc.start.offset++; valueLoc.start.column++; valueLoc.end = advancePositionWithClone(valueLoc.start, value.content); valueLoc.source = valueLoc.source.slice(1, -1); } const modifiers = match[3] ? match[3].slice(1).split('.') : []; if (isPropShorthand) modifiers.push('prop'); // 2.x compat v-bind:foo.sync -> v-model:foo if (dirName === 'bind' && arg) { if (modifiers.includes('sync') && checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) { dirName = 'model'; modifiers.splice(modifiers.indexOf('sync'), 1); } if (false) {} } return { type: 7 /* DIRECTIVE */, name: dirName, exp: value && { type: 4 /* SIMPLE_EXPRESSION */, content: value.content, isStatic: false, // Treat as non-constant by default. This can be potentially set to // other values by `transformExpression` to make it eligible for hoisting. constType: 0 /* NOT_CONSTANT */, loc: value.loc }, arg, modifiers, loc }; } // missing directive name or illegal directive name if (!context.inVPre && startsWith(name, 'v-')) { emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */); } return { type: 6 /* ATTRIBUTE */, name, value: value && { type: 2 /* TEXT */, content: value.content, loc: value.loc }, loc }; } function parseAttributeValue(context) { const start = getCursor(context); let content; const quote = context.source[0]; const isQuoted = quote === `"` || quote === `'`; if (isQuoted) { // Quoted value. advanceBy(context, 1); const endIndex = context.source.indexOf(quote); if (endIndex === -1) { content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */); } else { content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */); advanceBy(context, 1); } } else { // Unquoted const match = /^[^\t\r\n\f >]+/.exec(context.source); if (!match) { return undefined; } const unexpectedChars = /["'<=`]/g; let m; while ((m = unexpectedChars.exec(match[0]))) { emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index); } content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */); } return { content, isQuoted, loc: getSelection(context, start) }; } function parseInterpolation(context, mode) { const [open, close] = context.options.delimiters; const closeIndex = context.source.indexOf(close, open.length); if (closeIndex === -1) { emitError(context, 25 /* X_MISSING_INTERPOLATION_END */); return undefined; } const start = getCursor(context); advanceBy(context, open.length); const innerStart = getCursor(context); const innerEnd = getCursor(context); const rawContentLength = closeIndex - open.length; const rawContent = context.source.slice(0, rawContentLength); const preTrimContent = parseTextData(context, rawContentLength, mode); const content = preTrimContent.trim(); const startOffset = preTrimContent.indexOf(content); if (startOffset > 0) { advancePositionWithMutation(innerStart, rawContent, startOffset); } const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset); advancePositionWithMutation(innerEnd, rawContent, endOffset); advanceBy(context, close.length); return { type: 5 /* INTERPOLATION */, content: { type: 4 /* SIMPLE_EXPRESSION */, isStatic: false, // Set `isConstant` to false by default and will decide in transformExpression constType: 0 /* NOT_CONSTANT */, content, loc: getSelection(context, innerStart, innerEnd) }, loc: getSelection(context, start) }; } function parseText(context, mode) { const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]]; let endIndex = context.source.length; for (let i = 0; i < endTokens.length; i++) { const index = context.source.indexOf(endTokens[i], 1); if (index !== -1 && endIndex > index) { endIndex = index; } } const start = getCursor(context); const content = parseTextData(context, endIndex, mode); return { type: 2 /* TEXT */, content, loc: getSelection(context, start) }; } /** * Get text data with a given length from the current location. * This translates HTML entities in the text data. */ function parseTextData(context, length, mode) { const rawText = context.source.slice(0, length); advanceBy(context, length); if (mode === 2 /* RAWTEXT */ || mode === 3 /* CDATA */ || rawText.indexOf('&') === -1) { return rawText; } else { // DATA or RCDATA containing "&"". Entity decoding required. return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */); } } function getCursor(context) { const { column, line, offset } = context; return { column, line, offset }; } function getSelection(context, start, end) { end = end || getCursor(context); return { start, end, source: context.originalSource.slice(start.offset, end.offset) }; } function last(xs) { return xs[xs.length - 1]; } function startsWith(source, searchString) { return source.startsWith(searchString); } function advanceBy(context, numberOfCharacters) { const { source } = context; advancePositionWithMutation(context, source, numberOfCharacters); context.source = source.slice(numberOfCharacters); } function advanceSpaces(context) { const match = /^[\t\r\n\f ]+/.exec(context.source); if (match) { advanceBy(context, match[0].length); } } function getNewPosition(context, start, numberOfCharacters) { return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters); } function emitError(context, code, offset, loc = getCursor(context)) { if (offset) { loc.offset += offset; loc.column += offset; } context.options.onError(createCompilerError(code, { start: loc, end: loc, source: '' })); } function isEnd(context, mode, ancestors) { const s = context.source; switch (mode) { case 0 /* DATA */: if (startsWith(s, '</')) { // TODO: probably bad performance for (let i = ancestors.length - 1; i >= 0; --i) { if (startsWithEndTagOpen(s, ancestors[i].tag)) { return true; } } } break; case 1 /* RCDATA */: case 2 /* RAWTEXT */: { const parent = last(ancestors); if (parent && startsWithEndTagOpen(s, parent.tag)) { return true; } break; } case 3 /* CDATA */: if (startsWith(s, ']]>')) { return true; } break; } return !s; } function startsWithEndTagOpen(source, tag) { return (startsWith(source, '</') && source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() && /[\t\r\n\f />]/.test(source[2 + tag.length] || '>')); } function hoistStatic(root, context) { walk(root, context, // Root node is unfortunately non-hoistable due to potential parent // fallthrough attributes. isSingleElementRoot(root, root.children[0])); } function isSingleElementRoot(root, child) { const { children } = root; return (children.length === 1 && child.type === 1 /* ELEMENT */ && !isSlotOutlet(child)); } function walk(node, context, doNotHoistNode = false) { // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces // static bindings with expressions. These expressions are guaranteed to be // constant so they are still eligible for hoisting, but they are only // available at runtime and therefore cannot be evaluated ahead of time. // This is only a concern for pre-stringification (via transformHoist by // @vue/compiler-dom), but doing it here allows us to perform only one full // walk of the AST and allow `stringifyStatic` to stop walking as soon as its // stringification threshold is met. let canStringify = true; const { children } = node; const originalCount = children.length; let hoistedCount = 0; for (let i = 0; i < children.length; i++) { const child = children[i]; // only plain elements & text calls are eligible for hoisting. if (child.type === 1 /* ELEMENT */ && child.tagType === 0 /* ELEMENT */) { const constantType = doNotHoistNode ? 0 /* NOT_CONSTANT */ : getConstantType(child, context); if (constantType > 0 /* NOT_CONSTANT */) { if (constantType < 3 /* CAN_STRINGIFY */) { canStringify = false; } if (constantType >= 2 /* CAN_HOIST */) { child.codegenNode.patchFlag = -1 /* HOISTED */ + (( false) ? 0 : ``); child.codegenNode = context.hoist(child.codegenNode); hoistedCount++; continue; } } else { // node may contain dynamic children, but its props may be eligible for // hoisting. const codegenNode = child.codegenNode; if (codegenNode.type === 13 /* VNODE_CALL */) { const flag = getPatchFlag(codegenNode); if ((!flag || flag === 512 /* NEED_PATCH */ || flag === 1 /* TEXT */) && getGeneratedPropsConstantType(child, context) >= 2 /* CAN_HOIST */) { const props = getNodeProps(child); if (props) { codegenNode.props = context.hoist(props); } } if (codegenNode.dynamicProps) { codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps); } } } } else if (child.type === 12 /* TEXT_CALL */) { const contentType = getConstantType(child.content, context); if (contentType > 0) { if (contentType < 3 /* CAN_STRINGIFY */) { canStringify = false; } if (contentType >= 2 /* CAN_HOIST */) { child.codegenNode = context.hoist(child.codegenNode); hoistedCount++; } } } // walk further if (child.type === 1 /* ELEMENT */) { const isComponent = child.tagType === 1 /* COMPONENT */; if (isComponent) { context.scopes.vSlot++; } walk(child, context); if (isComponent) { context.scopes.vSlot--; } } else if (child.type === 11 /* FOR */) { // Do not hoist v-for single child because it has to be a block walk(child, context, child.children.length === 1); } else if (child.type === 9 /* IF */) { for (let i = 0; i < child.branches.length; i++) { // Do not hoist v-if single child because it has to be a block walk(child.branches[i], context, child.branches[i].children.length === 1); } } } if (canStringify && hoistedCount && context.transformHoist) { context.transformHoist(children, context, node); } // all children were hoisted - the entire children array is hoistable. if (hoistedCount && hoistedCount === originalCount && node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */ && node.codegenNode && node.codegenNode.type === 13 /* VNODE_CALL */ && (0,shared_esm_bundler.isArray)(node.codegenNode.children)) { node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children)); } } function getConstantType(node, context) { const { constantCache } = context; switch (node.type) { case 1 /* ELEMENT */: if (node.tagType !== 0 /* ELEMENT */) { return 0 /* NOT_CONSTANT */; } const cached = constantCache.get(node); if (cached !== undefined) { return cached; } const codegenNode = node.codegenNode; if (codegenNode.type !== 13 /* VNODE_CALL */) { return 0 /* NOT_CONSTANT */; } const flag = getPatchFlag(codegenNode); if (!flag) { let returnType = 3 /* CAN_STRINGIFY */; // Element itself has no patch flag. However we still need to check: // 1. Even for a node with no patch flag, it is possible for it to contain // non-hoistable expressions that refers to scope variables, e.g. compiler // injected keys or cached event handlers. Therefore we need to always // check the codegenNode's props to be sure. const generatedPropsType = getGeneratedPropsConstantType(node, context); if (generatedPropsType === 0 /* NOT_CONSTANT */) { constantCache.set(node, 0 /* NOT_CONSTANT */); return 0 /* NOT_CONSTANT */; } if (generatedPropsType < returnType) { returnType = generatedPropsType; } // 2. its children. for (let i = 0; i < node.children.length; i++) { const childType = getConstantType(node.children[i], context); if (childType === 0 /* NOT_CONSTANT */) { constantCache.set(node, 0 /* NOT_CONSTANT */); return 0 /* NOT_CONSTANT */; } if (childType < returnType) { returnType = childType; } } // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0 // type, check if any of the props can cause the type to be lowered // we can skip can_patch because it's guaranteed by the absence of a // patchFlag. if (returnType > 1 /* CAN_SKIP_PATCH */) { for (let i = 0; i < node.props.length; i++) { const p = node.props[i]; if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) { const expType = getConstantType(p.exp, context); if (expType === 0 /* NOT_CONSTANT */) { constantCache.set(node, 0 /* NOT_CONSTANT */); return 0 /* NOT_CONSTANT */; } if (expType < returnType) { returnType = expType; } } } } // only svg/foreignObject could be block here, however if they are // static then they don't need to be blocks since there will be no // nested updates. if (codegenNode.isBlock) { context.removeHelper(OPEN_BLOCK); context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent)); codegenNode.isBlock = false; context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent)); } constantCache.set(node, returnType); return returnType; } else { constantCache.set(node, 0 /* NOT_CONSTANT */); return 0 /* NOT_CONSTANT */; } case 2 /* TEXT */: case 3 /* COMMENT */: return 3 /* CAN_STRINGIFY */; case 9 /* IF */: case 11 /* FOR */: case 10 /* IF_BRANCH */: return 0 /* NOT_CONSTANT */; case 5 /* INTERPOLATION */: case 12 /* TEXT_CALL */: return getConstantType(node.content, context); case 4 /* SIMPLE_EXPRESSION */: return node.constType; case 8 /* COMPOUND_EXPRESSION */: let returnType = 3 /* CAN_STRINGIFY */; for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; if ((0,shared_esm_bundler.isString)(child) || (0,shared_esm_bundler.isSymbol)(child)) { continue; } const childType = getConstantType(child, context); if (childType === 0 /* NOT_CONSTANT */) { return 0 /* NOT_CONSTANT */; } else if (childType < returnType) { returnType = childType; } } return returnType; default: if ((false)) {} return 0 /* NOT_CONSTANT */; } } const allowHoistedHelperSet = new Set([ NORMALIZE_CLASS, NORMALIZE_STYLE, NORMALIZE_PROPS, GUARD_REACTIVE_PROPS ]); function getConstantTypeOfHelperCall(value, context) { if (value.type === 14 /* JS_CALL_EXPRESSION */ && !(0,shared_esm_bundler.isString)(value.callee) && allowHoistedHelperSet.has(value.callee)) { const arg = value.arguments[0]; if (arg.type === 4 /* SIMPLE_EXPRESSION */) { return getConstantType(arg, context); } else if (arg.type === 14 /* JS_CALL_EXPRESSION */) { // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))` return getConstantTypeOfHelperCall(arg, context); } } return 0 /* NOT_CONSTANT */; } function getGeneratedPropsConstantType(node, context) { let returnType = 3 /* CAN_STRINGIFY */; const props = getNodeProps(node); if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) { const { properties } = props; for (let i = 0; i < properties.length; i++) { const { key, value } = properties[i]; const keyType = getConstantType(key, context); if (keyType === 0 /* NOT_CONSTANT */) { return keyType; } if (keyType < returnType) { returnType = keyType; } let valueType; if (value.type === 4 /* SIMPLE_EXPRESSION */) { valueType = getConstantType(value, context); } else if (value.type === 14 /* JS_CALL_EXPRESSION */) { // some helper calls can be hoisted, // such as the `normalizeProps` generated by the compiler for pre-normalize class, // in this case we need to respect the ConstantType of the helper's argments valueType = getConstantTypeOfHelperCall(value, context); } else { valueType = 0 /* NOT_CONSTANT */; } if (valueType === 0 /* NOT_CONSTANT */) { return valueType; } if (valueType < returnType) { returnType = valueType; } } } return returnType; } function getNodeProps(node) { const codegenNode = node.codegenNode; if (codegenNode.type === 13 /* VNODE_CALL */) { return codegenNode.props; } } function getPatchFlag(node) { const flag = node.patchFlag; return flag ? parseInt(flag, 10) : undefined; } function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = shared_esm_bundler.NOOP, isCustomElement = shared_esm_bundler.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = shared_esm_bundler.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) { const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/); const context = { // options selfName: nameMatch && (0,shared_esm_bundler.capitalize)((0,shared_esm_bundler.camelize)(nameMatch[1])), prefixIdentifiers, hoistStatic, cacheHandlers, nodeTransforms, directiveTransforms, transformHoist, isBuiltInComponent, isCustomElement, expressionPlugins, scopeId, slotted, ssr, inSSR, ssrCssVars, bindingMetadata, inline, isTS, onError, onWarn, compatConfig, // state root, helpers: new Map(), components: new Set(), directives: new Set(), hoists: [], imports: [], constantCache: new Map(), temps: 0, cached: 0, identifiers: Object.create(null), scopes: { vFor: 0, vSlot: 0, vPre: 0, vOnce: 0 }, parent: null, currentNode: root, childIndex: 0, inVOnce: false, // methods helper(name) { const count = context.helpers.get(name) || 0; context.helpers.set(name, count + 1); return name; }, removeHelper(name) { const count = context.helpers.get(name); if (count) { const currentCount = count - 1; if (!currentCount) { context.helpers.delete(name); } else { context.helpers.set(name, currentCount); } } }, helperString(name) { return `_${helperNameMap[context.helper(name)]}`; }, replaceNode(node) { /* istanbul ignore if */ if ((false)) {} context.parent.children[context.childIndex] = context.currentNode = node; }, removeNode(node) { if (false) {} const list = context.parent.children; const removalIndex = node ? list.indexOf(node) : context.currentNode ? context.childIndex : -1; /* istanbul ignore if */ if (false) {} if (!node || node === context.currentNode) { // current node removed context.currentNode = null; context.onNodeRemoved(); } else { // sibling node removed if (context.childIndex > removalIndex) { context.childIndex--; context.onNodeRemoved(); } } context.parent.children.splice(removalIndex, 1); }, onNodeRemoved: () => { }, addIdentifiers(exp) { }, removeIdentifiers(exp) { }, hoist(exp) { if ((0,shared_esm_bundler.isString)(exp)) exp = createSimpleExpression(exp); context.hoists.push(exp); const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */); identifier.hoisted = exp; return identifier; }, cache(exp, isVNode = false) { return createCacheExpression(context.cached++, exp, isVNode); } }; { context.filters = new Set(); } return context; } function transform(root, options) { const context = createTransformContext(root, options); traverseNode(root, context); if (options.hoistStatic) { hoistStatic(root, context); } if (!options.ssr) { createRootCodegen(root, context); } // finalize meta information root.helpers = [...context.helpers.keys()]; root.components = [...context.components]; root.directives = [...context.directives]; root.imports = context.imports; root.hoists = context.hoists; root.temps = context.temps; root.cached = context.cached; { root.filters = [...context.filters]; } } function createRootCodegen(root, context) { const { helper } = context; const { children } = root; if (children.length === 1) { const child = children[0]; // if the single child is an element, turn it into a block. if (isSingleElementRoot(root, child) && child.codegenNode) { // single element root is never hoisted so codegenNode will never be // SimpleExpressionNode const codegenNode = child.codegenNode; if (codegenNode.type === 13 /* VNODE_CALL */) { makeBlock(codegenNode, context); } root.codegenNode = codegenNode; } else { // - single <slot/>, IfNode, ForNode: already blocks. // - single text node: always patched. // root codegen falls through via genNode() root.codegenNode = child; } } else if (children.length > 1) { // root has multiple nodes - return a fragment block. let patchFlag = 64 /* STABLE_FRAGMENT */; let patchFlagText = shared_esm_bundler.PatchFlagNames[64]; // check if the fragment actually contains a single valid child with // the rest being comments if (false) {} root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (( false) ? 0 : ``), undefined, undefined, true, undefined, false /* isComponent */); } else ; } function traverseChildren(parent, context) { let i = 0; const nodeRemoved = () => { i--; }; for (; i < parent.children.length; i++) { const child = parent.children[i]; if ((0,shared_esm_bundler.isString)(child)) continue; context.parent = parent; context.childIndex = i; context.onNodeRemoved = nodeRemoved; traverseNode(child, context); } } function traverseNode(node, context) { context.currentNode = node; // apply transform plugins const { nodeTransforms } = context; const exitFns = []; for (let i = 0; i < nodeTransforms.length; i++) { const onExit = nodeTransforms[i](node, context); if (onExit) { if ((0,shared_esm_bundler.isArray)(onExit)) { exitFns.push(...onExit); } else { exitFns.push(onExit); } } if (!context.currentNode) { // node was removed return; } else { // node may have been replaced node = context.currentNode; } } switch (node.type) { case 3 /* COMMENT */: if (!context.ssr) { // inject import for the Comment symbol, which is needed for creating // comment nodes with `createVNode` context.helper(CREATE_COMMENT); } break; case 5 /* INTERPOLATION */: // no need to traverse, but we need to inject toString helper if (!context.ssr) { context.helper(TO_DISPLAY_STRING); } break; // for container types, further traverse downwards case 9 /* IF */: for (let i = 0; i < node.branches.length; i++) { traverseNode(node.branches[i], context); } break; case 10 /* IF_BRANCH */: case 11 /* FOR */: case 1 /* ELEMENT */: case 0 /* ROOT */: traverseChildren(node, context); break; } // exit transforms context.currentNode = node; let i = exitFns.length; while (i--) { exitFns[i](); } } function createStructuralDirectiveTransform(name, fn) { const matches = (0,shared_esm_bundler.isString)(name) ? (n) => n === name : (n) => name.test(n); return (node, context) => { if (node.type === 1 /* ELEMENT */) { const { props } = node; // structural directive transforms are not concerned with slots // as they are handled separately in vSlot.ts if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) { return; } const exitFns = []; for (let i = 0; i < props.length; i++) { const prop = props[i]; if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) { // structural directives are removed to avoid infinite recursion // also we remove them *before* applying so that it can further // traverse itself in case it moves the node around props.splice(i, 1); i--; const onExit = fn(node, prop, context); if (onExit) exitFns.push(onExit); } } return exitFns; } }; } const PURE_ANNOTATION = `/*#__PURE__*/`; function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) { const context = { mode, prefixIdentifiers, sourceMap, filename, scopeId, optimizeImports, runtimeGlobalName, runtimeModuleName, ssrRuntimeModuleName, ssr, isTS, inSSR, source: ast.loc.source, code: ``, column: 1, line: 1, offset: 0, indentLevel: 0, pure: false, map: undefined, helper(key) { return `_${helperNameMap[key]}`; }, push(code, node) { context.code += code; }, indent() { newline(++context.indentLevel); }, deindent(withoutNewLine = false) { if (withoutNewLine) { --context.indentLevel; } else { newline(--context.indentLevel); } }, newline() { newline(context.indentLevel); } }; function newline(n) { context.push('\n' + ` `.repeat(n)); } return context; } function generate(ast, options = {}) { const context = createCodegenContext(ast, options); if (options.onContextCreated) options.onContextCreated(context); const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context; const hasHelpers = ast.helpers.length > 0; const useWithBlock = !prefixIdentifiers && mode !== 'module'; // preambles // in setup() inline mode, the preamble is generated in a sub context // and returned separately. const preambleContext = context; { genFunctionPreamble(ast, preambleContext); } // enter render function const functionName = ssr ? `ssrRender` : `render`; const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache']; const signature = args.join(', '); { push(`function ${functionName}(${signature}) {`); } indent(); if (useWithBlock) { push(`with (_ctx) {`); indent(); // function mode const declarations should be inside with block // also they should be renamed to avoid collision with user properties if (hasHelpers) { push(`const { ${ast.helpers .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`) .join(', ')} } = _Vue`); push(`\n`); newline(); } } // generate asset resolution statements if (ast.components.length) { genAssets(ast.components, 'component', context); if (ast.directives.length || ast.temps > 0) { newline(); } } if (ast.directives.length) { genAssets(ast.directives, 'directive', context); if (ast.temps > 0) { newline(); } } if (ast.filters && ast.filters.length) { newline(); genAssets(ast.filters, 'filter', context); newline(); } if (ast.temps > 0) { push(`let `); for (let i = 0; i < ast.temps; i++) { push(`${i > 0 ? `, ` : ``}_temp${i}`); } } if (ast.components.length || ast.directives.length || ast.temps) { push(`\n`); newline(); } // generate the VNode tree expression if (!ssr) { push(`return `); } if (ast.codegenNode) { genNode(ast.codegenNode, context); } else { push(`null`); } if (useWithBlock) { deindent(); push(`}`); } deindent(); push(`}`); return { ast, code: context.code, preamble: ``, // SourceMapGenerator does have toJSON() method but it's not in the types map: context.map ? context.map.toJSON() : undefined }; } function genFunctionPreamble(ast, context) { const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context; const VueBinding = runtimeGlobalName; const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`; // Generate const declaration for helpers // In prefix mode, we place the const declaration at top so it's done // only once; But if we not prefixing, we place the declaration inside the // with block so it doesn't incur the `in` check cost for every helper access. if (ast.helpers.length > 0) { { // "with" mode. // save Vue in a separate variable to avoid collision push(`const _Vue = ${VueBinding}\n`); // in "with" mode, helpers are declared inside the with block to avoid // has check cost, but hoists are lifted out of the function - we need // to provide the helper here. if (ast.hoists.length) { const staticHelpers = [ CREATE_VNODE, CREATE_ELEMENT_VNODE, CREATE_COMMENT, CREATE_TEXT, CREATE_STATIC ] .filter(helper => ast.helpers.includes(helper)) .map(aliasHelper) .join(', '); push(`const { ${staticHelpers} } = _Vue\n`); } } } genHoists(ast.hoists, context); newline(); push(`return `); } function genAssets(assets, type, { helper, push, newline, isTS }) { const resolver = helper(type === 'filter' ? RESOLVE_FILTER : type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE); for (let i = 0; i < assets.length; i++) { let id = assets[i]; // potential component implicit self-reference inferred from SFC filename const maybeSelfReference = id.endsWith('__self'); if (maybeSelfReference) { id = id.slice(0, -6); } push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`); if (i < assets.length - 1) { newline(); } } } function genHoists(hoists, context) { if (!hoists.length) { return; } context.pure = true; const { push, newline, helper, scopeId, mode } = context; newline(); for (let i = 0; i < hoists.length; i++) { const exp = hoists[i]; if (exp) { push(`const _hoisted_${i + 1} = ${``}`); genNode(exp, context); newline(); } } context.pure = false; } function isText$1(n) { return (isString(n) || n.type === 4 /* SIMPLE_EXPRESSION */ || n.type === 2 /* TEXT */ || n.type === 5 /* INTERPOLATION */ || n.type === 8 /* COMPOUND_EXPRESSION */); } function genNodeListAsArray(nodes, context) { const multilines = nodes.length > 3 || ((( false)) && 0); context.push(`[`); multilines && context.indent(); genNodeList(nodes, context, multilines); multilines && context.deindent(); context.push(`]`); } function genNodeList(nodes, context, multilines = false, comma = true) { const { push, newline } = context; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if ((0,shared_esm_bundler.isString)(node)) { push(node); } else if ((0,shared_esm_bundler.isArray)(node)) { genNodeListAsArray(node, context); } else { genNode(node, context); } if (i < nodes.length - 1) { if (multilines) { comma && push(','); newline(); } else { comma && push(', '); } } } } function genNode(node, context) { if ((0,shared_esm_bundler.isString)(node)) { context.push(node); return; } if ((0,shared_esm_bundler.isSymbol)(node)) { context.push(context.helper(node)); return; } switch (node.type) { case 1 /* ELEMENT */: case 9 /* IF */: case 11 /* FOR */: ( false) && 0; genNode(node.codegenNode, context); break; case 2 /* TEXT */: genText(node, context); break; case 4 /* SIMPLE_EXPRESSION */: genExpression(node, context); break; case 5 /* INTERPOLATION */: genInterpolation(node, context); break; case 12 /* TEXT_CALL */: genNode(node.codegenNode, context); break; case 8 /* COMPOUND_EXPRESSION */: genCompoundExpression(node, context); break; case 3 /* COMMENT */: genComment(node, context); break; case 13 /* VNODE_CALL */: genVNodeCall(node, context); break; case 14 /* JS_CALL_EXPRESSION */: genCallExpression(node, context); break; case 15 /* JS_OBJECT_EXPRESSION */: genObjectExpression(node, context); break; case 17 /* JS_ARRAY_EXPRESSION */: genArrayExpression(node, context); break; case 18 /* JS_FUNCTION_EXPRESSION */: genFunctionExpression(node, context); break; case 19 /* JS_CONDITIONAL_EXPRESSION */: genConditionalExpression(node, context); break; case 20 /* JS_CACHE_EXPRESSION */: genCacheExpression(node, context); break; case 21 /* JS_BLOCK_STATEMENT */: genNodeList(node.body, context, true, false); break; // SSR only types case 22 /* JS_TEMPLATE_LITERAL */: break; case 23 /* JS_IF_STATEMENT */: break; case 24 /* JS_ASSIGNMENT_EXPRESSION */: break; case 25 /* JS_SEQUENCE_EXPRESSION */: break; case 26 /* JS_RETURN_STATEMENT */: break; /* istanbul ignore next */ case 10 /* IF_BRANCH */: // noop break; default: if ((false)) {} } } function genText(node, context) { context.push(JSON.stringify(node.content), node); } function genExpression(node, context) { const { content, isStatic } = node; context.push(isStatic ? JSON.stringify(content) : content, node); } function genInterpolation(node, context) { const { push, helper, pure } = context; if (pure) push(PURE_ANNOTATION); push(`${helper(TO_DISPLAY_STRING)}(`); genNode(node.content, context); push(`)`); } function genCompoundExpression(node, context) { for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; if ((0,shared_esm_bundler.isString)(child)) { context.push(child); } else { genNode(child, context); } } } function genExpressionAsPropertyKey(node, context) { const { push } = context; if (node.type === 8 /* COMPOUND_EXPRESSION */) { push(`[`); genCompoundExpression(node, context); push(`]`); } else if (node.isStatic) { // only quote keys if necessary const text = isSimpleIdentifier(node.content) ? node.content : JSON.stringify(node.content); push(text, node); } else { push(`[${node.content}]`, node); } } function genComment(node, context) { const { push, helper, pure } = context; if (pure) { push(PURE_ANNOTATION); } push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node); } function genVNodeCall(node, context) { const { push, helper, pure } = context; const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node; if (directives) { push(helper(WITH_DIRECTIVES) + `(`); } if (isBlock) { push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `); } if (pure) { push(PURE_ANNOTATION); } const callHelper = isBlock ? getVNodeBlockHelper(context.inSSR, isComponent) : getVNodeHelper(context.inSSR, isComponent); push(helper(callHelper) + `(`, node); genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context); push(`)`); if (isBlock) { push(`)`); } if (directives) { push(`, `); genNode(directives, context); push(`)`); } } function genNullableArgs(args) { let i = args.length; while (i--) { if (args[i] != null) break; } return args.slice(0, i + 1).map(arg => arg || `null`); } // JavaScript function genCallExpression(node, context) { const { push, helper, pure } = context; const callee = (0,shared_esm_bundler.isString)(node.callee) ? node.callee : helper(node.callee); if (pure) { push(PURE_ANNOTATION); } push(callee + `(`, node); genNodeList(node.arguments, context); push(`)`); } function genObjectExpression(node, context) { const { push, indent, deindent, newline } = context; const { properties } = node; if (!properties.length) { push(`{}`, node); return; } const multilines = properties.length > 1 || ((( false)) && 0); push(multilines ? `{` : `{ `); multilines && indent(); for (let i = 0; i < properties.length; i++) { const { key, value } = properties[i]; // key genExpressionAsPropertyKey(key, context); push(`: `); // value genNode(value, context); if (i < properties.length - 1) { // will only reach this if it's multilines push(`,`); newline(); } } multilines && deindent(); push(multilines ? `}` : ` }`); } function genArrayExpression(node, context) { genNodeListAsArray(node.elements, context); } function genFunctionExpression(node, context) { const { push, indent, deindent } = context; const { params, returns, body, newline, isSlot } = node; if (isSlot) { // wrap slot functions with owner context push(`_${helperNameMap[WITH_CTX]}(`); } push(`(`, node); if ((0,shared_esm_bundler.isArray)(params)) { genNodeList(params, context); } else if (params) { genNode(params, context); } push(`) => `); if (newline || body) { push(`{`); indent(); } if (returns) { if (newline) { push(`return `); } if ((0,shared_esm_bundler.isArray)(returns)) { genNodeListAsArray(returns, context); } else { genNode(returns, context); } } else if (body) { genNode(body, context); } if (newline || body) { deindent(); push(`}`); } if (isSlot) { if (node.isNonScopedSlot) { push(`, undefined, true`); } push(`)`); } } function genConditionalExpression(node, context) { const { test, consequent, alternate, newline: needNewline } = node; const { push, indent, deindent, newline } = context; if (test.type === 4 /* SIMPLE_EXPRESSION */) { const needsParens = !isSimpleIdentifier(test.content); needsParens && push(`(`); genExpression(test, context); needsParens && push(`)`); } else { push(`(`); genNode(test, context); push(`)`); } needNewline && indent(); context.indentLevel++; needNewline || push(` `); push(`? `); genNode(consequent, context); context.indentLevel--; needNewline && newline(); needNewline || push(` `); push(`: `); const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */; if (!isNested) { context.indentLevel++; } genNode(alternate, context); if (!isNested) { context.indentLevel--; } needNewline && deindent(true /* without newline */); } function genCacheExpression(node, context) { const { push, helper, indent, deindent, newline } = context; push(`_cache[${node.index}] || (`); if (node.isVNode) { indent(); push(`${helper(SET_BLOCK_TRACKING)}(-1),`); newline(); } push(`_cache[${node.index}] = `); genNode(node.value, context); if (node.isVNode) { push(`,`); newline(); push(`${helper(SET_BLOCK_TRACKING)}(1),`); newline(); push(`_cache[${node.index}]`); deindent(); } push(`)`); } function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) { { return; } } function isReferencedIdentifier(id, parent, parentStack) { { return false; } } function isInDestructureAssignment(parent, parentStack) { if (parent && (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) { let i = parentStack.length; while (i--) { const p = parentStack[i]; if (p.type === 'AssignmentExpression') { return true; } else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) { break; } } } return false; } function walkFunctionParams(node, onIdent) { for (const p of node.params) { for (const id of extractIdentifiers(p)) { onIdent(id); } } } function walkBlockDeclarations(block, onIdent) { for (const stmt of block.body) { if (stmt.type === 'VariableDeclaration') { if (stmt.declare) continue; for (const decl of stmt.declarations) { for (const id of extractIdentifiers(decl.id)) { onIdent(id); } } } else if (stmt.type === 'FunctionDeclaration' || stmt.type === 'ClassDeclaration') { if (stmt.declare || !stmt.id) continue; onIdent(stmt.id); } } } function extractIdentifiers(param, nodes = []) { switch (param.type) { case 'Identifier': nodes.push(param); break; case 'MemberExpression': let object = param; while (object.type === 'MemberExpression') { object = object.object; } nodes.push(object); break; case 'ObjectPattern': for (const prop of param.properties) { if (prop.type === 'RestElement') { extractIdentifiers(prop.argument, nodes); } else { extractIdentifiers(prop.value, nodes); } } break; case 'ArrayPattern': param.elements.forEach(element => { if (element) extractIdentifiers(element, nodes); }); break; case 'RestElement': extractIdentifiers(param.argument, nodes); break; case 'AssignmentPattern': extractIdentifiers(param.left, nodes); break; } return nodes; } const isFunctionType = (node) => { return /Function(?:Expression|Declaration)$|Method$/.test(node.type); }; const isStaticProperty = (node) => node && (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') && !node.computed; const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node; // these keywords should not appear inside expressions, but operators like // typeof, instanceof and in are allowed const prohibitedKeywordRE = new RegExp('\\b' + ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + 'super,throw,while,yield,delete,export,import,return,switch,default,' + 'extends,finally,continue,debugger,function,arguments,typeof,void') .split(',') .join('\\b|\\b') + '\\b'); // strip strings in expressions const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g; /** * Validate a non-prefixed expression. * This is only called when using the in-browser runtime compiler since it * doesn't prefix expressions. */ function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) { const exp = node.content; // empty expressions are validated per-directive since some directives // do allow empty expressions. if (!exp.trim()) { return; } try { new Function(asRawStatements ? ` ${exp} ` : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`); } catch (e) { let message = e.message; const keywordMatch = exp .replace(stripStringRE, '') .match(prohibitedKeywordRE); if (keywordMatch) { message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`; } context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message)); } } const transformExpression = (node, context) => { if (node.type === 5 /* INTERPOLATION */) { node.content = processExpression(node.content, context); } else if (node.type === 1 /* ELEMENT */) { // handle directives on element for (let i = 0; i < node.props.length; i++) { const dir = node.props[i]; // do not process for v-on & v-for since they are special handled if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') { const exp = dir.exp; const arg = dir.arg; // do not process exp if this is v-on:arg - we need special handling // for wrapping inline statements. if (exp && exp.type === 4 /* SIMPLE_EXPRESSION */ && !(dir.name === 'on' && arg)) { dir.exp = processExpression(exp, context, // slot args must be processed as function params dir.name === 'slot'); } if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) { dir.arg = processExpression(arg, context); } } } } }; // Important: since this function uses Node.js only dependencies, it should // always be used with a leading !true check so that it can be // tree-shaken from the browser build. function processExpression(node, context, // some expressions like v-slot props & v-for aliases should be parsed as // function params asParams = false, // v-on handler values may contain multiple statements asRawStatements = false, localVars = Object.create(context.identifiers)) { { if ((false)) {} return node; } } const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => { return processIf(node, dir, context, (ifNode, branch, isRoot) => { // #1587: We need to dynamically increment the key based on the current // node's sibling nodes, since chained v-if/else branches are // rendered at the same depth const siblings = context.parent.children; let i = siblings.indexOf(ifNode); let key = 0; while (i-- >= 0) { const sibling = siblings[i]; if (sibling && sibling.type === 9 /* IF */) { key += sibling.branches.length; } } // Exit callback. Complete the codegenNode when all children have been // transformed. return () => { if (isRoot) { ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context); } else { // attach this branch's codegen node to the v-if root. const parentCondition = getParentCondition(ifNode.codegenNode); parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context); } }; }); }); // target-agnostic transform used for both Client and SSR function processIf(node, dir, context, processCodegen) { if (dir.name !== 'else' && (!dir.exp || !dir.exp.content.trim())) { const loc = dir.exp ? dir.exp.loc : node.loc; context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc)); dir.exp = createSimpleExpression(`true`, false, loc); } if (false) {} if (dir.name === 'if') { const branch = createIfBranch(node, dir); const ifNode = { type: 9 /* IF */, loc: node.loc, branches: [branch] }; context.replaceNode(ifNode); if (processCodegen) { return processCodegen(ifNode, branch, true); } } else { // locate the adjacent v-if const siblings = context.parent.children; const comments = []; let i = siblings.indexOf(node); while (i-- >= -1) { const sibling = siblings[i]; if (false /* COMMENT */) {} if (sibling && sibling.type === 2 /* TEXT */ && !sibling.content.trim().length) { context.removeNode(sibling); continue; } if (sibling && sibling.type === 9 /* IF */) { // Check if v-else was followed by v-else-if if (dir.name === 'else-if' && sibling.branches[sibling.branches.length - 1].condition === undefined) { context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc)); } // move the node to the if node's branches context.removeNode(); const branch = createIfBranch(node, dir); if (false) {} // check if user is forcing same key on different branches if (false) {} sibling.branches.push(branch); const onExit = processCodegen && processCodegen(sibling, branch, false); // since the branch was removed, it will not be traversed. // make sure to traverse here. traverseNode(branch, context); // call on exit if (onExit) onExit(); // make sure to reset currentNode after traversal to indicate this // node has been removed. context.currentNode = null; } else { context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc)); } break; } } } function createIfBranch(node, dir) { return { type: 10 /* IF_BRANCH */, loc: node.loc, condition: dir.name === 'else' ? undefined : dir.exp, children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for') ? node.children : [node], userKey: findProp(node, `key`) }; } function createCodegenNodeForBranch(branch, keyIndex, context) { if (branch.condition) { return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), // make sure to pass in asBlock: true so that the comment node call // closes the current block. createCallExpression(context.helper(CREATE_COMMENT), [ ( false) ? 0 : '""', 'true' ])); } else { return createChildrenCodegenNode(branch, keyIndex, context); } } function createChildrenCodegenNode(branch, keyIndex, context) { const { helper } = context; const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */)); const { children } = branch; const firstChild = children[0]; const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */; if (needFragmentWrapper) { if (children.length === 1 && firstChild.type === 11 /* FOR */) { // optimize away nested fragments when child is a ForNode const vnodeCall = firstChild.codegenNode; injectProp(vnodeCall, keyProperty, context); return vnodeCall; } else { let patchFlag = 64 /* STABLE_FRAGMENT */; let patchFlagText = shared_esm_bundler.PatchFlagNames[64]; // check if the fragment actually contains a single valid child with // the rest being comments if (false) {} return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (( false) ? 0 : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc); } } else { const ret = firstChild.codegenNode; const vnodeCall = getMemoedVNodeCall(ret); // Change createVNode to createBlock. if (vnodeCall.type === 13 /* VNODE_CALL */) { makeBlock(vnodeCall, context); } // inject branch key injectProp(vnodeCall, keyProperty, context); return ret; } } function isSameKey(a, b) { if (!a || a.type !== b.type) { return false; } if (a.type === 6 /* ATTRIBUTE */) { if (a.value.content !== b.value.content) { return false; } } else { // directive const exp = a.exp; const branchExp = b.exp; if (exp.type !== branchExp.type) { return false; } if (exp.type !== 4 /* SIMPLE_EXPRESSION */ || exp.isStatic !== branchExp.isStatic || exp.content !== branchExp.content) { return false; } } return true; } function getParentCondition(node) { while (true) { if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) { if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) { node = node.alternate; } else { return node; } } else if (node.type === 20 /* JS_CACHE_EXPRESSION */) { node = node.value; } } } const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => { const { helper, removeHelper } = context; return processFor(node, dir, context, forNode => { // create the loop render function expression now, and add the // iterator on exit after all children have been traversed const renderExp = createCallExpression(helper(RENDER_LIST), [ forNode.source ]); const memo = findDir(node, 'memo'); const keyProp = findProp(node, `key`); const keyExp = keyProp && (keyProp.type === 6 /* ATTRIBUTE */ ? createSimpleExpression(keyProp.value.content, true) : keyProp.exp); const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null; const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ && forNode.source.constType > 0 /* NOT_CONSTANT */; const fragmentFlag = isStableFragment ? 64 /* STABLE_FRAGMENT */ : keyProp ? 128 /* KEYED_FRAGMENT */ : 256 /* UNKEYED_FRAGMENT */; forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag + (( false) ? 0 : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc); return () => { // finish the codegen now that all children have been traversed let childBlock; const isTemplate = isTemplateNode(node); const { children } = forNode; // check <template v-for> key placement if (false) {} const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */; const slotOutlet = isSlotOutlet(node) ? node : isTemplate && node.children.length === 1 && isSlotOutlet(node.children[0]) ? node.children[0] // api-extractor somehow fails to infer this : null; if (slotOutlet) { // <slot v-for="..."> or <template v-for="..."><slot/></template> childBlock = slotOutlet.codegenNode; if (isTemplate && keyProperty) { // <template v-for="..." :key="..."><slot/></template> // we need to inject the key to the renderSlot() call. // the props for renderSlot is passed as the 3rd argument. injectProp(childBlock, keyProperty, context); } } else if (needFragmentWrapper) { // <template v-for="..."> with text or multi-elements // should generate a fragment block for each loop childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ + (( false) ? 0 : ``), undefined, undefined, true, undefined, false /* isComponent */); } else { // Normal element v-for. Directly use the child's codegenNode // but mark it as a block. childBlock = children[0] .codegenNode; if (isTemplate && keyProperty) { injectProp(childBlock, keyProperty, context); } if (childBlock.isBlock !== !isStableFragment) { if (childBlock.isBlock) { // switch from block to vnode removeHelper(OPEN_BLOCK); removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent)); } else { // switch from vnode to block removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent)); } } childBlock.isBlock = !isStableFragment; if (childBlock.isBlock) { helper(OPEN_BLOCK); helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent)); } else { helper(getVNodeHelper(context.inSSR, childBlock.isComponent)); } } if (memo) { const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [ createSimpleExpression(`_cached`) ])); loop.body = createBlockStatement([ createCompoundExpression([`const _memo = (`, memo.exp, `)`]), createCompoundExpression([ `if (_cached`, ...(keyExp ? [` && _cached.key === `, keyExp] : []), ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached` ]), createCompoundExpression([`const _item = `, childBlock]), createSimpleExpression(`_item.memo = _memo`), createSimpleExpression(`return _item`) ]); renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++))); } else { renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */)); } }; }); }); // target-agnostic transform used for both Client and SSR function processFor(node, dir, context, processCodegen) { if (!dir.exp) { context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc)); return; } const parseResult = parseForExpression( // can only be simple expression because vFor transform is applied // before expression transform. dir.exp, context); if (!parseResult) { context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc)); return; } const { addIdentifiers, removeIdentifiers, scopes } = context; const { source, value, key, index } = parseResult; const forNode = { type: 11 /* FOR */, loc: dir.loc, source, valueAlias: value, keyAlias: key, objectIndexAlias: index, parseResult, children: isTemplateNode(node) ? node.children : [node] }; context.replaceNode(forNode); // bookkeeping scopes.vFor++; const onExit = processCodegen && processCodegen(forNode); return () => { scopes.vFor--; if (onExit) onExit(); }; } const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/; // This regex doesn't cover the case if key or index aliases have destructuring, // but those do not make sense in the first place, so this works in practice. const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/; const stripParensRE = /^\(|\)$/g; function parseForExpression(input, context) { const loc = input.loc; const exp = input.content; const inMatch = exp.match(forAliasRE); if (!inMatch) return; const [, LHS, RHS] = inMatch; const result = { source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)), value: undefined, key: undefined, index: undefined }; if (false) {} let valueContent = LHS.trim().replace(stripParensRE, '').trim(); const trimmedOffset = LHS.indexOf(valueContent); const iteratorMatch = valueContent.match(forIteratorRE); if (iteratorMatch) { valueContent = valueContent.replace(forIteratorRE, '').trim(); const keyContent = iteratorMatch[1].trim(); let keyOffset; if (keyContent) { keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length); result.key = createAliasExpression(loc, keyContent, keyOffset); if (false) {} } if (iteratorMatch[2]) { const indexContent = iteratorMatch[2].trim(); if (indexContent) { result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key ? keyOffset + keyContent.length : trimmedOffset + valueContent.length)); if (false) {} } } } if (valueContent) { result.value = createAliasExpression(loc, valueContent, trimmedOffset); if (false) {} } return result; } function createAliasExpression(range, content, offset) { return createSimpleExpression(content, false, getInnerRange(range, offset, content.length)); } function createForLoopParams({ value, key, index }, memoArgs = []) { return createParamsList([value, key, index, ...memoArgs]); } function createParamsList(args) { let i = args.length; while (i--) { if (args[i]) break; } return args .slice(0, i + 1) .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false)); } const defaultFallback = createSimpleExpression(`undefined`, false); // A NodeTransform that: // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed // by transformExpression. This is only applied in non-browser builds with // { prefixIdentifiers: true }. // 2. Track v-slot depths so that we know a slot is inside another slot. // Note the exit callback is executed before buildSlots() on the same node, // so only nested slots see positive numbers. const trackSlotScopes = (node, context) => { if (node.type === 1 /* ELEMENT */ && (node.tagType === 1 /* COMPONENT */ || node.tagType === 3 /* TEMPLATE */)) { // We are only checking non-empty v-slot here // since we only care about slots that introduce scope variables. const vSlot = findDir(node, 'slot'); if (vSlot) { vSlot.exp; context.scopes.vSlot++; return () => { context.scopes.vSlot--; }; } } }; // A NodeTransform that tracks scope identifiers for scoped slots with v-for. // This transform is only applied in non-browser builds with { prefixIdentifiers: true } const trackVForSlotScopes = (node, context) => { let vFor; if (isTemplateNode(node) && node.props.some(isVSlot) && (vFor = findDir(node, 'for'))) { const result = (vFor.parseResult = parseForExpression(vFor.exp, context)); if (result) { const { value, key, index } = result; const { addIdentifiers, removeIdentifiers } = context; value && addIdentifiers(value); key && addIdentifiers(key); index && addIdentifiers(index); return () => { value && removeIdentifiers(value); key && removeIdentifiers(key); index && removeIdentifiers(index); }; } } }; const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc); // Instead of being a DirectiveTransform, v-slot processing is called during // transformElement to build the slots object for a component. function buildSlots(node, context, buildSlotFn = buildClientSlotFn) { context.helper(WITH_CTX); const { children, loc } = node; const slotsProperties = []; const dynamicSlots = []; // If the slot is inside a v-for or another v-slot, force it to be dynamic // since it likely uses a scope variable. let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0; // 1. Check for slot with slotProps on component itself. // <Comp v-slot="{ prop }"/> const onComponentSlot = findDir(node, 'slot', true); if (onComponentSlot) { const { arg, exp } = onComponentSlot; if (arg && !isStaticExp(arg)) { hasDynamicSlots = true; } slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc))); } // 2. Iterate through children and check for template slots // <template v-slot:foo="{ prop }"> let hasTemplateSlots = false; let hasNamedDefaultSlot = false; const implicitDefaultChildren = []; const seenSlotNames = new Set(); for (let i = 0; i < children.length; i++) { const slotElement = children[i]; let slotDir; if (!isTemplateNode(slotElement) || !(slotDir = findDir(slotElement, 'slot', true))) { // not a <template v-slot>, skip. if (slotElement.type !== 3 /* COMMENT */) { implicitDefaultChildren.push(slotElement); } continue; } if (onComponentSlot) { // already has on-component slot - this is incorrect usage. context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc)); break; } hasTemplateSlots = true; const { children: slotChildren, loc: slotLoc } = slotElement; const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir; // check if name is dynamic. let staticSlotName; if (isStaticExp(slotName)) { staticSlotName = slotName ? slotName.content : `default`; } else { hasDynamicSlots = true; } const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc); // check if this slot is conditional (v-if/v-for) let vIf; let vElse; let vFor; if ((vIf = findDir(slotElement, 'if'))) { hasDynamicSlots = true; dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)); } else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) { // find adjacent v-if let j = i; let prev; while (j--) { prev = children[j]; if (prev.type !== 3 /* COMMENT */) { break; } } if (prev && isTemplateNode(prev) && findDir(prev, 'if')) { // remove node children.splice(i, 1); i--; // attach this slot to previous conditional let conditional = dynamicSlots[dynamicSlots.length - 1]; while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) { conditional = conditional.alternate; } conditional.alternate = vElse.exp ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback) : buildDynamicSlot(slotName, slotFunction); } else { context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc)); } } else if ((vFor = findDir(slotElement, 'for'))) { hasDynamicSlots = true; const parseResult = vFor.parseResult || parseForExpression(vFor.exp, context); if (parseResult) { // Render the dynamic slots as an array and add it to the createSlot() // args. The runtime knows how to handle it appropriately. dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [ parseResult.source, createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */) ])); } else { context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc)); } } else { // check duplicate static names if (staticSlotName) { if (seenSlotNames.has(staticSlotName)) { context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc)); continue; } seenSlotNames.add(staticSlotName); if (staticSlotName === 'default') { hasNamedDefaultSlot = true; } } slotsProperties.push(createObjectProperty(slotName, slotFunction)); } } if (!onComponentSlot) { const buildDefaultSlotProperty = (props, children) => { const fn = buildSlotFn(props, children, loc); if (context.compatConfig) { fn.isNonScopedSlot = true; } return createObjectProperty(`default`, fn); }; if (!hasTemplateSlots) { // implicit default slot (on component) slotsProperties.push(buildDefaultSlotProperty(undefined, children)); } else if (implicitDefaultChildren.length && // #3766 // with whitespace: 'preserve', whitespaces between slots will end up in // implicitDefaultChildren. Ignore if all implicit children are whitespaces. implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) { // implicit default slot (mixed with named slots) if (hasNamedDefaultSlot) { context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc)); } else { slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren)); } } } const slotFlag = hasDynamicSlots ? 2 /* DYNAMIC */ : hasForwardedSlots(node.children) ? 3 /* FORWARDED */ : 1 /* STABLE */; let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, // 2 = compiled but dynamic = can skip normalization, but must run diff // 1 = compiled and static = can skip normalization AND diff as optimized createSimpleExpression(slotFlag + (( false) ? 0 : ``), false))), loc); if (dynamicSlots.length) { slots = createCallExpression(context.helper(CREATE_SLOTS), [ slots, createArrayExpression(dynamicSlots) ]); } return { slots, hasDynamicSlots }; } function buildDynamicSlot(name, fn) { return createObjectExpression([ createObjectProperty(`name`, name), createObjectProperty(`fn`, fn) ]); } function hasForwardedSlots(children) { for (let i = 0; i < children.length; i++) { const child = children[i]; switch (child.type) { case 1 /* ELEMENT */: if (child.tagType === 2 /* SLOT */ || hasForwardedSlots(child.children)) { return true; } break; case 9 /* IF */: if (hasForwardedSlots(child.branches)) return true; break; case 10 /* IF_BRANCH */: case 11 /* FOR */: if (hasForwardedSlots(child.children)) return true; break; } } return false; } function isNonWhitespaceContent(node) { if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */) return true; return node.type === 2 /* TEXT */ ? !!node.content.trim() : isNonWhitespaceContent(node.content); } // some directive transforms (e.g. v-model) may return a symbol for runtime // import, which should be used instead of a resolveDirective call. const directiveImportMap = new WeakMap(); // generate a JavaScript AST for this element's codegen const transformElement = (node, context) => { // perform the work on exit, after all child expressions have been // processed and merged. return function postTransformElement() { node = context.currentNode; if (!(node.type === 1 /* ELEMENT */ && (node.tagType === 0 /* ELEMENT */ || node.tagType === 1 /* COMPONENT */))) { return; } const { tag, props } = node; const isComponent = node.tagType === 1 /* COMPONENT */; // The goal of the transform is to create a codegenNode implementing the // VNodeCall interface. let vnodeTag = isComponent ? resolveComponentType(node, context) : `"${tag}"`; const isDynamicComponent = (0,shared_esm_bundler.isObject)(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT; let vnodeProps; let vnodeChildren; let vnodePatchFlag; let patchFlag = 0; let vnodeDynamicProps; let dynamicPropNames; let vnodeDirectives; let shouldUseBlock = // dynamic component may resolve to plain elements isDynamicComponent || vnodeTag === TELEPORT || vnodeTag === SUSPENSE || (!isComponent && // <svg> and <foreignObject> must be forced into blocks so that block // updates inside get proper isSVG flag at runtime. (#639, #643) // This is technically web-specific, but splitting the logic out of core // leads to too much unnecessary complexity. (tag === 'svg' || tag === 'foreignObject' || // #938: elements with dynamic keys should be forced into blocks findProp(node, 'key', true))); // props if (props.length > 0) { const propsBuildResult = buildProps(node, context); vnodeProps = propsBuildResult.props; patchFlag = propsBuildResult.patchFlag; dynamicPropNames = propsBuildResult.dynamicPropNames; const directives = propsBuildResult.directives; vnodeDirectives = directives && directives.length ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context))) : undefined; } // children if (node.children.length > 0) { if (vnodeTag === KEEP_ALIVE) { // Although a built-in component, we compile KeepAlive with raw children // instead of slot functions so that it can be used inside Transition // or other Transition-wrapping HOCs. // To ensure correct updates with block optimizations, we need to: // 1. Force keep-alive into a block. This avoids its children being // collected by a parent block. shouldUseBlock = true; // 2. Force keep-alive to always be updated, since it uses raw children. patchFlag |= 1024 /* DYNAMIC_SLOTS */; if (false) {} } const shouldBuildAsSlots = isComponent && // Teleport is not a real component and has dedicated runtime handling vnodeTag !== TELEPORT && // explained above. vnodeTag !== KEEP_ALIVE; if (shouldBuildAsSlots) { const { slots, hasDynamicSlots } = buildSlots(node, context); vnodeChildren = slots; if (hasDynamicSlots) { patchFlag |= 1024 /* DYNAMIC_SLOTS */; } } else if (node.children.length === 1 && vnodeTag !== TELEPORT) { const child = node.children[0]; const type = child.type; // check for dynamic text children const hasDynamicTextChild = type === 5 /* INTERPOLATION */ || type === 8 /* COMPOUND_EXPRESSION */; if (hasDynamicTextChild && getConstantType(child, context) === 0 /* NOT_CONSTANT */) { patchFlag |= 1 /* TEXT */; } // pass directly if the only child is a text node // (plain / interpolation / expression) if (hasDynamicTextChild || type === 2 /* TEXT */) { vnodeChildren = child; } else { vnodeChildren = node.children; } } else { vnodeChildren = node.children; } } // patchFlag & dynamicPropNames if (patchFlag !== 0) { if ((false)) {} else { vnodePatchFlag = String(patchFlag); } if (dynamicPropNames && dynamicPropNames.length) { vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames); } } node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc); }; }; function resolveComponentType(node, context, ssr = false) { let { tag } = node; // 1. dynamic component const isExplicitDynamic = isComponentTag(tag); const isProp = findProp(node, 'is'); if (isProp) { if (isExplicitDynamic || (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) { const exp = isProp.type === 6 /* ATTRIBUTE */ ? isProp.value && createSimpleExpression(isProp.value.content, true) : isProp.exp; if (exp) { return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [ exp ]); } } else if (isProp.type === 6 /* ATTRIBUTE */ && isProp.value.content.startsWith('vue:')) { // <button is="vue:xxx"> // if not <component>, only is value that starts with "vue:" will be // treated as component by the parse phase and reach here, unless it's // compat mode where all is values are considered components tag = isProp.value.content.slice(4); } } // 1.5 v-is (TODO: Deprecate) const isDir = !isExplicitDynamic && findDir(node, 'is'); if (isDir && isDir.exp) { return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [ isDir.exp ]); } // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...) const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag); if (builtIn) { // built-ins are simply fallthroughs / have special handling during ssr // so we don't need to import their runtime equivalents if (!ssr) context.helper(builtIn); return builtIn; } // 5. user component (resolve) context.helper(RESOLVE_COMPONENT); context.components.add(tag); return toValidAssetId(tag, `component`); } function buildProps(node, context, props = node.props, ssr = false) { const { tag, loc: elementLoc } = node; const isComponent = node.tagType === 1 /* COMPONENT */; let properties = []; const mergeArgs = []; const runtimeDirectives = []; // patchFlag analysis let patchFlag = 0; let hasRef = false; let hasClassBinding = false; let hasStyleBinding = false; let hasHydrationEventBinding = false; let hasDynamicKeys = false; let hasVnodeHook = false; const dynamicPropNames = []; const analyzePatchFlag = ({ key, value }) => { if (isStaticExp(key)) { const name = key.content; const isEventHandler = (0,shared_esm_bundler.isOn)(name); if (!isComponent && isEventHandler && // omit the flag for click handlers because hydration gives click // dedicated fast path. name.toLowerCase() !== 'onclick' && // omit v-model handlers name !== 'onUpdate:modelValue' && // omit onVnodeXXX hooks !(0,shared_esm_bundler.isReservedProp)(name)) { hasHydrationEventBinding = true; } if (isEventHandler && (0,shared_esm_bundler.isReservedProp)(name)) { hasVnodeHook = true; } if (value.type === 20 /* JS_CACHE_EXPRESSION */ || ((value.type === 4 /* SIMPLE_EXPRESSION */ || value.type === 8 /* COMPOUND_EXPRESSION */) && getConstantType(value, context) > 0)) { // skip if the prop is a cached handler or has constant value return; } if (name === 'ref') { hasRef = true; } else if (name === 'class') { hasClassBinding = true; } else if (name === 'style') { hasStyleBinding = true; } else if (name !== 'key' && !dynamicPropNames.includes(name)) { dynamicPropNames.push(name); } // treat the dynamic class and style binding of the component as dynamic props if (isComponent && (name === 'class' || name === 'style') && !dynamicPropNames.includes(name)) { dynamicPropNames.push(name); } } else { hasDynamicKeys = true; } }; for (let i = 0; i < props.length; i++) { // static attribute const prop = props[i]; if (prop.type === 6 /* ATTRIBUTE */) { const { loc, name, value } = prop; let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc); if (name === 'ref') { hasRef = true; } // skip is on <component>, or is="vue:xxx" if (name === 'is' && (isComponentTag(tag) || (value && value.content.startsWith('vue:')) || (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) { continue; } properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode)); } else { // directives const { name, arg, exp, loc } = prop; const isVBind = name === 'bind'; const isVOn = name === 'on'; // skip v-slot - it is handled by its dedicated transform. if (name === 'slot') { if (!isComponent) { context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc)); } continue; } // skip v-once/v-memo - they are handled by dedicated transforms. if (name === 'once' || name === 'memo') { continue; } // skip v-is and :is on <component> if (name === 'is' || (isVBind && isBindKey(arg, 'is') && (isComponentTag(tag) || (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) { continue; } // skip v-on in SSR compilation if (isVOn && ssr) { continue; } // special case for v-bind and v-on with no argument if (!arg && (isVBind || isVOn)) { hasDynamicKeys = true; if (exp) { if (properties.length) { mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc)); properties = []; } if (isVBind) { { // 2.x v-bind object order compat if ((false)) {} if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) { mergeArgs.unshift(exp); continue; } } mergeArgs.push(exp); } else { // v-on="obj" -> toHandlers(obj) mergeArgs.push({ type: 14 /* JS_CALL_EXPRESSION */, loc, callee: context.helper(TO_HANDLERS), arguments: [exp] }); } } else { context.onError(createCompilerError(isVBind ? 34 /* X_V_BIND_NO_EXPRESSION */ : 35 /* X_V_ON_NO_EXPRESSION */, loc)); } continue; } const directiveTransform = context.directiveTransforms[name]; if (directiveTransform) { // has built-in directive transform. const { props, needRuntime } = directiveTransform(prop, node, context); !ssr && props.forEach(analyzePatchFlag); properties.push(...props); if (needRuntime) { runtimeDirectives.push(prop); if ((0,shared_esm_bundler.isSymbol)(needRuntime)) { directiveImportMap.set(prop, needRuntime); } } } else { // no built-in transform, this is a user custom directive. runtimeDirectives.push(prop); } } if (prop.type === 6 /* ATTRIBUTE */ && prop.name === 'ref' && context.scopes.vFor > 0 && checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) { properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false))); } } let propsExpression = undefined; // has v-bind="object" or v-on="object", wrap with mergeProps if (mergeArgs.length) { if (properties.length) { mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc)); } if (mergeArgs.length > 1) { propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc); } else { // single v-bind with nothing else - no need for a mergeProps call propsExpression = mergeArgs[0]; } } else if (properties.length) { propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc); } // patchFlag analysis if (hasDynamicKeys) { patchFlag |= 16 /* FULL_PROPS */; } else { if (hasClassBinding && !isComponent) { patchFlag |= 2 /* CLASS */; } if (hasStyleBinding && !isComponent) { patchFlag |= 4 /* STYLE */; } if (dynamicPropNames.length) { patchFlag |= 8 /* PROPS */; } if (hasHydrationEventBinding) { patchFlag |= 32 /* HYDRATE_EVENTS */; } } if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) && (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) { patchFlag |= 512 /* NEED_PATCH */; } // pre-normalize props, SSR is skipped for now if (!context.inSSR && propsExpression) { switch (propsExpression.type) { case 15 /* JS_OBJECT_EXPRESSION */: // means that there is no v-bind, // but still need to deal with dynamic key binding let classKeyIndex = -1; let styleKeyIndex = -1; let hasDynamicKey = false; for (let i = 0; i < propsExpression.properties.length; i++) { const key = propsExpression.properties[i].key; if (isStaticExp(key)) { if (key.content === 'class') { classKeyIndex = i; } else if (key.content === 'style') { styleKeyIndex = i; } } else if (!key.isHandlerKey) { hasDynamicKey = true; } } const classProp = propsExpression.properties[classKeyIndex]; const styleProp = propsExpression.properties[styleKeyIndex]; // no dynamic key if (!hasDynamicKey) { if (classProp && !isStaticExp(classProp.value)) { classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]); } if (styleProp && !isStaticExp(styleProp.value) && // the static style is compiled into an object, // so use `hasStyleBinding` to ensure that it is a dynamic style binding (hasStyleBinding || // v-bind:style and style both exist, // v-bind:style with static literal object styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) { styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]); } } else { // dynamic key binding, wrap with `normalizeProps` propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]); } break; case 14 /* JS_CALL_EXPRESSION */: // mergeProps call, do nothing break; default: // single v-bind propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [ createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [ propsExpression ]) ]); break; } } return { props: propsExpression, directives: runtimeDirectives, patchFlag, dynamicPropNames }; } // Dedupe props in an object literal. // Literal duplicated attributes would have been warned during the parse phase, // however, it's possible to encounter duplicated `onXXX` handlers with different // modifiers. We also need to merge static and dynamic class / style attributes. // - onXXX handlers / style: merge into array // - class: merge into single expression with concatenation function dedupeProperties(properties) { const knownProps = new Map(); const deduped = []; for (let i = 0; i < properties.length; i++) { const prop = properties[i]; // dynamic keys are always allowed if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) { deduped.push(prop); continue; } const name = prop.key.content; const existing = knownProps.get(name); if (existing) { if (name === 'style' || name === 'class' || (0,shared_esm_bundler.isOn)(name)) { mergeAsArray(existing, prop); } // unexpected duplicate, should have emitted error during parse } else { knownProps.set(name, prop); deduped.push(prop); } } return deduped; } function mergeAsArray(existing, incoming) { if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) { existing.value.elements.push(incoming.value); } else { existing.value = createArrayExpression([existing.value, incoming.value], existing.loc); } } function buildDirectiveArgs(dir, context) { const dirArgs = []; const runtime = directiveImportMap.get(dir); if (runtime) { // built-in directive with runtime dirArgs.push(context.helperString(runtime)); } else { { // inject statement for resolving directive context.helper(RESOLVE_DIRECTIVE); context.directives.add(dir.name); dirArgs.push(toValidAssetId(dir.name, `directive`)); } } const { loc } = dir; if (dir.exp) dirArgs.push(dir.exp); if (dir.arg) { if (!dir.exp) { dirArgs.push(`void 0`); } dirArgs.push(dir.arg); } if (Object.keys(dir.modifiers).length) { if (!dir.arg) { if (!dir.exp) { dirArgs.push(`void 0`); } dirArgs.push(`void 0`); } const trueExpression = createSimpleExpression(`true`, false, loc); dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc)); } return createArrayExpression(dirArgs, dir.loc); } function stringifyDynamicPropNames(props) { let propsNamesString = `[`; for (let i = 0, l = props.length; i < l; i++) { propsNamesString += JSON.stringify(props[i]); if (i < l - 1) propsNamesString += ', '; } return propsNamesString + `]`; } function isComponentTag(tag) { return tag === 'component' || tag === 'Component'; } ( false) ? 0 : {}; ( false) ? 0 : []; const cacheStringFunction = (fn) => { const cache = Object.create(null); return ((str) => { const hit = cache[str]; return hit || (cache[str] = fn(str)); }); }; const camelizeRE = /-(\w)/g; /** * @private */ const camelize = cacheStringFunction((str) => { return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); }); const transformSlotOutlet = (node, context) => { if (isSlotOutlet(node)) { const { children, loc } = node; const { slotName, slotProps } = processSlotOutlet(node, context); const slotArgs = [ context.prefixIdentifiers ? `_ctx.$slots` : `$slots`, slotName, '{}', 'undefined', 'true' ]; let expectedLen = 2; if (slotProps) { slotArgs[2] = slotProps; expectedLen = 3; } if (children.length) { slotArgs[3] = createFunctionExpression([], children, false, false, loc); expectedLen = 4; } if (context.scopeId && !context.slotted) { expectedLen = 5; } slotArgs.splice(expectedLen); // remove unused arguments node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc); } }; function processSlotOutlet(node, context) { let slotName = `"default"`; let slotProps = undefined; const nonNameProps = []; for (let i = 0; i < node.props.length; i++) { const p = node.props[i]; if (p.type === 6 /* ATTRIBUTE */) { if (p.value) { if (p.name === 'name') { slotName = JSON.stringify(p.value.content); } else { p.name = camelize(p.name); nonNameProps.push(p); } } } else { if (p.name === 'bind' && isBindKey(p.arg, 'name')) { if (p.exp) slotName = p.exp; } else { if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) { p.arg.content = camelize(p.arg.content); } nonNameProps.push(p); } } } if (nonNameProps.length > 0) { const { props, directives } = buildProps(node, context, nonNameProps); slotProps = props; if (directives.length) { context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc)); } } return { slotName, slotProps }; } const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/; const transformOn = (dir, node, context, augmentor) => { const { loc, modifiers, arg } = dir; if (!dir.exp && !modifiers.length) { context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc)); } let eventName; if (arg.type === 4 /* SIMPLE_EXPRESSION */) { if (arg.isStatic) { const rawName = arg.content; // for all event listeners, auto convert it to camelCase. See issue #2249 eventName = createSimpleExpression((0,shared_esm_bundler.toHandlerKey)((0,shared_esm_bundler.camelize)(rawName)), true, arg.loc); } else { // #2388 eventName = createCompoundExpression([ `${context.helperString(TO_HANDLER_KEY)}(`, arg, `)` ]); } } else { // already a compound expression. eventName = arg; eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`); eventName.children.push(`)`); } // handler processing let exp = dir.exp; if (exp && !exp.content.trim()) { exp = undefined; } let shouldCache = context.cacheHandlers && !exp && !context.inVOnce; if (exp) { const isMemberExp = isMemberExpression(exp.content); const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content)); const hasMultipleStatements = exp.content.includes(`;`); if (false) {} if (isInlineStatement || (shouldCache && isMemberExp)) { // wrap inline statement in a function expression exp = createCompoundExpression([ `${isInlineStatement ? `$event` : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`, exp, hasMultipleStatements ? `}` : `)` ]); } } let ret = { props: [ createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc)) ] }; // apply extended compiler augmentor if (augmentor) { ret = augmentor(ret); } if (shouldCache) { // cache handlers so that it's always the same handler being passed down. // this avoids unnecessary re-renders when users use inline handlers on // components. ret.props[0].value = context.cache(ret.props[0].value); } // mark the key as handler for props normalization check ret.props.forEach(p => (p.key.isHandlerKey = true)); return ret; }; // v-bind without arg is handled directly in ./transformElements.ts due to it affecting // codegen for the entire props object. This transform here is only for v-bind // *with* args. const transformBind = (dir, _node, context) => { const { exp, modifiers, loc } = dir; const arg = dir.arg; if (arg.type !== 4 /* SIMPLE_EXPRESSION */) { arg.children.unshift(`(`); arg.children.push(`) || ""`); } else if (!arg.isStatic) { arg.content = `${arg.content} || ""`; } // .sync is replaced by v-model:arg if (modifiers.includes('camel')) { if (arg.type === 4 /* SIMPLE_EXPRESSION */) { if (arg.isStatic) { arg.content = (0,shared_esm_bundler.camelize)(arg.content); } else { arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`; } } else { arg.children.unshift(`${context.helperString(CAMELIZE)}(`); arg.children.push(`)`); } } if (!context.inSSR) { if (modifiers.includes('prop')) { injectPrefix(arg, '.'); } if (modifiers.includes('attr')) { injectPrefix(arg, '^'); } } if (!exp || (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) { context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc)); return { props: [createObjectProperty(arg, createSimpleExpression('', true, loc))] }; } return { props: [createObjectProperty(arg, exp)] }; }; const injectPrefix = (arg, prefix) => { if (arg.type === 4 /* SIMPLE_EXPRESSION */) { if (arg.isStatic) { arg.content = prefix + arg.content; } else { arg.content = `\`${prefix}\${${arg.content}}\``; } } else { arg.children.unshift(`'${prefix}' + (`); arg.children.push(`)`); } }; // Merge adjacent text nodes and expressions into a single expression // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child. const transformText = (node, context) => { if (node.type === 0 /* ROOT */ || node.type === 1 /* ELEMENT */ || node.type === 11 /* FOR */ || node.type === 10 /* IF_BRANCH */) { // perform the transform on node exit so that all expressions have already // been processed. return () => { const children = node.children; let currentContainer = undefined; let hasText = false; for (let i = 0; i < children.length; i++) { const child = children[i]; if (isText(child)) { hasText = true; for (let j = i + 1; j < children.length; j++) { const next = children[j]; if (isText(next)) { if (!currentContainer) { currentContainer = children[i] = { type: 8 /* COMPOUND_EXPRESSION */, loc: child.loc, children: [child] }; } // merge adjacent text node into current currentContainer.children.push(` + `, next); children.splice(j, 1); j--; } else { currentContainer = undefined; break; } } } } if (!hasText || // if this is a plain element with a single text child, leave it // as-is since the runtime has dedicated fast path for this by directly // setting textContent of the element. // for component root it's always normalized anyway. (children.length === 1 && (node.type === 0 /* ROOT */ || (node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */ && // #3756 // custom directives can potentially add DOM elements arbitrarily, // we need to avoid setting textContent of the element at runtime // to avoid accidentally overwriting the DOM elements added // by the user through custom directives. !node.props.find(p => p.type === 7 /* DIRECTIVE */ && !context.directiveTransforms[p.name]) && // in compat mode, <template> tags with no special directives // will be rendered as a fragment so its children must be // converted into vnodes. !(node.tag === 'template'))))) { return; } // pre-convert text nodes into createTextVNode(text) calls to avoid // runtime normalization. for (let i = 0; i < children.length; i++) { const child = children[i]; if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) { const callArgs = []; // createTextVNode defaults to single whitespace, so if it is a // single space the code could be an empty call to save bytes. if (child.type !== 2 /* TEXT */ || child.content !== ' ') { callArgs.push(child); } // mark dynamic text with flag so it gets patched inside a block if (!context.ssr && getConstantType(child, context) === 0 /* NOT_CONSTANT */) { callArgs.push(1 /* TEXT */ + (( false) ? 0 : ``)); } children[i] = { type: 12 /* TEXT_CALL */, content: child, loc: child.loc, codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs) }; } } }; } }; const seen = new WeakSet(); const transformOnce = (node, context) => { if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) { if (seen.has(node) || context.inVOnce) { return; } seen.add(node); context.inVOnce = true; context.helper(SET_BLOCK_TRACKING); return () => { context.inVOnce = false; const cur = context.currentNode; if (cur.codegenNode) { cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */); } }; } }; const transformModel = (dir, node, context) => { const { exp, arg } = dir; if (!exp) { context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc)); return createTransformProps(); } const rawExp = exp.loc.source; const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp; // im SFC <script setup> inline mode, the exp may have been transformed into // _unref(exp) context.bindingMetadata[rawExp]; const maybeRef = !true /* SETUP_CONST */; if (!expString.trim() || (!isMemberExpression(expString) && !maybeRef)) { context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc)); return createTransformProps(); } const propName = arg ? arg : createSimpleExpression('modelValue', true); const eventName = arg ? isStaticExp(arg) ? `onUpdate:${arg.content}` : createCompoundExpression(['"onUpdate:" + ', arg]) : `onUpdate:modelValue`; let assignmentExp; const eventArg = context.isTS ? `($event: any)` : `$event`; { assignmentExp = createCompoundExpression([ `${eventArg} => ((`, exp, `) = $event)` ]); } const props = [ // modelValue: foo createObjectProperty(propName, dir.exp), // "onUpdate:modelValue": $event => (foo = $event) createObjectProperty(eventName, assignmentExp) ]; // modelModifiers: { foo: true, "bar-baz": true } if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) { const modifiers = dir.modifiers .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`) .join(`, `); const modifiersKey = arg ? isStaticExp(arg) ? `${arg.content}Modifiers` : createCompoundExpression([arg, ' + "Modifiers"']) : `modelModifiers`; props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */))); } return createTransformProps(props); }; function createTransformProps(props = []) { return { props }; } const validDivisionCharRE = /[\w).+\-_$\]]/; const transformFilter = (node, context) => { if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) { return; } if (node.type === 5 /* INTERPOLATION */) { // filter rewrite is applied before expression transform so only // simple expressions are possible at this stage rewriteFilter(node.content, context); } if (node.type === 1 /* ELEMENT */) { node.props.forEach((prop) => { if (prop.type === 7 /* DIRECTIVE */ && prop.name !== 'for' && prop.exp) { rewriteFilter(prop.exp, context); } }); } }; function rewriteFilter(node, context) { if (node.type === 4 /* SIMPLE_EXPRESSION */) { parseFilter(node, context); } else { for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; if (typeof child !== 'object') continue; if (child.type === 4 /* SIMPLE_EXPRESSION */) { parseFilter(child, context); } else if (child.type === 8 /* COMPOUND_EXPRESSION */) { rewriteFilter(node, context); } else if (child.type === 5 /* INTERPOLATION */) { rewriteFilter(child.content, context); } } } } function parseFilter(node, context) { const exp = node.content; let inSingle = false; let inDouble = false; let inTemplateString = false; let inRegex = false; let curly = 0; let square = 0; let paren = 0; let lastFilterIndex = 0; let c, prev, i, expression, filters = []; for (i = 0; i < exp.length; i++) { prev = c; c = exp.charCodeAt(i); if (inSingle) { if (c === 0x27 && prev !== 0x5c) inSingle = false; } else if (inDouble) { if (c === 0x22 && prev !== 0x5c) inDouble = false; } else if (inTemplateString) { if (c === 0x60 && prev !== 0x5c) inTemplateString = false; } else if (inRegex) { if (c === 0x2f && prev !== 0x5c) inRegex = false; } else if (c === 0x7c && // pipe exp.charCodeAt(i + 1) !== 0x7c && exp.charCodeAt(i - 1) !== 0x7c && !curly && !square && !paren) { if (expression === undefined) { // first filter, end of expression lastFilterIndex = i + 1; expression = exp.slice(0, i).trim(); } else { pushFilter(); } } else { switch (c) { case 0x22: inDouble = true; break; // " case 0x27: inSingle = true; break; // ' case 0x60: inTemplateString = true; break; // ` case 0x28: paren++; break; // ( case 0x29: paren--; break; // ) case 0x5b: square++; break; // [ case 0x5d: square--; break; // ] case 0x7b: curly++; break; // { case 0x7d: curly--; break; // } } if (c === 0x2f) { // / let j = i - 1; let p; // find first non-whitespace prev char for (; j >= 0; j--) { p = exp.charAt(j); if (p !== ' ') break; } if (!p || !validDivisionCharRE.test(p)) { inRegex = true; } } } } if (expression === undefined) { expression = exp.slice(0, i).trim(); } else if (lastFilterIndex !== 0) { pushFilter(); } function pushFilter() { filters.push(exp.slice(lastFilterIndex, i).trim()); lastFilterIndex = i + 1; } if (filters.length) { ( false) && 0; for (i = 0; i < filters.length; i++) { expression = wrapFilter(expression, filters[i], context); } node.content = expression; } } function wrapFilter(exp, filter, context) { context.helper(RESOLVE_FILTER); const i = filter.indexOf('('); if (i < 0) { context.filters.add(filter); return `${toValidAssetId(filter, 'filter')}(${exp})`; } else { const name = filter.slice(0, i); const args = filter.slice(i + 1); context.filters.add(name); return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`; } } const seen$1 = new WeakSet(); const transformMemo = (node, context) => { if (node.type === 1 /* ELEMENT */) { const dir = findDir(node, 'memo'); if (!dir || seen$1.has(node)) { return; } seen$1.add(node); return () => { const codegenNode = node.codegenNode || context.currentNode.codegenNode; if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) { // non-component sub tree should be turned into a block if (node.tagType !== 1 /* COMPONENT */) { makeBlock(codegenNode, context); } node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [ dir.exp, createFunctionExpression(undefined, codegenNode), `_cache`, String(context.cached++) ]); } }; } }; function getBaseTransformPreset(prefixIdentifiers) { return [ [ transformOnce, transformIf, transformMemo, transformFor, ...([transformFilter] ), ...(( false) ? 0 : []), transformSlotOutlet, transformElement, trackSlotScopes, transformText ], { on: transformOn, bind: transformBind, model: transformModel } ]; } // we name it `baseCompile` so that higher order compilers like // @vue/compiler-dom can export `compile` while re-exporting everything else. function baseCompile(template, options = {}) { const onError = options.onError || defaultOnError; const isModuleMode = options.mode === 'module'; /* istanbul ignore if */ { if (options.prefixIdentifiers === true) { onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */)); } else if (isModuleMode) { onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */)); } } const prefixIdentifiers = !true ; if (options.cacheHandlers) { onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */)); } if (options.scopeId && !isModuleMode) { onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */)); } const ast = (0,shared_esm_bundler.isString)(template) ? baseParse(template, options) : template; const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(); transform(ast, (0,shared_esm_bundler.extend)({}, options, { prefixIdentifiers, nodeTransforms: [ ...nodeTransforms, ...(options.nodeTransforms || []) // user transforms ], directiveTransforms: (0,shared_esm_bundler.extend)({}, directiveTransforms, options.directiveTransforms || {} // user transforms ) })); return generate(ast, (0,shared_esm_bundler.extend)({}, options, { prefixIdentifiers })); } const noopDirectiveTransform = () => ({ props: [] }); ;// CONCATENATED MODULE: ./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js const V_MODEL_RADIO = Symbol(( false) ? 0 : ``); const V_MODEL_CHECKBOX = Symbol(( false) ? 0 : ``); const V_MODEL_TEXT = Symbol(( false) ? 0 : ``); const V_MODEL_SELECT = Symbol(( false) ? 0 : ``); const V_MODEL_DYNAMIC = Symbol(( false) ? 0 : ``); const V_ON_WITH_MODIFIERS = Symbol(( false) ? 0 : ``); const V_ON_WITH_KEYS = Symbol(( false) ? 0 : ``); const V_SHOW = Symbol(( false) ? 0 : ``); const TRANSITION = Symbol(( false) ? 0 : ``); const TRANSITION_GROUP = Symbol(( false) ? 0 : ``); registerRuntimeHelpers({ [V_MODEL_RADIO]: `vModelRadio`, [V_MODEL_CHECKBOX]: `vModelCheckbox`, [V_MODEL_TEXT]: `vModelText`, [V_MODEL_SELECT]: `vModelSelect`, [V_MODEL_DYNAMIC]: `vModelDynamic`, [V_ON_WITH_MODIFIERS]: `withModifiers`, [V_ON_WITH_KEYS]: `withKeys`, [V_SHOW]: `vShow`, [TRANSITION]: `Transition`, [TRANSITION_GROUP]: `TransitionGroup` }); /* eslint-disable no-restricted-globals */ let decoder; function decodeHtmlBrowser(raw, asAttr = false) { if (!decoder) { decoder = document.createElement('div'); } if (asAttr) { decoder.innerHTML = `<div foo="${raw.replace(/"/g, '"')}">`; return decoder.children[0].getAttribute('foo'); } else { decoder.innerHTML = raw; return decoder.textContent; } } const isRawTextContainer = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)('style,iframe,script,noscript', true); const parserOptions = { isVoidTag: shared_esm_bundler.isVoidTag, isNativeTag: tag => (0,shared_esm_bundler.isHTMLTag)(tag) || (0,shared_esm_bundler.isSVGTag)(tag), isPreTag: tag => tag === 'pre', decodeEntities: decodeHtmlBrowser , isBuiltInComponent: (tag) => { if (isBuiltInType(tag, `Transition`)) { return TRANSITION; } else if (isBuiltInType(tag, `TransitionGroup`)) { return TRANSITION_GROUP; } }, // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher getNamespace(tag, parent) { let ns = parent ? parent.ns : 0 /* HTML */; if (parent && ns === 2 /* MATH_ML */) { if (parent.tag === 'annotation-xml') { if (tag === 'svg') { return 1 /* SVG */; } if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ && a.name === 'encoding' && a.value != null && (a.value.content === 'text/html' || a.value.content === 'application/xhtml+xml'))) { ns = 0 /* HTML */; } } else if (/^m(?:[ions]|text)$/.test(parent.tag) && tag !== 'mglyph' && tag !== 'malignmark') { ns = 0 /* HTML */; } } else if (parent && ns === 1 /* SVG */) { if (parent.tag === 'foreignObject' || parent.tag === 'desc' || parent.tag === 'title') { ns = 0 /* HTML */; } } if (ns === 0 /* HTML */) { if (tag === 'svg') { return 1 /* SVG */; } if (tag === 'math') { return 2 /* MATH_ML */; } } return ns; }, // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments getTextMode({ tag, ns }) { if (ns === 0 /* HTML */) { if (tag === 'textarea' || tag === 'title') { return 1 /* RCDATA */; } if (isRawTextContainer(tag)) { return 2 /* RAWTEXT */; } } return 0 /* DATA */; } }; // Parse inline CSS strings for static style attributes into an object. // This is a NodeTransform since it works on the static `style` attribute and // converts it into a dynamic equivalent: // style="color: red" -> :style='{ "color": "red" }' // It is then processed by `transformElement` and included in the generated // props. const transformStyle = node => { if (node.type === 1 /* ELEMENT */) { node.props.forEach((p, i) => { if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) { // replace p with an expression node node.props[i] = { type: 7 /* DIRECTIVE */, name: `bind`, arg: createSimpleExpression(`style`, true, p.loc), exp: parseInlineCSS(p.value.content, p.loc), modifiers: [], loc: p.loc }; } }); } }; const parseInlineCSS = (cssText, loc) => { const normalized = (0,shared_esm_bundler.parseStringStyle)(cssText); return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */); }; function createDOMCompilerError(code, loc) { return createCompilerError(code, loc, false ? 0 : undefined); } const DOMErrorMessages = { [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`, [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`, [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`, [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`, [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`, [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`, [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`, [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`, [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`, [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`, [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.` }; const transformVHtml = (dir, node, context) => { const { exp, loc } = dir; if (!exp) { context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc)); } if (node.children.length) { context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc)); node.children.length = 0; } return { props: [ createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true)) ] }; }; const transformVText = (dir, node, context) => { const { exp, loc } = dir; if (!exp) { context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc)); } if (node.children.length) { context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc)); node.children.length = 0; } return { props: [ createObjectProperty(createSimpleExpression(`textContent`, true), exp ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc) : createSimpleExpression('', true)) ] }; }; const compiler_dom_esm_bundler_transformModel = (dir, node, context) => { const baseResult = transformModel(dir, node, context); // base transform has errors OR component v-model (only need props) if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) { return baseResult; } if (dir.arg) { context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc)); } function checkDuplicatedValue() { const value = findProp(node, 'value'); if (value) { context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc)); } } const { tag } = node; const isCustomElement = context.isCustomElement(tag); if (tag === 'input' || tag === 'textarea' || tag === 'select' || isCustomElement) { let directiveToUse = V_MODEL_TEXT; let isInvalidType = false; if (tag === 'input' || isCustomElement) { const type = findProp(node, `type`); if (type) { if (type.type === 7 /* DIRECTIVE */) { // :type="foo" directiveToUse = V_MODEL_DYNAMIC; } else if (type.value) { switch (type.value.content) { case 'radio': directiveToUse = V_MODEL_RADIO; break; case 'checkbox': directiveToUse = V_MODEL_CHECKBOX; break; case 'file': isInvalidType = true; context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc)); break; default: // text type ( false) && 0; break; } } } else if (hasDynamicKeyVBind(node)) { // element has bindings with dynamic keys, which can possibly contain // "type". directiveToUse = V_MODEL_DYNAMIC; } else { // text type ( false) && 0; } } else if (tag === 'select') { directiveToUse = V_MODEL_SELECT; } else { // textarea ( false) && 0; } // inject runtime directive // by returning the helper symbol via needRuntime // the import will replaced a resolveDirective call. if (!isInvalidType) { baseResult.needRuntime = context.helper(directiveToUse); } } else { context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc)); } // native vmodel doesn't need the `modelValue` props since they are also // passed to the runtime as `binding.value`. removing it reduces code size. baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ && p.key.content === 'modelValue')); return baseResult; }; const isEventOptionModifier = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)(`passive,once,capture`); const isNonKeyModifier = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)( // event propagation management `stop,prevent,self,` + // system modifiers + exact `ctrl,shift,alt,meta,exact,` + // mouse `middle`); // left & right could be mouse or key modifiers based on event type const maybeKeyModifier = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)('left,right'); const isKeyboardEvent = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)(`onkeyup,onkeydown,onkeypress`, true); const resolveModifiers = (key, modifiers, context, loc) => { const keyModifiers = []; const nonKeyModifiers = []; const eventOptionModifiers = []; for (let i = 0; i < modifiers.length; i++) { const modifier = modifiers[i]; if (modifier === 'native' && checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) { eventOptionModifiers.push(modifier); } else if (isEventOptionModifier(modifier)) { // eventOptionModifiers: modifiers for addEventListener() options, // e.g. .passive & .capture eventOptionModifiers.push(modifier); } else { // runtimeModifiers: modifiers that needs runtime guards if (maybeKeyModifier(modifier)) { if (isStaticExp(key)) { if (isKeyboardEvent(key.content)) { keyModifiers.push(modifier); } else { nonKeyModifiers.push(modifier); } } else { keyModifiers.push(modifier); nonKeyModifiers.push(modifier); } } else { if (isNonKeyModifier(modifier)) { nonKeyModifiers.push(modifier); } else { keyModifiers.push(modifier); } } } } return { keyModifiers, nonKeyModifiers, eventOptionModifiers }; }; const transformClick = (key, event) => { const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick'; return isStaticClick ? createSimpleExpression(event, true) : key.type !== 4 /* SIMPLE_EXPRESSION */ ? createCompoundExpression([ `(`, key, `) === "onClick" ? "${event}" : (`, key, `)` ]) : key; }; const compiler_dom_esm_bundler_transformOn = (dir, node, context) => { return transformOn(dir, node, context, baseResult => { const { modifiers } = dir; if (!modifiers.length) return baseResult; let { key, value: handlerExp } = baseResult.props[0]; const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc); // normalize click.right and click.middle since they don't actually fire if (nonKeyModifiers.includes('right')) { key = transformClick(key, `onContextmenu`); } if (nonKeyModifiers.includes('middle')) { key = transformClick(key, `onMouseup`); } if (nonKeyModifiers.length) { handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [ handlerExp, JSON.stringify(nonKeyModifiers) ]); } if (keyModifiers.length && // if event name is dynamic, always wrap with keys guard (!isStaticExp(key) || isKeyboardEvent(key.content))) { handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [ handlerExp, JSON.stringify(keyModifiers) ]); } if (eventOptionModifiers.length) { const modifierPostfix = eventOptionModifiers.map(shared_esm_bundler.capitalize).join(''); key = isStaticExp(key) ? createSimpleExpression(`${key.content}${modifierPostfix}`, true) : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]); } return { props: [createObjectProperty(key, handlerExp)] }; }); }; const transformShow = (dir, node, context) => { const { exp, loc } = dir; if (!exp) { context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc)); } return { props: [], needRuntime: context.helper(V_SHOW) }; }; const warnTransitionChildren = (node, context) => { if (node.type === 1 /* ELEMENT */ && node.tagType === 1 /* COMPONENT */) { const component = context.isBuiltInComponent(node.tag); if (component === TRANSITION) { return () => { if (node.children.length && hasMultipleChildren(node)) { context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, { start: node.children[0].loc.start, end: node.children[node.children.length - 1].loc.end, source: '' })); } }; } } }; function hasMultipleChildren(node) { // #1352 filter out potential comment nodes. const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ && !(c.type === 2 /* TEXT */ && !c.content.trim()))); const child = children[0]; return (children.length !== 1 || child.type === 11 /* FOR */ || (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren))); } const ignoreSideEffectTags = (node, context) => { if (node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */ && (node.tag === 'script' || node.tag === 'style')) { context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc)); context.removeNode(); } }; const DOMNodeTransforms = [ transformStyle, ...(( false) ? 0 : []) ]; const DOMDirectiveTransforms = { cloak: noopDirectiveTransform, html: transformVHtml, text: transformVText, model: compiler_dom_esm_bundler_transformModel, on: compiler_dom_esm_bundler_transformOn, show: transformShow }; function compile(template, options = {}) { return baseCompile(template, (0,shared_esm_bundler.extend)({}, parserOptions, options, { nodeTransforms: [ // ignore <script> and <tag> // this is not put inside DOMNodeTransforms because that list is used // by compiler-ssr to generate vnode fallback branches ignoreSideEffectTags, ...DOMNodeTransforms, ...(options.nodeTransforms || []) ], directiveTransforms: (0,shared_esm_bundler.extend)({}, DOMDirectiveTransforms, options.directiveTransforms || {}), transformHoist: null })); } function parse(template, options = {}) { return baseParse(template, (0,shared_esm_bundler.extend)({}, parserOptions, options)); } /***/ }), /***/ "./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "BaseTransition": () => (/* reexport */ BaseTransition), "Comment": () => (/* reexport */ Comment), "EffectScope": () => (/* reexport */ EffectScope), "Fragment": () => (/* reexport */ Fragment), "KeepAlive": () => (/* reexport */ KeepAlive), "ReactiveEffect": () => (/* reexport */ ReactiveEffect), "Static": () => (/* reexport */ Static), "Suspense": () => (/* reexport */ Suspense), "Teleport": () => (/* reexport */ Teleport), "Text": () => (/* reexport */ Text), "Transition": () => (/* binding */ Transition), "TransitionGroup": () => (/* binding */ TransitionGroup), "VueElement": () => (/* binding */ VueElement), "callWithAsyncErrorHandling": () => (/* reexport */ callWithAsyncErrorHandling), "callWithErrorHandling": () => (/* reexport */ callWithErrorHandling), "camelize": () => (/* reexport */ shared_esm_bundler.camelize), "capitalize": () => (/* reexport */ shared_esm_bundler.capitalize), "cloneVNode": () => (/* reexport */ cloneVNode), "compatUtils": () => (/* reexport */ compatUtils), "computed": () => (/* reexport */ computed), "createApp": () => (/* binding */ createApp), "createBlock": () => (/* reexport */ createBlock), "createCommentVNode": () => (/* reexport */ createCommentVNode), "createElementBlock": () => (/* reexport */ createElementBlock), "createElementVNode": () => (/* reexport */ createBaseVNode), "createHydrationRenderer": () => (/* reexport */ createHydrationRenderer), "createPropsRestProxy": () => (/* reexport */ createPropsRestProxy), "createRenderer": () => (/* reexport */ createRenderer), "createSSRApp": () => (/* binding */ createSSRApp), "createSlots": () => (/* reexport */ createSlots), "createStaticVNode": () => (/* reexport */ createStaticVNode), "createTextVNode": () => (/* reexport */ createTextVNode), "createVNode": () => (/* reexport */ createVNode), "customRef": () => (/* reexport */ customRef), "defineAsyncComponent": () => (/* reexport */ defineAsyncComponent), "defineComponent": () => (/* reexport */ defineComponent), "defineCustomElement": () => (/* binding */ defineCustomElement), "defineEmits": () => (/* reexport */ defineEmits), "defineExpose": () => (/* reexport */ defineExpose), "defineProps": () => (/* reexport */ defineProps), "defineSSRCustomElement": () => (/* binding */ defineSSRCustomElement), "devtools": () => (/* reexport */ devtools), "effect": () => (/* reexport */ effect), "effectScope": () => (/* reexport */ effectScope), "getCurrentInstance": () => (/* reexport */ getCurrentInstance), "getCurrentScope": () => (/* reexport */ getCurrentScope), "getTransitionRawChildren": () => (/* reexport */ getTransitionRawChildren), "guardReactiveProps": () => (/* reexport */ guardReactiveProps), "h": () => (/* reexport */ h), "handleError": () => (/* reexport */ handleError), "hydrate": () => (/* binding */ hydrate), "initCustomFormatter": () => (/* reexport */ initCustomFormatter), "initDirectivesForSSR": () => (/* binding */ initDirectivesForSSR), "inject": () => (/* reexport */ inject), "isMemoSame": () => (/* reexport */ isMemoSame), "isProxy": () => (/* reexport */ isProxy), "isReactive": () => (/* reexport */ isReactive), "isReadonly": () => (/* reexport */ isReadonly), "isRef": () => (/* reexport */ isRef), "isRuntimeOnly": () => (/* reexport */ runtime_core_esm_bundler_isRuntimeOnly), "isVNode": () => (/* reexport */ isVNode), "markRaw": () => (/* reexport */ markRaw), "mergeDefaults": () => (/* reexport */ mergeDefaults), "mergeProps": () => (/* reexport */ mergeProps), "nextTick": () => (/* reexport */ nextTick), "normalizeClass": () => (/* reexport */ shared_esm_bundler.normalizeClass), "normalizeProps": () => (/* reexport */ shared_esm_bundler.normalizeProps), "normalizeStyle": () => (/* reexport */ shared_esm_bundler.normalizeStyle), "onActivated": () => (/* reexport */ onActivated), "onBeforeMount": () => (/* reexport */ onBeforeMount), "onBeforeUnmount": () => (/* reexport */ onBeforeUnmount), "onBeforeUpdate": () => (/* reexport */ onBeforeUpdate), "onDeactivated": () => (/* reexport */ onDeactivated), "onErrorCaptured": () => (/* reexport */ onErrorCaptured), "onMounted": () => (/* reexport */ onMounted), "onRenderTracked": () => (/* reexport */ onRenderTracked), "onRenderTriggered": () => (/* reexport */ onRenderTriggered), "onScopeDispose": () => (/* reexport */ onScopeDispose), "onServerPrefetch": () => (/* reexport */ onServerPrefetch), "onUnmounted": () => (/* reexport */ onUnmounted), "onUpdated": () => (/* reexport */ onUpdated), "openBlock": () => (/* reexport */ openBlock), "popScopeId": () => (/* reexport */ popScopeId), "provide": () => (/* reexport */ provide), "proxyRefs": () => (/* reexport */ proxyRefs), "pushScopeId": () => (/* reexport */ pushScopeId), "queuePostFlushCb": () => (/* reexport */ queuePostFlushCb), "reactive": () => (/* reexport */ reactive), "readonly": () => (/* reexport */ readonly), "ref": () => (/* reexport */ ref), "registerRuntimeCompiler": () => (/* reexport */ registerRuntimeCompiler), "render": () => (/* binding */ render), "renderList": () => (/* reexport */ renderList), "renderSlot": () => (/* reexport */ renderSlot), "resolveComponent": () => (/* reexport */ resolveComponent), "resolveDirective": () => (/* reexport */ resolveDirective), "resolveDynamicComponent": () => (/* reexport */ resolveDynamicComponent), "resolveFilter": () => (/* reexport */ resolveFilter), "resolveTransitionHooks": () => (/* reexport */ resolveTransitionHooks), "setBlockTracking": () => (/* reexport */ setBlockTracking), "setDevtoolsHook": () => (/* reexport */ setDevtoolsHook), "setTransitionHooks": () => (/* reexport */ setTransitionHooks), "shallowReactive": () => (/* reexport */ shallowReactive), "shallowReadonly": () => (/* reexport */ shallowReadonly), "shallowRef": () => (/* reexport */ shallowRef), "ssrContextKey": () => (/* reexport */ ssrContextKey), "ssrUtils": () => (/* reexport */ ssrUtils), "stop": () => (/* reexport */ stop), "toDisplayString": () => (/* reexport */ shared_esm_bundler.toDisplayString), "toHandlerKey": () => (/* reexport */ shared_esm_bundler.toHandlerKey), "toHandlers": () => (/* reexport */ toHandlers), "toRaw": () => (/* reexport */ reactivity_esm_bundler_toRaw), "toRef": () => (/* reexport */ toRef), "toRefs": () => (/* reexport */ toRefs), "transformVNodeArgs": () => (/* reexport */ transformVNodeArgs), "triggerRef": () => (/* reexport */ triggerRef), "unref": () => (/* reexport */ unref), "useAttrs": () => (/* reexport */ useAttrs), "useCssModule": () => (/* binding */ useCssModule), "useCssVars": () => (/* binding */ useCssVars), "useSSRContext": () => (/* reexport */ useSSRContext), "useSlots": () => (/* reexport */ useSlots), "useTransitionState": () => (/* reexport */ useTransitionState), "vModelCheckbox": () => (/* binding */ vModelCheckbox), "vModelDynamic": () => (/* binding */ vModelDynamic), "vModelRadio": () => (/* binding */ vModelRadio), "vModelSelect": () => (/* binding */ vModelSelect), "vModelText": () => (/* binding */ vModelText), "vShow": () => (/* binding */ vShow), "version": () => (/* reexport */ version), "warn": () => (/* reexport */ runtime_core_esm_bundler_warn), "watch": () => (/* reexport */ watch), "watchEffect": () => (/* reexport */ watchEffect), "watchPostEffect": () => (/* reexport */ watchPostEffect), "watchSyncEffect": () => (/* reexport */ watchSyncEffect), "withAsyncContext": () => (/* reexport */ withAsyncContext), "withCtx": () => (/* reexport */ withCtx), "withDefaults": () => (/* reexport */ withDefaults), "withDirectives": () => (/* reexport */ withDirectives), "withKeys": () => (/* binding */ withKeys), "withMemo": () => (/* reexport */ withMemo), "withModifiers": () => (/* binding */ withModifiers), "withScopeId": () => (/* reexport */ withScopeId) }); // EXTERNAL MODULE: ./node_modules/@vue/shared/dist/shared.esm-bundler.js var shared_esm_bundler = __webpack_require__("./node_modules/@vue/shared/dist/shared.esm-bundler.js"); ;// CONCATENATED MODULE: ./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js function reactivity_esm_bundler_warn(msg, ...args) { console.warn(`[Vue warn] ${msg}`, ...args); } let activeEffectScope; const effectScopeStack = []; class EffectScope { constructor(detached = false) { this.active = true; this.effects = []; this.cleanups = []; if (!detached && activeEffectScope) { this.parent = activeEffectScope; this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1; } } run(fn) { if (this.active) { try { this.on(); return fn(); } finally { this.off(); } } else if ((false)) {} } on() { if (this.active) { effectScopeStack.push(this); activeEffectScope = this; } } off() { if (this.active) { effectScopeStack.pop(); activeEffectScope = effectScopeStack[effectScopeStack.length - 1]; } } stop(fromParent) { if (this.active) { this.effects.forEach(e => e.stop()); this.cleanups.forEach(cleanup => cleanup()); if (this.scopes) { this.scopes.forEach(e => e.stop(true)); } // nested scope, dereference from parent to avoid memory leaks if (this.parent && !fromParent) { // optimized O(1) removal const last = this.parent.scopes.pop(); if (last && last !== this) { this.parent.scopes[this.index] = last; last.index = this.index; } } this.active = false; } } } function effectScope(detached) { return new EffectScope(detached); } function recordEffectScope(effect, scope) { scope = scope || activeEffectScope; if (scope && scope.active) { scope.effects.push(effect); } } function getCurrentScope() { return activeEffectScope; } function onScopeDispose(fn) { if (activeEffectScope) { activeEffectScope.cleanups.push(fn); } else if ((false)) {} } const createDep = (effects) => { const dep = new Set(effects); dep.w = 0; dep.n = 0; return dep; }; const wasTracked = (dep) => (dep.w & trackOpBit) > 0; const newTracked = (dep) => (dep.n & trackOpBit) > 0; const initDepMarkers = ({ deps }) => { if (deps.length) { for (let i = 0; i < deps.length; i++) { deps[i].w |= trackOpBit; // set was tracked } } }; const finalizeDepMarkers = (effect) => { const { deps } = effect; if (deps.length) { let ptr = 0; for (let i = 0; i < deps.length; i++) { const dep = deps[i]; if (wasTracked(dep) && !newTracked(dep)) { dep.delete(effect); } else { deps[ptr++] = dep; } // clear bits dep.w &= ~trackOpBit; dep.n &= ~trackOpBit; } deps.length = ptr; } }; const targetMap = new WeakMap(); // The number of effects currently being tracked recursively. let effectTrackDepth = 0; let trackOpBit = 1; /** * The bitwise track markers support at most 30 levels op recursion. * This value is chosen to enable modern JS engines to use a SMI on all platforms. * When recursion depth is greater, fall back to using a full cleanup. */ const maxMarkerBits = 30; const effectStack = []; let activeEffect; const ITERATE_KEY = Symbol(( false) ? 0 : ''); const MAP_KEY_ITERATE_KEY = Symbol(( false) ? 0 : ''); class ReactiveEffect { constructor(fn, scheduler = null, scope) { this.fn = fn; this.scheduler = scheduler; this.active = true; this.deps = []; recordEffectScope(this, scope); } run() { if (!this.active) { return this.fn(); } if (!effectStack.includes(this)) { try { effectStack.push((activeEffect = this)); enableTracking(); trackOpBit = 1 << ++effectTrackDepth; if (effectTrackDepth <= maxMarkerBits) { initDepMarkers(this); } else { cleanupEffect(this); } return this.fn(); } finally { if (effectTrackDepth <= maxMarkerBits) { finalizeDepMarkers(this); } trackOpBit = 1 << --effectTrackDepth; resetTracking(); effectStack.pop(); const n = effectStack.length; activeEffect = n > 0 ? effectStack[n - 1] : undefined; } } } stop() { if (this.active) { cleanupEffect(this); if (this.onStop) { this.onStop(); } this.active = false; } } } function cleanupEffect(effect) { const { deps } = effect; if (deps.length) { for (let i = 0; i < deps.length; i++) { deps[i].delete(effect); } deps.length = 0; } } function effect(fn, options) { if (fn.effect) { fn = fn.effect.fn; } const _effect = new ReactiveEffect(fn); if (options) { (0,shared_esm_bundler.extend)(_effect, options); if (options.scope) recordEffectScope(_effect, options.scope); } if (!options || !options.lazy) { _effect.run(); } const runner = _effect.run.bind(_effect); runner.effect = _effect; return runner; } function stop(runner) { runner.effect.stop(); } let shouldTrack = true; const trackStack = []; function pauseTracking() { trackStack.push(shouldTrack); shouldTrack = false; } function enableTracking() { trackStack.push(shouldTrack); shouldTrack = true; } function resetTracking() { const last = trackStack.pop(); shouldTrack = last === undefined ? true : last; } function track(target, type, key) { if (!isTracking()) { return; } let depsMap = targetMap.get(target); if (!depsMap) { targetMap.set(target, (depsMap = new Map())); } let dep = depsMap.get(key); if (!dep) { depsMap.set(key, (dep = createDep())); } const eventInfo = ( false) ? 0 : undefined; trackEffects(dep, eventInfo); } function isTracking() { return shouldTrack && activeEffect !== undefined; } function trackEffects(dep, debuggerEventExtraInfo) { let shouldTrack = false; if (effectTrackDepth <= maxMarkerBits) { if (!newTracked(dep)) { dep.n |= trackOpBit; // set newly tracked shouldTrack = !wasTracked(dep); } } else { // Full cleanup mode. shouldTrack = !dep.has(activeEffect); } if (shouldTrack) { dep.add(activeEffect); activeEffect.deps.push(dep); if (false) {} } } function trigger(target, type, key, newValue, oldValue, oldTarget) { const depsMap = targetMap.get(target); if (!depsMap) { // never been tracked return; } let deps = []; if (type === "clear" /* CLEAR */) { // collection being cleared // trigger all effects for target deps = [...depsMap.values()]; } else if (key === 'length' && (0,shared_esm_bundler.isArray)(target)) { depsMap.forEach((dep, key) => { if (key === 'length' || key >= newValue) { deps.push(dep); } }); } else { // schedule runs for SET | ADD | DELETE if (key !== void 0) { deps.push(depsMap.get(key)); } // also run for iteration key on ADD | DELETE | Map.SET switch (type) { case "add" /* ADD */: if (!(0,shared_esm_bundler.isArray)(target)) { deps.push(depsMap.get(ITERATE_KEY)); if ((0,shared_esm_bundler.isMap)(target)) { deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); } } else if ((0,shared_esm_bundler.isIntegerKey)(key)) { // new index added to array -> length changes deps.push(depsMap.get('length')); } break; case "delete" /* DELETE */: if (!(0,shared_esm_bundler.isArray)(target)) { deps.push(depsMap.get(ITERATE_KEY)); if ((0,shared_esm_bundler.isMap)(target)) { deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); } } break; case "set" /* SET */: if ((0,shared_esm_bundler.isMap)(target)) { deps.push(depsMap.get(ITERATE_KEY)); } break; } } const eventInfo = ( false) ? 0 : undefined; if (deps.length === 1) { if (deps[0]) { if ((false)) {} else { triggerEffects(deps[0]); } } } else { const effects = []; for (const dep of deps) { if (dep) { effects.push(...dep); } } if ((false)) {} else { triggerEffects(createDep(effects)); } } } function triggerEffects(dep, debuggerEventExtraInfo) { // spread into array for stabilization for (const effect of (0,shared_esm_bundler.isArray)(dep) ? dep : [...dep]) { if (effect !== activeEffect || effect.allowRecurse) { if (false) {} if (effect.scheduler) { effect.scheduler(); } else { effect.run(); } } } } const isNonTrackableKeys = /*#__PURE__*/ (0,shared_esm_bundler.makeMap)(`__proto__,__v_isRef,__isVue`); const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol) .map(key => Symbol[key]) .filter(shared_esm_bundler.isSymbol)); const get = /*#__PURE__*/ createGetter(); const shallowGet = /*#__PURE__*/ createGetter(false, true); const readonlyGet = /*#__PURE__*/ createGetter(true); const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations(); function createArrayInstrumentations() { const instrumentations = {}; ['includes', 'indexOf', 'lastIndexOf'].forEach(key => { instrumentations[key] = function (...args) { const arr = reactivity_esm_bundler_toRaw(this); for (let i = 0, l = this.length; i < l; i++) { track(arr, "get" /* GET */, i + ''); } // we run the method using the original args first (which may be reactive) const res = arr[key](...args); if (res === -1 || res === false) { // if that didn't work, run it again using raw values. return arr[key](...args.map(reactivity_esm_bundler_toRaw)); } else { return res; } }; }); ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => { instrumentations[key] = function (...args) { pauseTracking(); const res = reactivity_esm_bundler_toRaw(this)[key].apply(this, args); resetTracking(); return res; }; }); return instrumentations; } function createGetter(isReadonly = false, shallow = false) { return function get(target, key, receiver) { if (key === "__v_isReactive" /* IS_REACTIVE */) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */) { return isReadonly; } else if (key === "__v_raw" /* RAW */ && receiver === (isReadonly ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) { return target; } const targetIsArray = (0,shared_esm_bundler.isArray)(target); if (!isReadonly && targetIsArray && (0,shared_esm_bundler.hasOwn)(arrayInstrumentations, key)) { return Reflect.get(arrayInstrumentations, key, receiver); } const res = Reflect.get(target, key, receiver); if ((0,shared_esm_bundler.isSymbol)(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { return res; } if (!isReadonly) { track(target, "get" /* GET */, key); } if (shallow) { return res; } if (isRef(res)) { // ref unwrapping - does not apply for Array + integer key. const shouldUnwrap = !targetIsArray || !(0,shared_esm_bundler.isIntegerKey)(key); return shouldUnwrap ? res.value : res; } if ((0,shared_esm_bundler.isObject)(res)) { // Convert returned value into a proxy as well. we do the isObject check // here to avoid invalid value warning. Also need to lazy access readonly // and reactive here to avoid circular dependency. return isReadonly ? readonly(res) : reactive(res); } return res; }; } const set = /*#__PURE__*/ createSetter(); const shallowSet = /*#__PURE__*/ createSetter(true); function createSetter(shallow = false) { return function set(target, key, value, receiver) { let oldValue = target[key]; if (!shallow) { value = reactivity_esm_bundler_toRaw(value); oldValue = reactivity_esm_bundler_toRaw(oldValue); if (!(0,shared_esm_bundler.isArray)(target) && isRef(oldValue) && !isRef(value)) { oldValue.value = value; return true; } } const hadKey = (0,shared_esm_bundler.isArray)(target) && (0,shared_esm_bundler.isIntegerKey)(key) ? Number(key) < target.length : (0,shared_esm_bundler.hasOwn)(target, key); const result = Reflect.set(target, key, value, receiver); // don't trigger if target is something up in the prototype chain of original if (target === reactivity_esm_bundler_toRaw(receiver)) { if (!hadKey) { trigger(target, "add" /* ADD */, key, value); } else if ((0,shared_esm_bundler.hasChanged)(value, oldValue)) { trigger(target, "set" /* SET */, key, value, oldValue); } } return result; }; } function deleteProperty(target, key) { const hadKey = (0,shared_esm_bundler.hasOwn)(target, key); const oldValue = target[key]; const result = Reflect.deleteProperty(target, key); if (result && hadKey) { trigger(target, "delete" /* DELETE */, key, undefined, oldValue); } return result; } function has(target, key) { const result = Reflect.has(target, key); if (!(0,shared_esm_bundler.isSymbol)(key) || !builtInSymbols.has(key)) { track(target, "has" /* HAS */, key); } return result; } function ownKeys(target) { track(target, "iterate" /* ITERATE */, (0,shared_esm_bundler.isArray)(target) ? 'length' : ITERATE_KEY); return Reflect.ownKeys(target); } const mutableHandlers = { get, set, deleteProperty, has, ownKeys }; const readonlyHandlers = { get: readonlyGet, set(target, key) { if ((false)) {} return true; }, deleteProperty(target, key) { if ((false)) {} return true; } }; const shallowReactiveHandlers = /*#__PURE__*/ (0,shared_esm_bundler.extend)({}, mutableHandlers, { get: shallowGet, set: shallowSet }); // Props handlers are special in the sense that it should not unwrap top-level // refs (in order to allow refs to be explicitly passed down), but should // retain the reactivity of the normal readonly object. const shallowReadonlyHandlers = /*#__PURE__*/ (0,shared_esm_bundler.extend)({}, readonlyHandlers, { get: shallowReadonlyGet }); const toShallow = (value) => value; const getProto = (v) => Reflect.getPrototypeOf(v); function get$1(target, key, isReadonly = false, isShallow = false) { // #1772: readonly(reactive(Map)) should return readonly + reactive version // of the value target = target["__v_raw" /* RAW */]; const rawTarget = reactivity_esm_bundler_toRaw(target); const rawKey = reactivity_esm_bundler_toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "get" /* GET */, key); } !isReadonly && track(rawTarget, "get" /* GET */, rawKey); const { has } = getProto(rawTarget); const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; if (has.call(rawTarget, key)) { return wrap(target.get(key)); } else if (has.call(rawTarget, rawKey)) { return wrap(target.get(rawKey)); } else if (target !== rawTarget) { // #3602 readonly(reactive(Map)) // ensure that the nested reactive `Map` can do tracking for itself target.get(key); } } function has$1(key, isReadonly = false) { const target = this["__v_raw" /* RAW */]; const rawTarget = reactivity_esm_bundler_toRaw(target); const rawKey = reactivity_esm_bundler_toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "has" /* HAS */, key); } !isReadonly && track(rawTarget, "has" /* HAS */, rawKey); return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); } function size(target, isReadonly = false) { target = target["__v_raw" /* RAW */]; !isReadonly && track(reactivity_esm_bundler_toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY); return Reflect.get(target, 'size', target); } function add(value) { value = reactivity_esm_bundler_toRaw(value); const target = reactivity_esm_bundler_toRaw(this); const proto = getProto(target); const hadKey = proto.has.call(target, value); if (!hadKey) { target.add(value); trigger(target, "add" /* ADD */, value, value); } return this; } function set$1(key, value) { value = reactivity_esm_bundler_toRaw(value); const target = reactivity_esm_bundler_toRaw(this); const { has, get } = getProto(target); let hadKey = has.call(target, key); if (!hadKey) { key = reactivity_esm_bundler_toRaw(key); hadKey = has.call(target, key); } else if ((false)) {} const oldValue = get.call(target, key); target.set(key, value); if (!hadKey) { trigger(target, "add" /* ADD */, key, value); } else if ((0,shared_esm_bundler.hasChanged)(value, oldValue)) { trigger(target, "set" /* SET */, key, value, oldValue); } return this; } function deleteEntry(key) { const target = reactivity_esm_bundler_toRaw(this); const { has, get } = getProto(target); let hadKey = has.call(target, key); if (!hadKey) { key = reactivity_esm_bundler_toRaw(key); hadKey = has.call(target, key); } else if ((false)) {} const oldValue = get ? get.call(target, key) : undefined; // forward the operation before queueing reactions const result = target.delete(key); if (hadKey) { trigger(target, "delete" /* DELETE */, key, undefined, oldValue); } return result; } function clear() { const target = reactivity_esm_bundler_toRaw(this); const hadItems = target.size !== 0; const oldTarget = ( false) ? 0 : undefined; // forward the operation before queueing reactions const result = target.clear(); if (hadItems) { trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget); } return result; } function createForEach(isReadonly, isShallow) { return function forEach(callback, thisArg) { const observed = this; const target = observed["__v_raw" /* RAW */]; const rawTarget = reactivity_esm_bundler_toRaw(target); const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY); return target.forEach((value, key) => { // important: make sure the callback is // 1. invoked with the reactive map as `this` and 3rd arg // 2. the value received should be a corresponding reactive/readonly. return callback.call(thisArg, wrap(value), wrap(key), observed); }); }; } function createIterableMethod(method, isReadonly, isShallow) { return function (...args) { const target = this["__v_raw" /* RAW */]; const rawTarget = reactivity_esm_bundler_toRaw(target); const targetIsMap = (0,shared_esm_bundler.isMap)(rawTarget); const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap); const isKeyOnly = method === 'keys' && targetIsMap; const innerIterator = target[method](...args); const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); // return a wrapped iterator which returns observed versions of the // values emitted from the real iterator return { // iterator protocol next() { const { value, done } = innerIterator.next(); return done ? { value, done } : { value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), done }; }, // iterable protocol [Symbol.iterator]() { return this; } }; }; } function createReadonlyMethod(type) { return function (...args) { if ((false)) {} return type === "delete" /* DELETE */ ? false : this; }; } function createInstrumentations() { const mutableInstrumentations = { get(key) { return get$1(this, key); }, get size() { return size(this); }, has: has$1, add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, false) }; const shallowInstrumentations = { get(key) { return get$1(this, key, false, true); }, get size() { return size(this); }, has: has$1, add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, true) }; const readonlyInstrumentations = { get(key) { return get$1(this, key, true); }, get size() { return size(this, true); }, has(key) { return has$1.call(this, key, true); }, add: createReadonlyMethod("add" /* ADD */), set: createReadonlyMethod("set" /* SET */), delete: createReadonlyMethod("delete" /* DELETE */), clear: createReadonlyMethod("clear" /* CLEAR */), forEach: createForEach(true, false) }; const shallowReadonlyInstrumentations = { get(key) { return get$1(this, key, true, true); }, get size() { return size(this, true); }, has(key) { return has$1.call(this, key, true); }, add: createReadonlyMethod("add" /* ADD */), set: createReadonlyMethod("set" /* SET */), delete: createReadonlyMethod("delete" /* DELETE */), clear: createReadonlyMethod("clear" /* CLEAR */), forEach: createForEach(true, true) }; const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; iteratorMethods.forEach(method => { mutableInstrumentations[method] = createIterableMethod(method, false, false); readonlyInstrumentations[method] = createIterableMethod(method, true, false); shallowInstrumentations[method] = createIterableMethod(method, false, true); shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); }); return [ mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations ]; } const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations(); function createInstrumentationGetter(isReadonly, shallow) { const instrumentations = shallow ? isReadonly ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations; return (target, key, receiver) => { if (key === "__v_isReactive" /* IS_REACTIVE */) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */) { return isReadonly; } else if (key === "__v_raw" /* RAW */) { return target; } return Reflect.get((0,shared_esm_bundler.hasOwn)(instrumentations, key) && key in target ? instrumentations : target, key, receiver); }; } const mutableCollectionHandlers = { get: /*#__PURE__*/ createInstrumentationGetter(false, false) }; const shallowCollectionHandlers = { get: /*#__PURE__*/ createInstrumentationGetter(false, true) }; const readonlyCollectionHandlers = { get: /*#__PURE__*/ createInstrumentationGetter(true, false) }; const shallowReadonlyCollectionHandlers = { get: /*#__PURE__*/ createInstrumentationGetter(true, true) }; function checkIdentityKeys(target, has, key) { const rawKey = reactivity_esm_bundler_toRaw(key); if (rawKey !== key && has.call(target, rawKey)) { const type = toRawType(target); console.warn(`Reactive ${type} contains both the raw and reactive ` + `versions of the same object${type === `Map` ? ` as keys` : ``}, ` + `which can lead to inconsistencies. ` + `Avoid differentiating between the raw and reactive versions ` + `of an object and only use the reactive version if possible.`); } } const reactiveMap = new WeakMap(); const shallowReactiveMap = new WeakMap(); const readonlyMap = new WeakMap(); const shallowReadonlyMap = new WeakMap(); function targetTypeMap(rawType) { switch (rawType) { case 'Object': case 'Array': return 1 /* COMMON */; case 'Map': case 'Set': case 'WeakMap': case 'WeakSet': return 2 /* COLLECTION */; default: return 0 /* INVALID */; } } function getTargetType(value) { return value["__v_skip" /* SKIP */] || !Object.isExtensible(value) ? 0 /* INVALID */ : targetTypeMap((0,shared_esm_bundler.toRawType)(value)); } function reactive(target) { // if trying to observe a readonly proxy, return the readonly version. if (target && target["__v_isReadonly" /* IS_READONLY */]) { return target; } return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); } /** * Return a shallowly-reactive copy of the original object, where only the root * level properties are reactive. It also does not auto-unwrap refs (even at the * root level). */ function shallowReactive(target) { return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); } /** * Creates a readonly copy of the original object. Note the returned copy is not * made reactive, but `readonly` can be called on an already reactive object. */ function readonly(target) { return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); } /** * Returns a reactive-copy of the original object, where only the root level * properties are readonly, and does NOT unwrap refs nor recursively convert * returned properties. * This is used for creating the props proxy object for stateful components. */ function shallowReadonly(target) { return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); } function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { if (!(0,shared_esm_bundler.isObject)(target)) { if ((false)) {} return target; } // target is already a Proxy, return it. // exception: calling readonly() on a reactive object if (target["__v_raw" /* RAW */] && !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) { return target; } // target already has corresponding Proxy const existingProxy = proxyMap.get(target); if (existingProxy) { return existingProxy; } // only a whitelist of value types can be observed. const targetType = getTargetType(target); if (targetType === 0 /* INVALID */) { return target; } const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); proxyMap.set(target, proxy); return proxy; } function isReactive(value) { if (isReadonly(value)) { return isReactive(value["__v_raw" /* RAW */]); } return !!(value && value["__v_isReactive" /* IS_REACTIVE */]); } function isReadonly(value) { return !!(value && value["__v_isReadonly" /* IS_READONLY */]); } function isProxy(value) { return isReactive(value) || isReadonly(value); } function reactivity_esm_bundler_toRaw(observed) { const raw = observed && observed["__v_raw" /* RAW */]; return raw ? reactivity_esm_bundler_toRaw(raw) : observed; } function markRaw(value) { (0,shared_esm_bundler.def)(value, "__v_skip" /* SKIP */, true); return value; } const toReactive = (value) => (0,shared_esm_bundler.isObject)(value) ? reactive(value) : value; const toReadonly = (value) => (0,shared_esm_bundler.isObject)(value) ? readonly(value) : value; function trackRefValue(ref) { if (isTracking()) { ref = reactivity_esm_bundler_toRaw(ref); if (!ref.dep) { ref.dep = createDep(); } if ((false)) {} else { trackEffects(ref.dep); } } } function triggerRefValue(ref, newVal) { ref = reactivity_esm_bundler_toRaw(ref); if (ref.dep) { if ((false)) {} else { triggerEffects(ref.dep); } } } function isRef(r) { return Boolean(r && r.__v_isRef === true); } function ref(value) { return createRef(value, false); } function shallowRef(value) { return createRef(value, true); } function createRef(rawValue, shallow) { if (isRef(rawValue)) { return rawValue; } return new RefImpl(rawValue, shallow); } class RefImpl { constructor(value, _shallow) { this._shallow = _shallow; this.dep = undefined; this.__v_isRef = true; this._rawValue = _shallow ? value : reactivity_esm_bundler_toRaw(value); this._value = _shallow ? value : toReactive(value); } get value() { trackRefValue(this); return this._value; } set value(newVal) { newVal = this._shallow ? newVal : reactivity_esm_bundler_toRaw(newVal); if ((0,shared_esm_bundler.hasChanged)(newVal, this._rawValue)) { this._rawValue = newVal; this._value = this._shallow ? newVal : toReactive(newVal); triggerRefValue(this, newVal); } } } function triggerRef(ref) { triggerRefValue(ref, ( false) ? 0 : void 0); } function unref(ref) { return isRef(ref) ? ref.value : ref; } const shallowUnwrapHandlers = { get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), set: (target, key, value, receiver) => { const oldValue = target[key]; if (isRef(oldValue) && !isRef(value)) { oldValue.value = value; return true; } else { return Reflect.set(target, key, value, receiver); } } }; function proxyRefs(objectWithRefs) { return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); } class CustomRefImpl { constructor(factory) { this.dep = undefined; this.__v_isRef = true; const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this)); this._get = get; this._set = set; } get value() { return this._get(); } set value(newVal) { this._set(newVal); } } function customRef(factory) { return new CustomRefImpl(factory); } function toRefs(object) { if (false) {} const ret = (0,shared_esm_bundler.isArray)(object) ? new Array(object.length) : {}; for (const key in object) { ret[key] = toRef(object, key); } return ret; } class ObjectRefImpl { constructor(_object, _key) { this._object = _object; this._key = _key; this.__v_isRef = true; } get value() { return this._object[this._key]; } set value(newVal) { this._object[this._key] = newVal; } } function toRef(object, key) { const val = object[key]; return isRef(val) ? val : new ObjectRefImpl(object, key); } class ComputedRefImpl { constructor(getter, _setter, isReadonly) { this._setter = _setter; this.dep = undefined; this._dirty = true; this.__v_isRef = true; this.effect = new ReactiveEffect(getter, () => { if (!this._dirty) { this._dirty = true; triggerRefValue(this); } }); this["__v_isReadonly" /* IS_READONLY */] = isReadonly; } get value() { // the computed ref may get wrapped by other proxies e.g. readonly() #3376 const self = reactivity_esm_bundler_toRaw(this); trackRefValue(self); if (self._dirty) { self._dirty = false; self._value = self.effect.run(); } return self._value; } set value(newValue) { this._setter(newValue); } } function computed(getterOrOptions, debugOptions) { let getter; let setter; const onlyGetter = (0,shared_esm_bundler.isFunction)(getterOrOptions); if (onlyGetter) { getter = getterOrOptions; setter = ( false) ? 0 : shared_esm_bundler.NOOP; } else { getter = getterOrOptions.get; setter = getterOrOptions.set; } const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter); if (false) {} return cRef; } var _a; const tick = Promise.resolve(); const queue = (/* unused pure expression or super */ null && ([])); let queued = false; const scheduler = (fn) => { queue.push(fn); if (!queued) { queued = true; tick.then(flush); } }; const flush = () => { for (let i = 0; i < queue.length; i++) { queue[i](); } queue.length = 0; queued = false; }; class DeferredComputedRefImpl { constructor(getter) { this.dep = undefined; this._dirty = true; this.__v_isRef = true; this[_a] = true; let compareTarget; let hasCompareTarget = false; let scheduled = false; this.effect = new ReactiveEffect(getter, (computedTrigger) => { if (this.dep) { if (computedTrigger) { compareTarget = this._value; hasCompareTarget = true; } else if (!scheduled) { const valueToCompare = hasCompareTarget ? compareTarget : this._value; scheduled = true; hasCompareTarget = false; scheduler(() => { if (this.effect.active && this._get() !== valueToCompare) { triggerRefValue(this); } scheduled = false; }); } // chained upstream computeds are notified synchronously to ensure // value invalidation in case of sync access; normal effects are // deferred to be triggered in scheduler. for (const e of this.dep) { if (e.computed) { e.scheduler(true /* computedTrigger */); } } } this._dirty = true; }); this.effect.computed = true; } _get() { if (this._dirty) { this._dirty = false; return (this._value = this.effect.run()); } return this._value; } get value() { trackRefValue(this); // the computed ref may get wrapped by other proxies e.g. readonly() #3376 return reactivity_esm_bundler_toRaw(this)._get(); } } _a = "__v_isReadonly" /* IS_READONLY */; function deferredComputed(getter) { return new DeferredComputedRefImpl(getter); } ;// CONCATENATED MODULE: ./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js /* eslint-disable no-restricted-globals */ let isHmrUpdating = false; const hmrDirtyComponents = new Set(); // Expose the HMR runtime on the global object // This makes it entirely tree-shakable without polluting the exports and makes // it easier to be used in toolings like vue-loader // Note: for a component to be eligible for HMR it also needs the __hmrId option // to be set so that its instances can be registered / removed. if ((false)) {} const map = new Map(); function registerHMR(instance) { const id = instance.type.__hmrId; let record = map.get(id); if (!record) { createRecord(id, instance.type); record = map.get(id); } record.instances.add(instance); } function unregisterHMR(instance) { map.get(instance.type.__hmrId).instances.delete(instance); } function createRecord(id, initialDef) { if (map.has(id)) { return false; } map.set(id, { initialDef: normalizeClassComponent(initialDef), instances: new Set() }); return true; } function normalizeClassComponent(component) { return isClassComponent(component) ? component.__vccOpts : component; } function rerender(id, newRender) { const record = map.get(id); if (!record) { return; } // update initial record (for not-yet-rendered component) record.initialDef.render = newRender; [...record.instances].forEach(instance => { if (newRender) { instance.render = newRender; normalizeClassComponent(instance.type).render = newRender; } instance.renderCache = []; // this flag forces child components with slot content to update isHmrUpdating = true; instance.update(); isHmrUpdating = false; }); } function reload(id, newComp) { const record = map.get(id); if (!record) return; newComp = normalizeClassComponent(newComp); // update initial def (for not-yet-rendered components) updateComponentDef(record.initialDef, newComp); // create a snapshot which avoids the set being mutated during updates const instances = [...record.instances]; for (const instance of instances) { const oldComp = normalizeClassComponent(instance.type); if (!hmrDirtyComponents.has(oldComp)) { // 1. Update existing comp definition to match new one if (oldComp !== record.initialDef) { updateComponentDef(oldComp, newComp); } // 2. mark definition dirty. This forces the renderer to replace the // component on patch. hmrDirtyComponents.add(oldComp); } // 3. invalidate options resolution cache instance.appContext.optionsCache.delete(instance.type); // 4. actually update if (instance.ceReload) { // custom element hmrDirtyComponents.add(oldComp); instance.ceReload(newComp.styles); hmrDirtyComponents.delete(oldComp); } else if (instance.parent) { // 4. Force the parent instance to re-render. This will cause all updated // components to be unmounted and re-mounted. Queue the update so that we // don't end up forcing the same parent to re-render multiple times. queueJob(instance.parent.update); // instance is the inner component of an async custom element // invoke to reset styles if (instance.parent.type.__asyncLoader && instance.parent.ceReload) { instance.parent.ceReload(newComp.styles); } } else if (instance.appContext.reload) { // root instance mounted via createApp() has a reload method instance.appContext.reload(); } else if (typeof window !== 'undefined') { // root instance inside tree created via raw render(). Force reload. window.location.reload(); } else { console.warn('[HMR] Root or manually mounted instance modified. Full reload required.'); } } // 5. make sure to cleanup dirty hmr components after update queuePostFlushCb(() => { for (const instance of instances) { hmrDirtyComponents.delete(normalizeClassComponent(instance.type)); } }); } function updateComponentDef(oldComp, newComp) { extend(oldComp, newComp); for (const key in oldComp) { if (key !== '__file' && !(key in newComp)) { delete oldComp[key]; } } } function tryWrap(fn) { return (id, arg) => { try { return fn(id, arg); } catch (e) { console.error(e); console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` + `Full reload required.`); } }; } let devtools; let buffer = []; let devtoolsNotInstalled = false; function emit(event, ...args) { if (devtools) { devtools.emit(event, ...args); } else if (!devtoolsNotInstalled) { buffer.push({ event, args }); } } function setDevtoolsHook(hook, target) { var _a, _b; devtools = hook; if (devtools) { devtools.enabled = true; buffer.forEach(({ event, args }) => devtools.emit(event, ...args)); buffer = []; } else if ( // handle late devtools injection - only do this if we are in an actual // browser environment to avoid the timer handle stalling test runner exit // (#4815) // eslint-disable-next-line no-restricted-globals typeof window !== 'undefined' && // some envs mock window but not fully window.HTMLElement && // also exclude jsdom !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) { const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []); replay.push((newHook) => { setDevtoolsHook(newHook, target); }); // clear buffer after 3s - the user probably doesn't have devtools installed // at all, and keeping the buffer will cause memory leaks (#4738) setTimeout(() => { if (!devtools) { target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; devtoolsNotInstalled = true; buffer = []; } }, 3000); } else { // non-browser env, assume not installed devtoolsNotInstalled = true; buffer = []; } } function devtoolsInitApp(app, version) { emit("app:init" /* APP_INIT */, app, version, { Fragment, Text, Comment, Static }); } function devtoolsUnmountApp(app) { emit("app:unmount" /* APP_UNMOUNT */, app); } const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */); const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */); const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */); function createDevtoolsComponentHook(hook) { return (component) => { emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); }; } const devtoolsPerfStart = /*#__PURE__*/ (/* unused pure expression or super */ null && (createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */))); const devtoolsPerfEnd = /*#__PURE__*/ (/* unused pure expression or super */ null && (createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */))); function createDevtoolsPerformanceHook(hook) { return (component, type, time) => { emit(hook, component.appContext.app, component.uid, component, type, time); }; } function devtoolsComponentEmit(component, event, params) { emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); } function emit$1(instance, event, ...rawArgs) { const props = instance.vnode.props || shared_esm_bundler.EMPTY_OBJ; if ((false)) {} let args = rawArgs; const isModelListener = event.startsWith('update:'); // for v-model update:xxx events, apply modifiers on args const modelArg = isModelListener && event.slice(7); if (modelArg && modelArg in props) { const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`; const { number, trim } = props[modifiersKey] || shared_esm_bundler.EMPTY_OBJ; if (trim) { args = rawArgs.map(a => a.trim()); } else if (number) { args = rawArgs.map(shared_esm_bundler.toNumber); } } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentEmit(instance, event, args); } if ((false)) {} let handlerName; let handler = props[(handlerName = (0,shared_esm_bundler.toHandlerKey)(event))] || // also try camelCase event handler (#2249) props[(handlerName = (0,shared_esm_bundler.toHandlerKey)((0,shared_esm_bundler.camelize)(event)))]; // for v-model update:xxx events, also trigger kebab-case equivalent // for props passed via kebab-case if (!handler && isModelListener) { handler = props[(handlerName = (0,shared_esm_bundler.toHandlerKey)((0,shared_esm_bundler.hyphenate)(event)))]; } if (handler) { callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); } const onceHandler = props[handlerName + `Once`]; if (onceHandler) { if (!instance.emitted) { instance.emitted = {}; } else if (instance.emitted[handlerName]) { return; } instance.emitted[handlerName] = true; callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); } } function normalizeEmitsOptions(comp, appContext, asMixin = false) { const cache = appContext.emitsCache; const cached = cache.get(comp); if (cached !== undefined) { return cached; } const raw = comp.emits; let normalized = {}; // apply mixin/extends props let hasExtends = false; if (__VUE_OPTIONS_API__ && !(0,shared_esm_bundler.isFunction)(comp)) { const extendEmits = (raw) => { const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); if (normalizedFromExtend) { hasExtends = true; (0,shared_esm_bundler.extend)(normalized, normalizedFromExtend); } }; if (!asMixin && appContext.mixins.length) { appContext.mixins.forEach(extendEmits); } if (comp.extends) { extendEmits(comp.extends); } if (comp.mixins) { comp.mixins.forEach(extendEmits); } } if (!raw && !hasExtends) { cache.set(comp, null); return null; } if ((0,shared_esm_bundler.isArray)(raw)) { raw.forEach(key => (normalized[key] = null)); } else { (0,shared_esm_bundler.extend)(normalized, raw); } cache.set(comp, normalized); return normalized; } // Check if an incoming prop key is a declared emit event listener. // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are // both considered matched listeners. function isEmitListener(options, key) { if (!options || !(0,shared_esm_bundler.isOn)(key)) { return false; } key = key.slice(2).replace(/Once$/, ''); return ((0,shared_esm_bundler.hasOwn)(options, key[0].toLowerCase() + key.slice(1)) || (0,shared_esm_bundler.hasOwn)(options, (0,shared_esm_bundler.hyphenate)(key)) || (0,shared_esm_bundler.hasOwn)(options, key)); } /** * mark the current rendering instance for asset resolution (e.g. * resolveComponent, resolveDirective) during render */ let currentRenderingInstance = null; let currentScopeId = null; /** * Note: rendering calls maybe nested. The function returns the parent rendering * instance if present, which should be restored after the render is done: * * ```js * const prev = setCurrentRenderingInstance(i) * // ...render * setCurrentRenderingInstance(prev) * ``` */ function setCurrentRenderingInstance(instance) { const prev = currentRenderingInstance; currentRenderingInstance = instance; currentScopeId = (instance && instance.type.__scopeId) || null; return prev; } /** * Set scope id when creating hoisted vnodes. * @private compiler helper */ function pushScopeId(id) { currentScopeId = id; } /** * Technically we no longer need this after 3.0.8 but we need to keep the same * API for backwards compat w/ code generated by compilers. * @private */ function popScopeId() { currentScopeId = null; } /** * Only for backwards compat * @private */ const withScopeId = (_id) => withCtx; /** * Wrap a slot function to memoize current rendering instance * @private compiler helper */ function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only ) { if (!ctx) return fn; // already normalized if (fn._n) { return fn; } const renderFnWithContext = (...args) => { // If a user calls a compiled slot inside a template expression (#1745), it // can mess up block tracking, so by default we disable block tracking and // force bail out when invoking a compiled slot (indicated by the ._d flag). // This isn't necessary if rendering a compiled `<slot>`, so we flip the // ._d flag off when invoking the wrapped fn inside `renderSlot`. if (renderFnWithContext._d) { setBlockTracking(-1); } const prevInstance = setCurrentRenderingInstance(ctx); const res = fn(...args); setCurrentRenderingInstance(prevInstance); if (renderFnWithContext._d) { setBlockTracking(1); } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentUpdated(ctx); } return res; }; // mark normalized to avoid duplicated wrapping renderFnWithContext._n = true; // mark this as compiled by default // this is used in vnode.ts -> normalizeChildren() to set the slot // rendering flag. renderFnWithContext._c = true; // disable block tracking by default renderFnWithContext._d = true; return renderFnWithContext; } /** * dev only flag to track whether $attrs was used during render. * If $attrs was used during render then the warning for failed attrs * fallthrough can be suppressed. */ let accessedAttrs = false; function markAttrsAccessed() { accessedAttrs = true; } function renderComponentRoot(instance) { const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance; let result; let fallthroughAttrs; const prev = setCurrentRenderingInstance(instance); if ((false)) {} try { if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { // withProxy is a proxy with a different `has` trap only for // runtime-compiled render functions using `with` block. const proxyToUse = withProxy || proxy; result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); fallthroughAttrs = attrs; } else { // functional const render = Component; // in dev, mark attrs accessed if optional props (attrs === props) if (false) {} result = normalizeVNode(render.length > 1 ? render(props, ( false) ? 0 : { attrs, slots, emit }) : render(props, null /* we know it doesn't need it */)); fallthroughAttrs = Component.props ? attrs : getFunctionalFallthrough(attrs); } } catch (err) { blockStack.length = 0; handleError(err, instance, 1 /* RENDER_FUNCTION */); result = createVNode(Comment); } // attr merging // in dev mode, comments are preserved, and it's possible for a template // to have comments along side the root element which makes it a fragment let root = result; let setRoot = undefined; if (false /* DEV_ROOT_FRAGMENT */) {} if (fallthroughAttrs && inheritAttrs !== false) { const keys = Object.keys(fallthroughAttrs); const { shapeFlag } = root; if (keys.length) { if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) { if (propsOptions && keys.some(shared_esm_bundler.isModelListener)) { // If a v-model listener (onUpdate:xxx) has a corresponding declared // prop, it indicates this component expects to handle v-model and // it should not fallthrough. // related: #1543, #1643, #1989 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions); } root = cloneVNode(root, fallthroughAttrs); } else if (false) {} } } // inherit directives if (vnode.dirs) { if (false) {} root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs; } // inherit transition data if (vnode.transition) { if (false) {} root.transition = vnode.transition; } if (false) {} else { result = root; } setCurrentRenderingInstance(prev); return result; } /** * dev only * In dev mode, template root level comments are rendered, which turns the * template into a fragment root, but we need to locate the single element * root for attrs and scope id processing. */ const getChildRoot = (vnode) => { const rawChildren = vnode.children; const dynamicChildren = vnode.dynamicChildren; const childRoot = filterSingleRoot(rawChildren); if (!childRoot) { return [vnode, undefined]; } const index = rawChildren.indexOf(childRoot); const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; const setRoot = (updatedRoot) => { rawChildren[index] = updatedRoot; if (dynamicChildren) { if (dynamicIndex > -1) { dynamicChildren[dynamicIndex] = updatedRoot; } else if (updatedRoot.patchFlag > 0) { vnode.dynamicChildren = [...dynamicChildren, updatedRoot]; } } }; return [normalizeVNode(childRoot), setRoot]; }; function filterSingleRoot(children) { let singleRoot; for (let i = 0; i < children.length; i++) { const child = children[i]; if (isVNode(child)) { // ignore user comment if (child.type !== Comment || child.children === 'v-if') { if (singleRoot) { // has more than 1 non-comment child, return now return; } else { singleRoot = child; } } } else { return; } } return singleRoot; } const getFunctionalFallthrough = (attrs) => { let res; for (const key in attrs) { if (key === 'class' || key === 'style' || (0,shared_esm_bundler.isOn)(key)) { (res || (res = {}))[key] = attrs[key]; } } return res; }; const filterModelListeners = (attrs, props) => { const res = {}; for (const key in attrs) { if (!(0,shared_esm_bundler.isModelListener)(key) || !(key.slice(9) in props)) { res[key] = attrs[key]; } } return res; }; const isElementRoot = (vnode) => { return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) || vnode.type === Comment // potential v-if branch switch ); }; function shouldUpdateComponent(prevVNode, nextVNode, optimized) { const { props: prevProps, children: prevChildren, component } = prevVNode; const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; const emits = component.emitsOptions; // Parent component's render function was hot-updated. Since this may have // caused the child component's slots content to have changed, we need to // force the child to update as well. if (false) {} // force child update for runtime directive or transition on component vnode. if (nextVNode.dirs || nextVNode.transition) { return true; } if (optimized && patchFlag >= 0) { if (patchFlag & 1024 /* DYNAMIC_SLOTS */) { // slot content that references values that might have changed, // e.g. in a v-for return true; } if (patchFlag & 16 /* FULL_PROPS */) { if (!prevProps) { return !!nextProps; } // presence of this flag indicates props are always non-null return hasPropsChanged(prevProps, nextProps, emits); } else if (patchFlag & 8 /* PROPS */) { const dynamicProps = nextVNode.dynamicProps; for (let i = 0; i < dynamicProps.length; i++) { const key = dynamicProps[i]; if (nextProps[key] !== prevProps[key] && !isEmitListener(emits, key)) { return true; } } } } else { // this path is only taken by manually written render functions // so presence of any children leads to a forced update if (prevChildren || nextChildren) { if (!nextChildren || !nextChildren.$stable) { return true; } } if (prevProps === nextProps) { return false; } if (!prevProps) { return !!nextProps; } if (!nextProps) { return true; } return hasPropsChanged(prevProps, nextProps, emits); } return false; } function hasPropsChanged(prevProps, nextProps, emitsOptions) { const nextKeys = Object.keys(nextProps); if (nextKeys.length !== Object.keys(prevProps).length) { return true; } for (let i = 0; i < nextKeys.length; i++) { const key = nextKeys[i]; if (nextProps[key] !== prevProps[key] && !isEmitListener(emitsOptions, key)) { return true; } } return false; } function updateHOCHostEl({ vnode, parent }, el // HostNode ) { while (parent && parent.subTree === vnode) { (vnode = parent.vnode).el = el; parent = parent.parent; } } const isSuspense = (type) => type.__isSuspense; // Suspense exposes a component-like API, and is treated like a component // in the compiler, but internally it's a special built-in type that hooks // directly into the renderer. const SuspenseImpl = { name: 'Suspense', // In order to make Suspense tree-shakable, we need to avoid importing it // directly in the renderer. The renderer checks for the __isSuspense flag // on a vnode's type and calls the `process` method, passing in renderer // internals. __isSuspense: true, process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, // platform-specific impl passed from renderer rendererInternals) { if (n1 == null) { mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals); } else { patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals); } }, hydrate: hydrateSuspense, create: createSuspenseBoundary, normalize: normalizeSuspenseChildren }; // Force-casted public typing for h and TSX props inference const Suspense = (SuspenseImpl ); function triggerEvent(vnode, name) { const eventListener = vnode.props && vnode.props[name]; if ((0,shared_esm_bundler.isFunction)(eventListener)) { eventListener(); } } function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) { const { p: patch, o: { createElement } } = rendererInternals; const hiddenContainer = createElement('div'); const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals)); // start mounting the content subtree in an off-dom container patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds); // now check if we have encountered any async deps if (suspense.deps > 0) { // has async // invoke @fallback event triggerEvent(vnode, 'onPending'); triggerEvent(vnode, 'onFallback'); // mount the fallback tree patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, slotScopeIds); setActiveBranch(suspense, vnode.ssFallback); } else { // Suspense has no async deps. Just resolve. suspense.resolve(); } } function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) { const suspense = (n2.suspense = n1.suspense); suspense.vnode = n2; n2.el = n1.el; const newBranch = n2.ssContent; const newFallback = n2.ssFallback; const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense; if (pendingBranch) { suspense.pendingBranch = newBranch; if (isSameVNodeType(newBranch, pendingBranch)) { // same root type but content may have changed. patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); if (suspense.deps <= 0) { suspense.resolve(); } else if (isInFallback) { patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, slotScopeIds, optimized); setActiveBranch(suspense, newFallback); } } else { // toggled before pending tree is resolved suspense.pendingId++; if (isHydrating) { // if toggled before hydration is finished, the current DOM tree is // no longer valid. set it as the active branch so it will be unmounted // when resolved suspense.isHydrating = false; suspense.activeBranch = pendingBranch; } else { unmount(pendingBranch, parentComponent, suspense); } // increment pending ID. this is used to invalidate async callbacks // reset suspense state suspense.deps = 0; // discard effects from pending branch suspense.effects.length = 0; // discard previous container suspense.hiddenContainer = createElement('div'); if (isInFallback) { // already in fallback state patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); if (suspense.deps <= 0) { suspense.resolve(); } else { patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, slotScopeIds, optimized); setActiveBranch(suspense, newFallback); } } else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { // toggled "back" to current active branch patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized); // force resolve suspense.resolve(true); } else { // switched to a 3rd branch patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); if (suspense.deps <= 0) { suspense.resolve(); } } } } else { if (activeBranch && isSameVNodeType(newBranch, activeBranch)) { // root did not change, just normal patch patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized); setActiveBranch(suspense, newBranch); } else { // root node toggled // invoke @pending event triggerEvent(n2, 'onPending'); // mount pending branch in off-dom container suspense.pendingBranch = newBranch; suspense.pendingId++; patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); if (suspense.deps <= 0) { // incoming branch has no async deps, resolve now. suspense.resolve(); } else { const { timeout, pendingId } = suspense; if (timeout > 0) { setTimeout(() => { if (suspense.pendingId === pendingId) { suspense.fallback(newFallback); } }, timeout); } else if (timeout === 0) { suspense.fallback(newFallback); } } } } } let hasWarned = false; function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) { /* istanbul ignore if */ if (false) {} const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals; const timeout = (0,shared_esm_bundler.toNumber)(vnode.props && vnode.props.timeout); const suspense = { vnode, parent, parentComponent, isSVG, container, hiddenContainer, anchor, deps: 0, pendingId: 0, timeout: typeof timeout === 'number' ? timeout : -1, activeBranch: null, pendingBranch: null, isInFallback: true, isHydrating, isUnmounted: false, effects: [], resolve(resume = false) { if ((false)) {} const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense; if (suspense.isHydrating) { suspense.isHydrating = false; } else if (!resume) { const delayEnter = activeBranch && pendingBranch.transition && pendingBranch.transition.mode === 'out-in'; if (delayEnter) { activeBranch.transition.afterLeave = () => { if (pendingId === suspense.pendingId) { move(pendingBranch, container, anchor, 0 /* ENTER */); } }; } // this is initial anchor on mount let { anchor } = suspense; // unmount current active tree if (activeBranch) { // if the fallback tree was mounted, it may have been moved // as part of a parent suspense. get the latest anchor for insertion anchor = next(activeBranch); unmount(activeBranch, parentComponent, suspense, true); } if (!delayEnter) { // move content from off-dom container to actual container move(pendingBranch, container, anchor, 0 /* ENTER */); } } setActiveBranch(suspense, pendingBranch); suspense.pendingBranch = null; suspense.isInFallback = false; // flush buffered effects // check if there is a pending parent suspense let parent = suspense.parent; let hasUnresolvedAncestor = false; while (parent) { if (parent.pendingBranch) { // found a pending parent suspense, merge buffered post jobs // into that parent parent.effects.push(...effects); hasUnresolvedAncestor = true; break; } parent = parent.parent; } // no pending parent suspense, flush all jobs if (!hasUnresolvedAncestor) { queuePostFlushCb(effects); } suspense.effects = []; // invoke @resolve event triggerEvent(vnode, 'onResolve'); }, fallback(fallbackVNode) { if (!suspense.pendingBranch) { return; } const { vnode, activeBranch, parentComponent, container, isSVG } = suspense; // invoke @fallback event triggerEvent(vnode, 'onFallback'); const anchor = next(activeBranch); const mountFallback = () => { if (!suspense.isInFallback) { return; } // mount the fallback tree patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, slotScopeIds, optimized); setActiveBranch(suspense, fallbackVNode); }; const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; if (delayEnter) { activeBranch.transition.afterLeave = mountFallback; } suspense.isInFallback = true; // unmount current active branch unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now true // shouldRemove ); if (!delayEnter) { mountFallback(); } }, move(container, anchor, type) { suspense.activeBranch && move(suspense.activeBranch, container, anchor, type); suspense.container = container; }, next() { return suspense.activeBranch && next(suspense.activeBranch); }, registerDep(instance, setupRenderEffect) { const isInPendingSuspense = !!suspense.pendingBranch; if (isInPendingSuspense) { suspense.deps++; } const hydratedEl = instance.vnode.el; instance .asyncDep.catch(err => { handleError(err, instance, 0 /* SETUP_FUNCTION */); }) .then(asyncSetupResult => { // retry when the setup() promise resolves. // component may have been unmounted before resolve. if (instance.isUnmounted || suspense.isUnmounted || suspense.pendingId !== instance.suspenseId) { return; } // retry from this component instance.asyncResolved = true; const { vnode } = instance; if ((false)) {} handleSetupResult(instance, asyncSetupResult, false); if (hydratedEl) { // vnode may have been replaced if an update happened before the // async dep is resolved. vnode.el = hydratedEl; } const placeholder = !hydratedEl && instance.subTree.el; setupRenderEffect(instance, vnode, // component may have been moved before resolve. // if this is not a hydration, instance.subTree will be the comment // placeholder. parentNode(hydratedEl || instance.subTree.el), // anchor will not be used if this is hydration, so only need to // consider the comment placeholder case. hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized); if (placeholder) { remove(placeholder); } updateHOCHostEl(instance, vnode.el); if ((false)) {} // only decrease deps count if suspense is not already resolved if (isInPendingSuspense && --suspense.deps === 0) { suspense.resolve(); } }); }, unmount(parentSuspense, doRemove) { suspense.isUnmounted = true; if (suspense.activeBranch) { unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove); } if (suspense.pendingBranch) { unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove); } } }; return suspense; } function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) { /* eslint-disable no-restricted-globals */ const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */)); // there are two possible scenarios for server-rendered suspense: // - success: ssr content should be fully resolved // - failure: ssr content should be the fallback branch. // however, on the client we don't really know if it has failed or not // attempt to hydrate the DOM assuming it has succeeded, but we still // need to construct a suspense boundary first const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized); if (suspense.deps === 0) { suspense.resolve(); } return result; /* eslint-enable no-restricted-globals */ } function normalizeSuspenseChildren(vnode) { const { shapeFlag, children } = vnode; const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */; vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children); vnode.ssFallback = isSlotChildren ? normalizeSuspenseSlot(children.fallback) : createVNode(Comment); } function normalizeSuspenseSlot(s) { let block; if ((0,shared_esm_bundler.isFunction)(s)) { const trackBlock = isBlockTreeEnabled && s._c; if (trackBlock) { // disableTracking: false // allow block tracking for compiled slots // (see ./componentRenderContext.ts) s._d = false; openBlock(); } s = s(); if (trackBlock) { s._d = true; block = currentBlock; closeBlock(); } } if ((0,shared_esm_bundler.isArray)(s)) { const singleChild = filterSingleRoot(s); if (false) {} s = singleChild; } s = normalizeVNode(s); if (block && !s.dynamicChildren) { s.dynamicChildren = block.filter(c => c !== s); } return s; } function queueEffectWithSuspense(fn, suspense) { if (suspense && suspense.pendingBranch) { if ((0,shared_esm_bundler.isArray)(fn)) { suspense.effects.push(...fn); } else { suspense.effects.push(fn); } } else { queuePostFlushCb(fn); } } function setActiveBranch(suspense, branch) { suspense.activeBranch = branch; const { vnode, parentComponent } = suspense; const el = (vnode.el = branch.el); // in case suspense is the root node of a component, // recursively update the HOC el if (parentComponent && parentComponent.subTree === vnode) { parentComponent.vnode.el = el; updateHOCHostEl(parentComponent, el); } } function provide(key, value) { if (!currentInstance) { if ((false)) {} } else { let provides = currentInstance.provides; // by default an instance inherits its parent's provides object // but when it needs to provide values of its own, it creates its // own provides object using parent provides object as prototype. // this way in `inject` we can simply look up injections from direct // parent and let the prototype chain do the work. const parentProvides = currentInstance.parent && currentInstance.parent.provides; if (parentProvides === provides) { provides = currentInstance.provides = Object.create(parentProvides); } // TS doesn't allow symbol as index type provides[key] = value; } } function inject(key, defaultValue, treatDefaultAsFactory = false) { // fallback to `currentRenderingInstance` so that this can be called in // a functional component const instance = currentInstance || currentRenderingInstance; if (instance) { // #2400 // to support `app.use` plugins, // fallback to appContext's `provides` if the intance is at root const provides = instance.parent == null ? instance.vnode.appContext && instance.vnode.appContext.provides : instance.parent.provides; if (provides && key in provides) { // TS doesn't allow symbol as index type return provides[key]; } else if (arguments.length > 1) { return treatDefaultAsFactory && (0,shared_esm_bundler.isFunction)(defaultValue) ? defaultValue.call(instance.proxy) : defaultValue; } else if ((false)) {} } else if ((false)) {} } function useTransitionState() { const state = { isMounted: false, isLeaving: false, isUnmounting: false, leavingVNodes: new Map() }; onMounted(() => { state.isMounted = true; }); onBeforeUnmount(() => { state.isUnmounting = true; }); return state; } const TransitionHookValidator = [Function, Array]; const BaseTransitionImpl = { name: `BaseTransition`, props: { mode: String, appear: Boolean, persisted: Boolean, // enter onBeforeEnter: TransitionHookValidator, onEnter: TransitionHookValidator, onAfterEnter: TransitionHookValidator, onEnterCancelled: TransitionHookValidator, // leave onBeforeLeave: TransitionHookValidator, onLeave: TransitionHookValidator, onAfterLeave: TransitionHookValidator, onLeaveCancelled: TransitionHookValidator, // appear onBeforeAppear: TransitionHookValidator, onAppear: TransitionHookValidator, onAfterAppear: TransitionHookValidator, onAppearCancelled: TransitionHookValidator }, setup(props, { slots }) { const instance = getCurrentInstance(); const state = useTransitionState(); let prevTransitionKey; return () => { const children = slots.default && getTransitionRawChildren(slots.default(), true); if (!children || !children.length) { return; } // warn multiple elements if (false) {} // there's no need to track reactivity for these props so use the raw // props for a bit better perf const rawProps = reactivity_esm_bundler_toRaw(props); const { mode } = rawProps; // check mode if (false) {} // at this point children has a guaranteed length of 1. const child = children[0]; if (state.isLeaving) { return emptyPlaceholder(child); } // in the case of <transition><keep-alive/></transition>, we need to // compare the type of the kept-alive children. const innerChild = getKeepAliveChild(child); if (!innerChild) { return emptyPlaceholder(child); } const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); setTransitionHooks(innerChild, enterHooks); const oldChild = instance.subTree; const oldInnerChild = oldChild && getKeepAliveChild(oldChild); let transitionKeyChanged = false; const { getTransitionKey } = innerChild.type; if (getTransitionKey) { const key = getTransitionKey(); if (prevTransitionKey === undefined) { prevTransitionKey = key; } else if (key !== prevTransitionKey) { prevTransitionKey = key; transitionKeyChanged = true; } } // handle mode if (oldInnerChild && oldInnerChild.type !== Comment && (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); // update old tree's hooks in case of dynamic transition setTransitionHooks(oldInnerChild, leavingHooks); // switching between different views if (mode === 'out-in') { state.isLeaving = true; // return placeholder node and queue update when leave finishes leavingHooks.afterLeave = () => { state.isLeaving = false; instance.update(); }; return emptyPlaceholder(child); } else if (mode === 'in-out' && innerChild.type !== Comment) { leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; // early removal callback el._leaveCb = () => { earlyRemove(); el._leaveCb = undefined; delete enterHooks.delayedLeave; }; enterHooks.delayedLeave = delayedLeave; }; } } return child; }; } }; // export the public type for h/tsx inference // also to avoid inline import() in generated d.ts files const BaseTransition = BaseTransitionImpl; function getLeavingNodesForType(state, vnode) { const { leavingVNodes } = state; let leavingVNodesCache = leavingVNodes.get(vnode.type); if (!leavingVNodesCache) { leavingVNodesCache = Object.create(null); leavingVNodes.set(vnode.type, leavingVNodesCache); } return leavingVNodesCache; } // The transition hooks are attached to the vnode as vnode.transition // and will be called at appropriate timing in the renderer. function resolveTransitionHooks(vnode, props, state, instance) { const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props; const key = String(vnode.key); const leavingVNodesCache = getLeavingNodesForType(state, vnode); const callHook = (hook, args) => { hook && callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args); }; const hooks = { mode, persisted, beforeEnter(el) { let hook = onBeforeEnter; if (!state.isMounted) { if (appear) { hook = onBeforeAppear || onBeforeEnter; } else { return; } } // for same element (v-show) if (el._leaveCb) { el._leaveCb(true /* cancelled */); } // for toggled element with same key (v-if) const leavingVNode = leavingVNodesCache[key]; if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el._leaveCb) { // force early removal (not cancelled) leavingVNode.el._leaveCb(); } callHook(hook, [el]); }, enter(el) { let hook = onEnter; let afterHook = onAfterEnter; let cancelHook = onEnterCancelled; if (!state.isMounted) { if (appear) { hook = onAppear || onEnter; afterHook = onAfterAppear || onAfterEnter; cancelHook = onAppearCancelled || onEnterCancelled; } else { return; } } let called = false; const done = (el._enterCb = (cancelled) => { if (called) return; called = true; if (cancelled) { callHook(cancelHook, [el]); } else { callHook(afterHook, [el]); } if (hooks.delayedLeave) { hooks.delayedLeave(); } el._enterCb = undefined; }); if (hook) { hook(el, done); if (hook.length <= 1) { done(); } } else { done(); } }, leave(el, remove) { const key = String(vnode.key); if (el._enterCb) { el._enterCb(true /* cancelled */); } if (state.isUnmounting) { return remove(); } callHook(onBeforeLeave, [el]); let called = false; const done = (el._leaveCb = (cancelled) => { if (called) return; called = true; remove(); if (cancelled) { callHook(onLeaveCancelled, [el]); } else { callHook(onAfterLeave, [el]); } el._leaveCb = undefined; if (leavingVNodesCache[key] === vnode) { delete leavingVNodesCache[key]; } }); leavingVNodesCache[key] = vnode; if (onLeave) { onLeave(el, done); if (onLeave.length <= 1) { done(); } } else { done(); } }, clone(vnode) { return resolveTransitionHooks(vnode, props, state, instance); } }; return hooks; } // the placeholder really only handles one special case: KeepAlive // in the case of a KeepAlive in a leave phase we need to return a KeepAlive // placeholder with empty content to avoid the KeepAlive instance from being // unmounted. function emptyPlaceholder(vnode) { if (isKeepAlive(vnode)) { vnode = cloneVNode(vnode); vnode.children = null; return vnode; } } function getKeepAliveChild(vnode) { return isKeepAlive(vnode) ? vnode.children ? vnode.children[0] : undefined : vnode; } function setTransitionHooks(vnode, hooks) { if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) { setTransitionHooks(vnode.component.subTree, hooks); } else if (vnode.shapeFlag & 128 /* SUSPENSE */) { vnode.ssContent.transition = hooks.clone(vnode.ssContent); vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); } else { vnode.transition = hooks; } } function getTransitionRawChildren(children, keepComment = false) { let ret = []; let keyedFragmentCount = 0; for (let i = 0; i < children.length; i++) { const child = children[i]; // handle fragment children case, e.g. v-for if (child.type === Fragment) { if (child.patchFlag & 128 /* KEYED_FRAGMENT */) keyedFragmentCount++; ret = ret.concat(getTransitionRawChildren(child.children, keepComment)); } // comment placeholders should be skipped, e.g. v-if else if (keepComment || child.type !== Comment) { ret.push(child); } } // #1126 if a transition children list contains multiple sub fragments, these // fragments will be merged into a flat children array. Since each v-for // fragment may contain different static bindings inside, we need to de-op // these children to force full diffs to ensure correct behavior. if (keyedFragmentCount > 1) { for (let i = 0; i < ret.length; i++) { ret[i].patchFlag = -2 /* BAIL */; } } return ret; } // implementation, close to no-op function defineComponent(options) { return (0,shared_esm_bundler.isFunction)(options) ? { setup: options, name: options.name } : options; } const isAsyncWrapper = (i) => !!i.type.__asyncLoader; function defineAsyncComponent(source) { if ((0,shared_esm_bundler.isFunction)(source)) { source = { loader: source }; } const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out suspensible = true, onError: userOnError } = source; let pendingRequest = null; let resolvedComp; let retries = 0; const retry = () => { retries++; pendingRequest = null; return load(); }; const load = () => { let thisRequest; return (pendingRequest || (thisRequest = pendingRequest = loader() .catch(err => { err = err instanceof Error ? err : new Error(String(err)); if (userOnError) { return new Promise((resolve, reject) => { const userRetry = () => resolve(retry()); const userFail = () => reject(err); userOnError(err, userRetry, userFail, retries + 1); }); } else { throw err; } }) .then((comp) => { if (thisRequest !== pendingRequest && pendingRequest) { return pendingRequest; } if (false) {} // interop module default if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { comp = comp.default; } if (false) {} resolvedComp = comp; return comp; }))); }; return defineComponent({ name: 'AsyncComponentWrapper', __asyncLoader: load, get __asyncResolved() { return resolvedComp; }, setup() { const instance = currentInstance; // already resolved if (resolvedComp) { return () => createInnerComp(resolvedComp, instance); } const onError = (err) => { pendingRequest = null; handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */); }; // suspense-controlled or SSR. if ((suspensible && instance.suspense) || (isInSSRComponentSetup)) { return load() .then(comp => { return () => createInnerComp(comp, instance); }) .catch(err => { onError(err); return () => errorComponent ? createVNode(errorComponent, { error: err }) : null; }); } const loaded = ref(false); const error = ref(); const delayed = ref(!!delay); if (delay) { setTimeout(() => { delayed.value = false; }, delay); } if (timeout != null) { setTimeout(() => { if (!loaded.value && !error.value) { const err = new Error(`Async component timed out after ${timeout}ms.`); onError(err); error.value = err; } }, timeout); } load() .then(() => { loaded.value = true; if (instance.parent && isKeepAlive(instance.parent.vnode)) { // parent is keep-alive, force update so the loaded component's // name is taken into account queueJob(instance.parent.update); } }) .catch(err => { onError(err); error.value = err; }); return () => { if (loaded.value && resolvedComp) { return createInnerComp(resolvedComp, instance); } else if (error.value && errorComponent) { return createVNode(errorComponent, { error: error.value }); } else if (loadingComponent && !delayed.value) { return createVNode(loadingComponent); } }; } }); } function createInnerComp(comp, { vnode: { ref, props, children } }) { const vnode = createVNode(comp, props, children); // ensure inner component inherits the async wrapper's ref owner vnode.ref = ref; return vnode; } const isKeepAlive = (vnode) => vnode.type.__isKeepAlive; const KeepAliveImpl = { name: `KeepAlive`, // Marker for special handling inside the renderer. We are not using a === // check directly on KeepAlive in the renderer, because importing it directly // would prevent it from being tree-shaken. __isKeepAlive: true, props: { include: [String, RegExp, Array], exclude: [String, RegExp, Array], max: [String, Number] }, setup(props, { slots }) { const instance = getCurrentInstance(); // KeepAlive communicates with the instantiated renderer via the // ctx where the renderer passes in its internals, // and the KeepAlive instance exposes activate/deactivate implementations. // The whole point of this is to avoid importing KeepAlive directly in the // renderer to facilitate tree-shaking. const sharedContext = instance.ctx; // if the internal renderer is not registered, it indicates that this is server-side rendering, // for KeepAlive, we just need to render its children if (!sharedContext.renderer) { return slots.default; } const cache = new Map(); const keys = new Set(); let current = null; if (( false) || __VUE_PROD_DEVTOOLS__) { instance.__v_cache = cache; } const parentSuspense = instance.suspense; const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext; const storageContainer = createElement('div'); sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { const instance = vnode.component; move(vnode, container, anchor, 0 /* ENTER */, parentSuspense); // in case props have changed patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized); queuePostRenderEffect(() => { instance.isDeactivated = false; if (instance.a) { (0,shared_esm_bundler.invokeArrayFns)(instance.a); } const vnodeHook = vnode.props && vnode.props.onVnodeMounted; if (vnodeHook) { invokeVNodeHook(vnodeHook, instance.parent, vnode); } }, parentSuspense); if (( false) || __VUE_PROD_DEVTOOLS__) { // Update components tree devtoolsComponentAdded(instance); } }; sharedContext.deactivate = (vnode) => { const instance = vnode.component; move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense); queuePostRenderEffect(() => { if (instance.da) { (0,shared_esm_bundler.invokeArrayFns)(instance.da); } const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; if (vnodeHook) { invokeVNodeHook(vnodeHook, instance.parent, vnode); } instance.isDeactivated = true; }, parentSuspense); if (( false) || __VUE_PROD_DEVTOOLS__) { // Update components tree devtoolsComponentAdded(instance); } }; function unmount(vnode) { // reset the shapeFlag so it can be properly unmounted resetShapeFlag(vnode); _unmount(vnode, instance, parentSuspense); } function pruneCache(filter) { cache.forEach((vnode, key) => { const name = getComponentName(vnode.type); if (name && (!filter || !filter(name))) { pruneCacheEntry(key); } }); } function pruneCacheEntry(key) { const cached = cache.get(key); if (!current || cached.type !== current.type) { unmount(cached); } else if (current) { // current active instance should no longer be kept-alive. // we can't unmount it now but it might be later, so reset its flag now. resetShapeFlag(current); } cache.delete(key); keys.delete(key); } // prune cache on include/exclude prop change watch(() => [props.include, props.exclude], ([include, exclude]) => { include && pruneCache(name => matches(include, name)); exclude && pruneCache(name => !matches(exclude, name)); }, // prune post-render after `current` has been updated { flush: 'post', deep: true }); // cache sub tree after render let pendingCacheKey = null; const cacheSubtree = () => { // fix #1621, the pendingCacheKey could be 0 if (pendingCacheKey != null) { cache.set(pendingCacheKey, getInnerChild(instance.subTree)); } }; onMounted(cacheSubtree); onUpdated(cacheSubtree); onBeforeUnmount(() => { cache.forEach(cached => { const { subTree, suspense } = instance; const vnode = getInnerChild(subTree); if (cached.type === vnode.type) { // current instance will be unmounted as part of keep-alive's unmount resetShapeFlag(vnode); // but invoke its deactivated hook here const da = vnode.component.da; da && queuePostRenderEffect(da, suspense); return; } unmount(cached); }); }); return () => { pendingCacheKey = null; if (!slots.default) { return null; } const children = slots.default(); const rawVNode = children[0]; if (children.length > 1) { if ((false)) {} current = null; return children; } else if (!isVNode(rawVNode) || (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) && !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) { current = null; return rawVNode; } let vnode = getInnerChild(rawVNode); const comp = vnode.type; // for async components, name check should be based in its loaded // inner component if available const name = getComponentName(isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp); const { include, exclude, max } = props; if ((include && (!name || !matches(include, name))) || (exclude && name && matches(exclude, name))) { current = vnode; return rawVNode; } const key = vnode.key == null ? comp : vnode.key; const cachedVNode = cache.get(key); // clone vnode if it's reused because we are going to mutate it if (vnode.el) { vnode = cloneVNode(vnode); if (rawVNode.shapeFlag & 128 /* SUSPENSE */) { rawVNode.ssContent = vnode; } } // #1513 it's possible for the returned vnode to be cloned due to attr // fallthrough or scopeId, so the vnode here may not be the final vnode // that is mounted. Instead of caching it directly, we store the pending // key and cache `instance.subTree` (the normalized vnode) in // beforeMount/beforeUpdate hooks. pendingCacheKey = key; if (cachedVNode) { // copy over mounted state vnode.el = cachedVNode.el; vnode.component = cachedVNode.component; if (vnode.transition) { // recursively update transition hooks on subTree setTransitionHooks(vnode, vnode.transition); } // avoid vnode being mounted as fresh vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */; // make this key the freshest keys.delete(key); keys.add(key); } else { keys.add(key); // prune oldest entry if (max && keys.size > parseInt(max, 10)) { pruneCacheEntry(keys.values().next().value); } } // avoid vnode being unmounted vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; current = vnode; return rawVNode; }; } }; // export the public type for h/tsx inference // also to avoid inline import() in generated d.ts files const KeepAlive = KeepAliveImpl; function matches(pattern, name) { if ((0,shared_esm_bundler.isArray)(pattern)) { return pattern.some((p) => matches(p, name)); } else if ((0,shared_esm_bundler.isString)(pattern)) { return pattern.split(',').indexOf(name) > -1; } else if (pattern.test) { return pattern.test(name); } /* istanbul ignore next */ return false; } function onActivated(hook, target) { registerKeepAliveHook(hook, "a" /* ACTIVATED */, target); } function onDeactivated(hook, target) { registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target); } function registerKeepAliveHook(hook, type, target = currentInstance) { // cache the deactivate branch check wrapper for injected hooks so the same // hook can be properly deduped by the scheduler. "__wdc" stands for "with // deactivation check". const wrappedHook = hook.__wdc || (hook.__wdc = () => { // only fire the hook if the target instance is NOT in a deactivated branch. let current = target; while (current) { if (current.isDeactivated) { return; } current = current.parent; } hook(); }); injectHook(type, wrappedHook, target); // In addition to registering it on the target instance, we walk up the parent // chain and register it on all ancestor instances that are keep-alive roots. // This avoids the need to walk the entire component tree when invoking these // hooks, and more importantly, avoids the need to track child components in // arrays. if (target) { let current = target.parent; while (current && current.parent) { if (isKeepAlive(current.parent.vnode)) { injectToKeepAliveRoot(wrappedHook, type, target, current); } current = current.parent; } } } function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { // injectHook wraps the original for error handling, so make sure to remove // the wrapped version. const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); onUnmounted(() => { (0,shared_esm_bundler.remove)(keepAliveRoot[type], injected); }, target); } function resetShapeFlag(vnode) { let shapeFlag = vnode.shapeFlag; if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; } if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */; } vnode.shapeFlag = shapeFlag; } function getInnerChild(vnode) { return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode; } function injectHook(type, hook, target = currentInstance, prepend = false) { if (target) { const hooks = target[type] || (target[type] = []); // cache the error handling wrapper for injected hooks so the same hook // can be properly deduped by the scheduler. "__weh" stands for "with error // handling". const wrappedHook = hook.__weh || (hook.__weh = (...args) => { if (target.isUnmounted) { return; } // disable tracking inside all lifecycle hooks // since they can potentially be called inside effects. pauseTracking(); // Set currentInstance during hook invocation. // This assumes the hook does not synchronously trigger other hooks, which // can only be false when the user does something really funky. setCurrentInstance(target); const res = callWithAsyncErrorHandling(hook, target, type, args); unsetCurrentInstance(); resetTracking(); return res; }); if (prepend) { hooks.unshift(wrappedHook); } else { hooks.push(wrappedHook); } return wrappedHook; } else if ((false)) {} } const createHook = (lifecycle) => (hook, target = currentInstance) => // post-create lifecycle registrations are noops during SSR (except for serverPrefetch) (!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) && injectHook(lifecycle, hook, target); const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */); const onMounted = createHook("m" /* MOUNTED */); const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */); const onUpdated = createHook("u" /* UPDATED */); const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */); const onUnmounted = createHook("um" /* UNMOUNTED */); const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */); const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */); const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */); function onErrorCaptured(hook, target = currentInstance) { injectHook("ec" /* ERROR_CAPTURED */, hook, target); } function createDuplicateChecker() { const cache = Object.create(null); return (type, key) => { if (cache[key]) { runtime_core_esm_bundler_warn(`${type} property "${key}" is already defined in ${cache[key]}.`); } else { cache[key] = type; } }; } let shouldCacheAccess = true; function applyOptions(instance) { const options = resolveMergedOptions(instance); const publicThis = instance.proxy; const ctx = instance.ctx; // do not cache property access on public proxy during state initialization shouldCacheAccess = false; // call beforeCreate first before accessing other options since // the hook may mutate resolved options (#2791) if (options.beforeCreate) { callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */); } const { // state data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, // lifecycle created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch, // public API expose, inheritAttrs, // assets components, directives, filters } = options; const checkDuplicateProperties = ( false) ? 0 : null; if ((false)) {} // options initialization order (to be consistent with Vue 2): // - props (already done outside of this function) // - inject // - methods // - data (deferred since it relies on `this` access) // - computed // - watch (deferred since it relies on `this` access) if (injectOptions) { resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef); } if (methods) { for (const key in methods) { const methodHandler = methods[key]; if ((0,shared_esm_bundler.isFunction)(methodHandler)) { // In dev mode, we use the `createRenderContext` function to define // methods to the proxy target, and those are read-only but // reconfigurable, so it needs to be redefined here if ((false)) {} else { ctx[key] = methodHandler.bind(publicThis); } if ((false)) {} } else if ((false)) {} } } if (dataOptions) { if (false) {} const data = dataOptions.call(publicThis, publicThis); if (false) {} if (!(0,shared_esm_bundler.isObject)(data)) { ( false) && 0; } else { instance.data = reactive(data); if ((false)) {} } } // state initialization complete at this point - start caching access shouldCacheAccess = true; if (computedOptions) { for (const key in computedOptions) { const opt = computedOptions[key]; const get = (0,shared_esm_bundler.isFunction)(opt) ? opt.bind(publicThis, publicThis) : (0,shared_esm_bundler.isFunction)(opt.get) ? opt.get.bind(publicThis, publicThis) : shared_esm_bundler.NOOP; if (false) {} const set = !(0,shared_esm_bundler.isFunction)(opt) && (0,shared_esm_bundler.isFunction)(opt.set) ? opt.set.bind(publicThis) : ( false) ? 0 : shared_esm_bundler.NOOP; const c = computed({ get, set }); Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => c.value, set: v => (c.value = v) }); if ((false)) {} } } if (watchOptions) { for (const key in watchOptions) { createWatcher(watchOptions[key], ctx, publicThis, key); } } if (provideOptions) { const provides = (0,shared_esm_bundler.isFunction)(provideOptions) ? provideOptions.call(publicThis) : provideOptions; Reflect.ownKeys(provides).forEach(key => { provide(key, provides[key]); }); } if (created) { callHook(created, instance, "c" /* CREATED */); } function registerLifecycleHook(register, hook) { if ((0,shared_esm_bundler.isArray)(hook)) { hook.forEach(_hook => register(_hook.bind(publicThis))); } else if (hook) { register(hook.bind(publicThis)); } } registerLifecycleHook(onBeforeMount, beforeMount); registerLifecycleHook(onMounted, mounted); registerLifecycleHook(onBeforeUpdate, beforeUpdate); registerLifecycleHook(onUpdated, updated); registerLifecycleHook(onActivated, activated); registerLifecycleHook(onDeactivated, deactivated); registerLifecycleHook(onErrorCaptured, errorCaptured); registerLifecycleHook(onRenderTracked, renderTracked); registerLifecycleHook(onRenderTriggered, renderTriggered); registerLifecycleHook(onBeforeUnmount, beforeUnmount); registerLifecycleHook(onUnmounted, unmounted); registerLifecycleHook(onServerPrefetch, serverPrefetch); if ((0,shared_esm_bundler.isArray)(expose)) { if (expose.length) { const exposed = instance.exposed || (instance.exposed = {}); expose.forEach(key => { Object.defineProperty(exposed, key, { get: () => publicThis[key], set: val => (publicThis[key] = val) }); }); } else if (!instance.exposed) { instance.exposed = {}; } } // options that are handled when creating the instance but also need to be // applied from mixins if (render && instance.render === shared_esm_bundler.NOOP) { instance.render = render; } if (inheritAttrs != null) { instance.inheritAttrs = inheritAttrs; } // asset options. if (components) instance.components = components; if (directives) instance.directives = directives; } function resolveInjections(injectOptions, ctx, checkDuplicateProperties = shared_esm_bundler.NOOP, unwrapRef = false) { if ((0,shared_esm_bundler.isArray)(injectOptions)) { injectOptions = normalizeInject(injectOptions); } for (const key in injectOptions) { const opt = injectOptions[key]; let injected; if ((0,shared_esm_bundler.isObject)(opt)) { if ('default' in opt) { injected = inject(opt.from || key, opt.default, true /* treat default function as factory */); } else { injected = inject(opt.from || key); } } else { injected = inject(opt); } if (isRef(injected)) { // TODO remove the check in 3.3 if (unwrapRef) { Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => injected.value, set: v => (injected.value = v) }); } else { if ((false)) {} ctx[key] = injected; } } else { ctx[key] = injected; } if ((false)) {} } } function callHook(hook, instance, type) { callWithAsyncErrorHandling((0,shared_esm_bundler.isArray)(hook) ? hook.map(h => h.bind(instance.proxy)) : hook.bind(instance.proxy), instance, type); } function createWatcher(raw, ctx, publicThis, key) { const getter = key.includes('.') ? createPathGetter(publicThis, key) : () => publicThis[key]; if ((0,shared_esm_bundler.isString)(raw)) { const handler = ctx[raw]; if ((0,shared_esm_bundler.isFunction)(handler)) { watch(getter, handler); } else if ((false)) {} } else if ((0,shared_esm_bundler.isFunction)(raw)) { watch(getter, raw.bind(publicThis)); } else if ((0,shared_esm_bundler.isObject)(raw)) { if ((0,shared_esm_bundler.isArray)(raw)) { raw.forEach(r => createWatcher(r, ctx, publicThis, key)); } else { const handler = (0,shared_esm_bundler.isFunction)(raw.handler) ? raw.handler.bind(publicThis) : ctx[raw.handler]; if ((0,shared_esm_bundler.isFunction)(handler)) { watch(getter, handler, raw); } else if ((false)) {} } } else if ((false)) {} } /** * Resolve merged options and cache it on the component. * This is done only once per-component since the merging does not involve * instances. */ function resolveMergedOptions(instance) { const base = instance.type; const { mixins, extends: extendsOptions } = base; const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext; const cached = cache.get(base); let resolved; if (cached) { resolved = cached; } else if (!globalMixins.length && !mixins && !extendsOptions) { { resolved = base; } } else { resolved = {}; if (globalMixins.length) { globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true)); } mergeOptions(resolved, base, optionMergeStrategies); } cache.set(base, resolved); return resolved; } function mergeOptions(to, from, strats, asMixin = false) { const { mixins, extends: extendsOptions } = from; if (extendsOptions) { mergeOptions(to, extendsOptions, strats, true); } if (mixins) { mixins.forEach((m) => mergeOptions(to, m, strats, true)); } for (const key in from) { if (asMixin && key === 'expose') { ( false) && 0; } else { const strat = internalOptionMergeStrats[key] || (strats && strats[key]); to[key] = strat ? strat(to[key], from[key]) : from[key]; } } return to; } const internalOptionMergeStrats = { data: mergeDataFn, props: mergeObjectOptions, emits: mergeObjectOptions, // objects methods: mergeObjectOptions, computed: mergeObjectOptions, // lifecycle beforeCreate: mergeAsArray, created: mergeAsArray, beforeMount: mergeAsArray, mounted: mergeAsArray, beforeUpdate: mergeAsArray, updated: mergeAsArray, beforeDestroy: mergeAsArray, beforeUnmount: mergeAsArray, destroyed: mergeAsArray, unmounted: mergeAsArray, activated: mergeAsArray, deactivated: mergeAsArray, errorCaptured: mergeAsArray, serverPrefetch: mergeAsArray, // assets components: mergeObjectOptions, directives: mergeObjectOptions, // watch watch: mergeWatchOptions, // provide / inject provide: mergeDataFn, inject: mergeInject }; function mergeDataFn(to, from) { if (!from) { return to; } if (!to) { return from; } return function mergedDataFn() { return ((0,shared_esm_bundler.extend))((0,shared_esm_bundler.isFunction)(to) ? to.call(this, this) : to, (0,shared_esm_bundler.isFunction)(from) ? from.call(this, this) : from); }; } function mergeInject(to, from) { return mergeObjectOptions(normalizeInject(to), normalizeInject(from)); } function normalizeInject(raw) { if ((0,shared_esm_bundler.isArray)(raw)) { const res = {}; for (let i = 0; i < raw.length; i++) { res[raw[i]] = raw[i]; } return res; } return raw; } function mergeAsArray(to, from) { return to ? [...new Set([].concat(to, from))] : from; } function mergeObjectOptions(to, from) { return to ? (0,shared_esm_bundler.extend)((0,shared_esm_bundler.extend)(Object.create(null), to), from) : from; } function mergeWatchOptions(to, from) { if (!to) return from; if (!from) return to; const merged = (0,shared_esm_bundler.extend)(Object.create(null), to); for (const key in from) { merged[key] = mergeAsArray(to[key], from[key]); } return merged; } function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison isSSR = false) { const props = {}; const attrs = {}; (0,shared_esm_bundler.def)(attrs, InternalObjectKey, 1); instance.propsDefaults = Object.create(null); setFullProps(instance, rawProps, props, attrs); // ensure all declared prop keys are present for (const key in instance.propsOptions[0]) { if (!(key in props)) { props[key] = undefined; } } // validation if ((false)) {} if (isStateful) { // stateful instance.props = isSSR ? props : shallowReactive(props); } else { if (!instance.type.props) { // functional w/ optional props, props === attrs instance.props = attrs; } else { // functional w/ declared props instance.props = props; } } instance.attrs = attrs; } function updateProps(instance, rawProps, rawPrevProps, optimized) { const { props, attrs, vnode: { patchFlag } } = instance; const rawCurrentProps = reactivity_esm_bundler_toRaw(props); const [options] = instance.propsOptions; let hasAttrsChanged = false; if ( // always force full diff in dev // - #1942 if hmr is enabled with sfc component // - vite#872 non-sfc component used by sfc component true && (optimized || patchFlag > 0) && !(patchFlag & 16 /* FULL_PROPS */)) { if (patchFlag & 8 /* PROPS */) { // Compiler-generated props & no keys change, just set the updated // the props. const propsToUpdate = instance.vnode.dynamicProps; for (let i = 0; i < propsToUpdate.length; i++) { let key = propsToUpdate[i]; // PROPS flag guarantees rawProps to be non-null const value = rawProps[key]; if (options) { // attr / props separation was done on init and will be consistent // in this code path, so just check if attrs have it. if ((0,shared_esm_bundler.hasOwn)(attrs, key)) { if (value !== attrs[key]) { attrs[key] = value; hasAttrsChanged = true; } } else { const camelizedKey = (0,shared_esm_bundler.camelize)(key); props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */); } } else { if (value !== attrs[key]) { attrs[key] = value; hasAttrsChanged = true; } } } } } else { // full props update. if (setFullProps(instance, rawProps, props, attrs)) { hasAttrsChanged = true; } // in case of dynamic props, check if we need to delete keys from // the props object let kebabKey; for (const key in rawCurrentProps) { if (!rawProps || // for camelCase (!(0,shared_esm_bundler.hasOwn)(rawProps, key) && // it's possible the original props was passed in as kebab-case // and converted to camelCase (#955) ((kebabKey = (0,shared_esm_bundler.hyphenate)(key)) === key || !(0,shared_esm_bundler.hasOwn)(rawProps, kebabKey)))) { if (options) { if (rawPrevProps && // for camelCase (rawPrevProps[key] !== undefined || // for kebab-case rawPrevProps[kebabKey] !== undefined)) { props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */); } } else { delete props[key]; } } } // in the case of functional component w/o props declaration, props and // attrs point to the same object so it should already have been updated. if (attrs !== rawCurrentProps) { for (const key in attrs) { if (!rawProps || !(0,shared_esm_bundler.hasOwn)(rawProps, key)) { delete attrs[key]; hasAttrsChanged = true; } } } } // trigger updates for $attrs in case it's used in component slots if (hasAttrsChanged) { trigger(instance, "set" /* SET */, '$attrs'); } if ((false)) {} } function setFullProps(instance, rawProps, props, attrs) { const [options, needCastKeys] = instance.propsOptions; let hasAttrsChanged = false; let rawCastValues; if (rawProps) { for (let key in rawProps) { // key, ref are reserved and never passed down if ((0,shared_esm_bundler.isReservedProp)(key)) { continue; } const value = rawProps[key]; // prop option names are camelized during normalization, so to support // kebab -> camel conversion here we need to camelize the key. let camelKey; if (options && (0,shared_esm_bundler.hasOwn)(options, (camelKey = (0,shared_esm_bundler.camelize)(key)))) { if (!needCastKeys || !needCastKeys.includes(camelKey)) { props[camelKey] = value; } else { (rawCastValues || (rawCastValues = {}))[camelKey] = value; } } else if (!isEmitListener(instance.emitsOptions, key)) { if (value !== attrs[key]) { attrs[key] = value; hasAttrsChanged = true; } } } } if (needCastKeys) { const rawCurrentProps = reactivity_esm_bundler_toRaw(props); const castValues = rawCastValues || shared_esm_bundler.EMPTY_OBJ; for (let i = 0; i < needCastKeys.length; i++) { const key = needCastKeys[i]; props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !(0,shared_esm_bundler.hasOwn)(castValues, key)); } } return hasAttrsChanged; } function resolvePropValue(options, props, key, value, instance, isAbsent) { const opt = options[key]; if (opt != null) { const hasDefault = (0,shared_esm_bundler.hasOwn)(opt, 'default'); // default values if (hasDefault && value === undefined) { const defaultValue = opt.default; if (opt.type !== Function && (0,shared_esm_bundler.isFunction)(defaultValue)) { const { propsDefaults } = instance; if (key in propsDefaults) { value = propsDefaults[key]; } else { setCurrentInstance(instance); value = propsDefaults[key] = defaultValue.call(null, props); unsetCurrentInstance(); } } else { value = defaultValue; } } // boolean casting if (opt[0 /* shouldCast */]) { if (isAbsent && !hasDefault) { value = false; } else if (opt[1 /* shouldCastTrue */] && (value === '' || value === (0,shared_esm_bundler.hyphenate)(key))) { value = true; } } } return value; } function normalizePropsOptions(comp, appContext, asMixin = false) { const cache = appContext.propsCache; const cached = cache.get(comp); if (cached) { return cached; } const raw = comp.props; const normalized = {}; const needCastKeys = []; // apply mixin/extends props let hasExtends = false; if (__VUE_OPTIONS_API__ && !(0,shared_esm_bundler.isFunction)(comp)) { const extendProps = (raw) => { hasExtends = true; const [props, keys] = normalizePropsOptions(raw, appContext, true); (0,shared_esm_bundler.extend)(normalized, props); if (keys) needCastKeys.push(...keys); }; if (!asMixin && appContext.mixins.length) { appContext.mixins.forEach(extendProps); } if (comp.extends) { extendProps(comp.extends); } if (comp.mixins) { comp.mixins.forEach(extendProps); } } if (!raw && !hasExtends) { cache.set(comp, shared_esm_bundler.EMPTY_ARR); return shared_esm_bundler.EMPTY_ARR; } if ((0,shared_esm_bundler.isArray)(raw)) { for (let i = 0; i < raw.length; i++) { if (false) {} const normalizedKey = (0,shared_esm_bundler.camelize)(raw[i]); if (validatePropName(normalizedKey)) { normalized[normalizedKey] = shared_esm_bundler.EMPTY_OBJ; } } } else if (raw) { if (false) {} for (const key in raw) { const normalizedKey = (0,shared_esm_bundler.camelize)(key); if (validatePropName(normalizedKey)) { const opt = raw[key]; const prop = (normalized[normalizedKey] = (0,shared_esm_bundler.isArray)(opt) || (0,shared_esm_bundler.isFunction)(opt) ? { type: opt } : opt); if (prop) { const booleanIndex = getTypeIndex(Boolean, prop.type); const stringIndex = getTypeIndex(String, prop.type); prop[0 /* shouldCast */] = booleanIndex > -1; prop[1 /* shouldCastTrue */] = stringIndex < 0 || booleanIndex < stringIndex; // if the prop needs boolean casting or default value if (booleanIndex > -1 || (0,shared_esm_bundler.hasOwn)(prop, 'default')) { needCastKeys.push(normalizedKey); } } } } } const res = [normalized, needCastKeys]; cache.set(comp, res); return res; } function validatePropName(key) { if (key[0] !== '$') { return true; } else if ((false)) {} return false; } // use function string name to check type constructors // so that it works across vms / iframes. function getType(ctor) { const match = ctor && ctor.toString().match(/^\s*function (\w+)/); return match ? match[1] : ctor === null ? 'null' : ''; } function isSameType(a, b) { return getType(a) === getType(b); } function getTypeIndex(type, expectedTypes) { if ((0,shared_esm_bundler.isArray)(expectedTypes)) { return expectedTypes.findIndex(t => isSameType(t, type)); } else if ((0,shared_esm_bundler.isFunction)(expectedTypes)) { return isSameType(expectedTypes, type) ? 0 : -1; } return -1; } /** * dev only */ function validateProps(rawProps, props, instance) { const resolvedValues = toRaw(props); const options = instance.propsOptions[0]; for (const key in options) { let opt = options[key]; if (opt == null) continue; validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key))); } } /** * dev only */ function validateProp(name, value, prop, isAbsent) { const { type, required, validator } = prop; // required! if (required && isAbsent) { runtime_core_esm_bundler_warn('Missing required prop: "' + name + '"'); return; } // missing but optional if (value == null && !prop.required) { return; } // type check if (type != null && type !== true) { let isValid = false; const types = isArray(type) ? type : [type]; const expectedTypes = []; // value is valid as long as one of the specified types match for (let i = 0; i < types.length && !isValid; i++) { const { valid, expectedType } = assertType(value, types[i]); expectedTypes.push(expectedType || ''); isValid = valid; } if (!isValid) { runtime_core_esm_bundler_warn(getInvalidTypeMessage(name, value, expectedTypes)); return; } } // custom validator if (validator && !validator(value)) { runtime_core_esm_bundler_warn('Invalid prop: custom validator check failed for prop "' + name + '".'); } } const isSimpleType = /*#__PURE__*/ (/* unused pure expression or super */ null && (makeMap('String,Number,Boolean,Function,Symbol,BigInt'))); /** * dev only */ function assertType(value, type) { let valid; const expectedType = getType(type); if (isSimpleType(expectedType)) { const t = typeof value; valid = t === expectedType.toLowerCase(); // for primitive wrapper objects if (!valid && t === 'object') { valid = value instanceof type; } } else if (expectedType === 'Object') { valid = isObject(value); } else if (expectedType === 'Array') { valid = isArray(value); } else if (expectedType === 'null') { valid = value === null; } else { valid = value instanceof type; } return { valid, expectedType }; } /** * dev only */ function getInvalidTypeMessage(name, value, expectedTypes) { let message = `Invalid prop: type check failed for prop "${name}".` + ` Expected ${expectedTypes.map(capitalize).join(' | ')}`; const expectedType = expectedTypes[0]; const receivedType = toRawType(value); const expectedValue = styleValue(value, expectedType); const receivedValue = styleValue(value, receivedType); // check if we need to specify expected value if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { message += ` with value ${expectedValue}`; } message += `, got ${receivedType} `; // check if we need to specify received value if (isExplicable(receivedType)) { message += `with value ${receivedValue}.`; } return message; } /** * dev only */ function styleValue(value, type) { if (type === 'String') { return `"${value}"`; } else if (type === 'Number') { return `${Number(value)}`; } else { return `${value}`; } } /** * dev only */ function isExplicable(type) { const explicitTypes = ['string', 'number', 'boolean']; return explicitTypes.some(elem => type.toLowerCase() === elem); } /** * dev only */ function isBoolean(...args) { return args.some(elem => elem.toLowerCase() === 'boolean'); } const isInternalKey = (key) => key[0] === '_' || key === '$stable'; const normalizeSlotValue = (value) => (0,shared_esm_bundler.isArray)(value) ? value.map(normalizeVNode) : [normalizeVNode(value)]; const normalizeSlot = (key, rawSlot, ctx) => { const normalized = withCtx((...args) => { if (false) {} return normalizeSlotValue(rawSlot(...args)); }, ctx); normalized._c = false; return normalized; }; const normalizeObjectSlots = (rawSlots, slots, instance) => { const ctx = rawSlots._ctx; for (const key in rawSlots) { if (isInternalKey(key)) continue; const value = rawSlots[key]; if ((0,shared_esm_bundler.isFunction)(value)) { slots[key] = normalizeSlot(key, value, ctx); } else if (value != null) { if (false) {} const normalized = normalizeSlotValue(value); slots[key] = () => normalized; } } }; const normalizeVNodeSlots = (instance, children) => { if (false) {} const normalized = normalizeSlotValue(children); instance.slots.default = () => normalized; }; const initSlots = (instance, children) => { if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { const type = children._; if (type) { // users can get the shallow readonly version of the slots object through `this.$slots`, // we should avoid the proxy object polluting the slots of the internal instance instance.slots = reactivity_esm_bundler_toRaw(children); // make compiler marker non-enumerable (0,shared_esm_bundler.def)(children, '_', type); } else { normalizeObjectSlots(children, (instance.slots = {})); } } else { instance.slots = {}; if (children) { normalizeVNodeSlots(instance, children); } } (0,shared_esm_bundler.def)(instance.slots, InternalObjectKey, 1); }; const updateSlots = (instance, children, optimized) => { const { vnode, slots } = instance; let needDeletionCheck = true; let deletionComparisonTarget = shared_esm_bundler.EMPTY_OBJ; if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { const type = children._; if (type) { // compiled slots. if (false) {} else if (optimized && type === 1 /* STABLE */) { // compiled AND stable. // no need to update, and skip stale slots removal. needDeletionCheck = false; } else { // compiled but dynamic (v-if/v-for on slots) - update slots, but skip // normalization. (0,shared_esm_bundler.extend)(slots, children); // #2893 // when rendering the optimized slots by manually written render function, // we need to delete the `slots._` flag if necessary to make subsequent updates reliable, // i.e. let the `renderSlot` create the bailed Fragment if (!optimized && type === 1 /* STABLE */) { delete slots._; } } } else { needDeletionCheck = !children.$stable; normalizeObjectSlots(children, slots); } deletionComparisonTarget = children; } else if (children) { // non slot object children (direct value) passed to a component normalizeVNodeSlots(instance, children); deletionComparisonTarget = { default: 1 }; } // delete stale slots if (needDeletionCheck) { for (const key in slots) { if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { delete slots[key]; } } } }; /** Runtime helper for applying directives to a vnode. Example usage: const comp = resolveComponent('comp') const foo = resolveDirective('foo') const bar = resolveDirective('bar') return withDirectives(h(comp), [ [foo, this.x], [bar, this.y] ]) */ const isBuiltInDirective = /*#__PURE__*/ (/* unused pure expression or super */ null && (makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo'))); function validateDirectiveName(name) { if (isBuiltInDirective(name)) { runtime_core_esm_bundler_warn('Do not use built-in directive ids as custom directive id: ' + name); } } /** * Adds directives to a VNode. */ function withDirectives(vnode, directives) { const internalInstance = currentRenderingInstance; if (internalInstance === null) { ( false) && 0; return vnode; } const instance = internalInstance.proxy; const bindings = vnode.dirs || (vnode.dirs = []); for (let i = 0; i < directives.length; i++) { let [dir, value, arg, modifiers = shared_esm_bundler.EMPTY_OBJ] = directives[i]; if ((0,shared_esm_bundler.isFunction)(dir)) { dir = { mounted: dir, updated: dir }; } if (dir.deep) { traverse(value); } bindings.push({ dir, instance, value, oldValue: void 0, arg, modifiers }); } return vnode; } function invokeDirectiveHook(vnode, prevVNode, instance, name) { const bindings = vnode.dirs; const oldBindings = prevVNode && prevVNode.dirs; for (let i = 0; i < bindings.length; i++) { const binding = bindings[i]; if (oldBindings) { binding.oldValue = oldBindings[i].value; } let hook = binding.dir[name]; if (hook) { // disable tracking inside all lifecycle hooks // since they can potentially be called inside effects. pauseTracking(); callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [ vnode.el, binding, vnode, prevVNode ]); resetTracking(); } } } function createAppContext() { return { app: null, config: { isNativeTag: shared_esm_bundler.NO, performance: false, globalProperties: {}, optionMergeStrategies: {}, errorHandler: undefined, warnHandler: undefined, compilerOptions: {} }, mixins: [], components: {}, directives: {}, provides: Object.create(null), optionsCache: new WeakMap(), propsCache: new WeakMap(), emitsCache: new WeakMap() }; } let uid = 0; function createAppAPI(render, hydrate) { return function createApp(rootComponent, rootProps = null) { if (rootProps != null && !(0,shared_esm_bundler.isObject)(rootProps)) { ( false) && 0; rootProps = null; } const context = createAppContext(); const installedPlugins = new Set(); let isMounted = false; const app = (context.app = { _uid: uid++, _component: rootComponent, _props: rootProps, _container: null, _context: context, _instance: null, version, get config() { return context.config; }, set config(v) { if ((false)) {} }, use(plugin, ...options) { if (installedPlugins.has(plugin)) { ( false) && 0; } else if (plugin && (0,shared_esm_bundler.isFunction)(plugin.install)) { installedPlugins.add(plugin); plugin.install(app, ...options); } else if ((0,shared_esm_bundler.isFunction)(plugin)) { installedPlugins.add(plugin); plugin(app, ...options); } else if ((false)) {} return app; }, mixin(mixin) { if (__VUE_OPTIONS_API__) { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin); } else if ((false)) {} } else if ((false)) {} return app; }, component(name, component) { if ((false)) {} if (!component) { return context.components[name]; } if (false) {} context.components[name] = component; return app; }, directive(name, directive) { if ((false)) {} if (!directive) { return context.directives[name]; } if (false) {} context.directives[name] = directive; return app; }, mount(rootContainer, isHydrate, isSVG) { if (!isMounted) { const vnode = createVNode(rootComponent, rootProps); // store app context on the root VNode. // this will be set on the root instance on initial mount. vnode.appContext = context; // HMR root reload if ((false)) {} if (isHydrate && hydrate) { hydrate(vnode, rootContainer); } else { render(vnode, rootContainer, isSVG); } isMounted = true; app._container = rootContainer; rootContainer.__vue_app__ = app; if (( false) || __VUE_PROD_DEVTOOLS__) { app._instance = vnode.component; devtoolsInitApp(app, version); } return getExposeProxy(vnode.component) || vnode.component.proxy; } else if ((false)) {} }, unmount() { if (isMounted) { render(null, app._container); if (( false) || __VUE_PROD_DEVTOOLS__) { app._instance = null; devtoolsUnmountApp(app); } delete app._container.__vue_app__; } else if ((false)) {} }, provide(key, value) { if (false) {} // TypeScript doesn't allow symbols as index type // https://github.com/Microsoft/TypeScript/issues/24587 context.provides[key] = value; return app; } }); return app; }; } let hasMismatch = false; const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; const isComment = (node) => node.nodeType === 8 /* COMMENT */; // Note: hydration is DOM-specific // But we have to place it in core due to tight coupling with core - splitting // it out creates a ton of unnecessary complexity. // Hydration also depends on some renderer internal logic which needs to be // passed in via arguments. function createHydrationFunctions(rendererInternals) { const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals; const hydrate = (vnode, container) => { if (!container.hasChildNodes()) { ( false) && 0; patch(null, vnode, container); flushPostFlushCbs(); return; } hasMismatch = false; hydrateNode(container.firstChild, vnode, null, null, null); flushPostFlushCbs(); if (hasMismatch && !false) { // this error should show up in production console.error(`Hydration completed but contains mismatches.`); } }; const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => { const isFragmentStart = isComment(node) && node.data === '['; const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart); const { type, ref, shapeFlag } = vnode; const domType = node.nodeType; vnode.el = node; let nextNode = null; switch (type) { case Text: if (domType !== 3 /* TEXT */) { nextNode = onMismatch(); } else { if (node.data !== vnode.children) { hasMismatch = true; ( false) && 0; node.data = vnode.children; } nextNode = nextSibling(node); } break; case Comment: if (domType !== 8 /* COMMENT */ || isFragmentStart) { nextNode = onMismatch(); } else { nextNode = nextSibling(node); } break; case Static: if (domType !== 1 /* ELEMENT */) { nextNode = onMismatch(); } else { // determine anchor, adopt content nextNode = node; // if the static vnode has its content stripped during build, // adopt it from the server-rendered HTML. const needToAdoptContent = !vnode.children.length; for (let i = 0; i < vnode.staticCount; i++) { if (needToAdoptContent) vnode.children += nextNode.outerHTML; if (i === vnode.staticCount - 1) { vnode.anchor = nextNode; } nextNode = nextSibling(nextNode); } return nextNode; } break; case Fragment: if (!isFragmentStart) { nextNode = onMismatch(); } else { nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); } break; default: if (shapeFlag & 1 /* ELEMENT */) { if (domType !== 1 /* ELEMENT */ || vnode.type.toLowerCase() !== node.tagName.toLowerCase()) { nextNode = onMismatch(); } else { nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); } } else if (shapeFlag & 6 /* COMPONENT */) { // when setting up the render effect, if the initial vnode already // has .el set, the component will perform hydration instead of mount // on its sub-tree. vnode.slotScopeIds = slotScopeIds; const container = parentNode(node); mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized); // component may be async, so in the case of fragments we cannot rely // on component's rendered output to determine the end of the fragment // instead, we do a lookahead to find the end anchor node. nextNode = isFragmentStart ? locateClosingAsyncAnchor(node) : nextSibling(node); // #3787 // if component is async, it may get moved / unmounted before its // inner component is loaded, so we need to give it a placeholder // vnode that matches its adopted DOM. if (isAsyncWrapper(vnode)) { let subTree; if (isFragmentStart) { subTree = createVNode(Fragment); subTree.anchor = nextNode ? nextNode.previousSibling : container.lastChild; } else { subTree = node.nodeType === 3 ? createTextVNode('') : createVNode('div'); } subTree.el = node; vnode.component.subTree = subTree; } } else if (shapeFlag & 64 /* TELEPORT */) { if (domType !== 8 /* COMMENT */) { nextNode = onMismatch(); } else { nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren); } } else if (shapeFlag & 128 /* SUSPENSE */) { nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode); } else if ((false)) {} } if (ref != null) { setRef(ref, null, parentSuspense, vnode); } return nextNode; }; const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { optimized = optimized || !!vnode.dynamicChildren; const { type, props, patchFlag, shapeFlag, dirs } = vnode; // #4006 for form elements with non-string v-model value bindings // e.g. <option :value="obj">, <input type="checkbox" :true-value="1"> const forcePatchValue = (type === 'input' && dirs) || type === 'option'; // skip props & children if this is hoisted static nodes if (forcePatchValue || patchFlag !== -1 /* HOISTED */) { if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'created'); } // props if (props) { if (forcePatchValue || !optimized || patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) { for (const key in props) { if ((forcePatchValue && key.endsWith('value')) || ((0,shared_esm_bundler.isOn)(key) && !(0,shared_esm_bundler.isReservedProp)(key))) { patchProp(el, key, null, props[key], false, undefined, parentComponent); } } } else if (props.onClick) { // Fast path for click listeners (which is most often) to avoid // iterating through props. patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent); } } // vnode / directive hooks let vnodeHooks; if ((vnodeHooks = props && props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHooks, parentComponent, vnode); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { queueEffectWithSuspense(() => { vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); }, parentSuspense); } // children if (shapeFlag & 16 /* ARRAY_CHILDREN */ && // skip if element has innerHTML / textContent !(props && (props.innerHTML || props.textContent))) { let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized); let hasWarned = false; while (next) { hasMismatch = true; if (false) {} // The SSRed DOM contains more nodes than it should. Remove them. const cur = next; next = next.nextSibling; remove(cur); } } else if (shapeFlag & 8 /* TEXT_CHILDREN */) { if (el.textContent !== vnode.children) { hasMismatch = true; ( false) && 0; el.textContent = vnode.children; } } } return el.nextSibling; }; const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => { optimized = optimized || !!parentVNode.dynamicChildren; const children = parentVNode.children; const l = children.length; let hasWarned = false; for (let i = 0; i < l; i++) { const vnode = optimized ? children[i] : (children[i] = normalizeVNode(children[i])); if (node) { node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); } else if (vnode.type === Text && !vnode.children) { continue; } else { hasMismatch = true; if (false) {} // the SSRed DOM didn't contain enough nodes. Mount the missing ones. patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); } } return node; }; const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { const { slotScopeIds: fragmentSlotScopeIds } = vnode; if (fragmentSlotScopeIds) { slotScopeIds = slotScopeIds ? slotScopeIds.concat(fragmentSlotScopeIds) : fragmentSlotScopeIds; } const container = parentNode(node); const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized); if (next && isComment(next) && next.data === ']') { return nextSibling((vnode.anchor = next)); } else { // fragment didn't hydrate successfully, since we didn't get a end anchor // back. This should have led to node/children mismatch warnings. hasMismatch = true; // since the anchor is missing, we need to create one and insert it insert((vnode.anchor = createComment(`]`)), container, next); return next; } }; const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => { hasMismatch = true; ( false) && 0; vnode.el = null; if (isFragment) { // remove excessive fragment nodes const end = locateClosingAsyncAnchor(node); while (true) { const next = nextSibling(node); if (next && next !== end) { remove(next); } else { break; } } } const next = nextSibling(node); const container = parentNode(node); remove(node); patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds); return next; }; const locateClosingAsyncAnchor = (node) => { let match = 0; while (node) { node = nextSibling(node); if (node && isComment(node)) { if (node.data === '[') match++; if (node.data === ']') { if (match === 0) { return nextSibling(node); } else { match--; } } } } return node; }; return [hydrate, hydrateNode]; } let supported; let perf; function startMeasure(instance, type) { if (instance.appContext.config.performance && isSupported()) { perf.mark(`vue-${type}-${instance.uid}`); } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsPerfStart(instance, type, supported ? perf.now() : Date.now()); } } function endMeasure(instance, type) { if (instance.appContext.config.performance && isSupported()) { const startTag = `vue-${type}-${instance.uid}`; const endTag = startTag + `:end`; perf.mark(endTag); perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag); perf.clearMarks(startTag); perf.clearMarks(endTag); } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsPerfEnd(instance, type, supported ? perf.now() : Date.now()); } } function isSupported() { if (supported !== undefined) { return supported; } /* eslint-disable no-restricted-globals */ if (typeof window !== 'undefined' && window.performance) { supported = true; perf = window.performance; } else { supported = false; } /* eslint-enable no-restricted-globals */ return supported; } /** * This is only called in esm-bundler builds. * It is called when a renderer is created, in `baseCreateRenderer` so that * importing runtime-core is side-effects free. * * istanbul-ignore-next */ function initFeatureFlags() { const needWarn = []; if (typeof __VUE_OPTIONS_API__ !== 'boolean') { ( false) && 0; (0,shared_esm_bundler.getGlobalThis)().__VUE_OPTIONS_API__ = true; } if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { ( false) && 0; (0,shared_esm_bundler.getGlobalThis)().__VUE_PROD_DEVTOOLS__ = false; } if (false) {} } const queuePostRenderEffect = queueEffectWithSuspense ; /** * The createRenderer function accepts two generic arguments: * HostNode and HostElement, corresponding to Node and Element types in the * host environment. For example, for runtime-dom, HostNode would be the DOM * `Node` interface and HostElement would be the DOM `Element` interface. * * Custom renderers can pass in the platform specific types like this: * * ``` js * const { render, createApp } = createRenderer<Node, Element>({ * patchProp, * ...nodeOps * }) * ``` */ function createRenderer(options) { return baseCreateRenderer(options); } // Separate API for creating hydration-enabled renderer. // Hydration logic is only used when calling this function, making it // tree-shakable. function createHydrationRenderer(options) { return baseCreateRenderer(options, createHydrationFunctions); } // implementation function baseCreateRenderer(options, createHydrationFns) { // compile-time feature flags check { initFeatureFlags(); } const target = (0,shared_esm_bundler.getGlobalThis)(); target.__VUE__ = true; if (( false) || __VUE_PROD_DEVTOOLS__) { setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target); } const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = shared_esm_bundler.NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options; // Note: functions inside this closure should use `const xxx = () => {}` // style in order to prevent being inlined by minifiers. const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = false ? 0 : !!n2.dynamicChildren) => { if (n1 === n2) { return; } // patching & not same type, unmount old tree if (n1 && !isSameVNodeType(n1, n2)) { anchor = getNextHostNode(n1); unmount(n1, parentComponent, parentSuspense, true); n1 = null; } if (n2.patchFlag === -2 /* BAIL */) { optimized = false; n2.dynamicChildren = null; } const { type, ref, shapeFlag } = n2; switch (type) { case Text: processText(n1, n2, container, anchor); break; case Comment: processCommentNode(n1, n2, container, anchor); break; case Static: if (n1 == null) { mountStaticNode(n2, container, anchor, isSVG); } else if ((false)) {} break; case Fragment: processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); break; default: if (shapeFlag & 1 /* ELEMENT */) { processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else if (shapeFlag & 6 /* COMPONENT */) { processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else if (shapeFlag & 64 /* TELEPORT */) { type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); } else if (shapeFlag & 128 /* SUSPENSE */) { type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals); } else if ((false)) {} } // set ref if (ref != null && parentComponent) { setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2); } }; const processText = (n1, n2, container, anchor) => { if (n1 == null) { hostInsert((n2.el = hostCreateText(n2.children)), container, anchor); } else { const el = (n2.el = n1.el); if (n2.children !== n1.children) { hostSetText(el, n2.children); } } }; const processCommentNode = (n1, n2, container, anchor) => { if (n1 == null) { hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor); } else { // there's no support for dynamic comments n2.el = n1.el; } }; const mountStaticNode = (n2, container, anchor, isSVG) => { [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); }; /** * Dev / HMR only */ const patchStaticNode = (n1, n2, container, isSVG) => { // static nodes are only patched during dev for HMR if (n2.children !== n1.children) { const anchor = hostNextSibling(n1.anchor); // remove existing removeStaticNode(n1); [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); } else { n2.el = n1.el; n2.anchor = n1.anchor; } }; const moveStaticNode = ({ el, anchor }, container, nextSibling) => { let next; while (el && el !== anchor) { next = hostNextSibling(el); hostInsert(el, container, nextSibling); el = next; } hostInsert(anchor, container, nextSibling); }; const removeStaticNode = ({ el, anchor }) => { let next; while (el && el !== anchor) { next = hostNextSibling(el); hostRemove(el); el = next; } hostRemove(anchor); }; const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { isSVG = isSVG || n2.type === 'svg'; if (n1 == null) { mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else { patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } }; const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { let el; let vnodeHook; const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode; if ( true && vnode.el && hostCloneNode !== undefined && patchFlag === -1 /* HOISTED */) { // If a vnode has non-null el, it means it's being reused. // Only static vnodes can be reused, so its mounted DOM nodes should be // exactly the same, and we can simply do a clone here. // only do this in production since cloned trees cannot be HMR updated. el = vnode.el = hostCloneNode(vnode.el); } else { el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props); // mount children first, since some props may rely on child content // being already rendered, e.g. `<select value>` if (shapeFlag & 8 /* TEXT_CHILDREN */) { hostSetElementText(el, vnode.children); } else if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'created'); } // props if (props) { for (const key in props) { if (key !== 'value' && !(0,shared_esm_bundler.isReservedProp)(key)) { hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } /** * Special case for setting value on DOM elements: * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024) * - it needs to be forced (#1471) * #2353 proposes adding another renderer option to configure this, but * the properties affects are so finite it is worth special casing it * here to reduce the complexity. (Special casing it also should not * affect non-DOM renderers) */ if ('value' in props) { hostPatchProp(el, 'value', null, props.value); } if ((vnodeHook = props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHook, parentComponent, vnode); } } // scopeId setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent); } if (( false) || __VUE_PROD_DEVTOOLS__) { Object.defineProperty(el, '__vnode', { value: vnode, enumerable: false }); Object.defineProperty(el, '__vueParentComponent', { value: parentComponent, enumerable: false }); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved // #1689 For inside suspense + suspense resolved case, just call it const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) && transition && !transition.persisted; if (needCallTransitionHooks) { transition.beforeEnter(el); } hostInsert(el, container, anchor); if ((vnodeHook = props && props.onVnodeMounted) || needCallTransitionHooks || dirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); needCallTransitionHooks && transition.enter(el); dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); }, parentSuspense); } }; const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => { if (scopeId) { hostSetScopeId(el, scopeId); } if (slotScopeIds) { for (let i = 0; i < slotScopeIds.length; i++) { hostSetScopeId(el, slotScopeIds[i]); } } if (parentComponent) { let subTree = parentComponent.subTree; if (false /* DEV_ROOT_FRAGMENT */) {} if (vnode === subTree) { const parentVNode = parentComponent.vnode; setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent); } } }; const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => { for (let i = start; i < children.length; i++) { const child = (children[i] = optimized ? cloneIfMounted(children[i]) : normalizeVNode(children[i])); patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } }; const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { const el = (n2.el = n1.el); let { patchFlag, dynamicChildren, dirs } = n2; // #1426 take the old vnode's patch flag into account since user may clone a // compiler-generated vnode, which de-opts to FULL_PROPS patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */; const oldProps = n1.props || shared_esm_bundler.EMPTY_OBJ; const newProps = n2.props || shared_esm_bundler.EMPTY_OBJ; let vnodeHook; if ((vnodeHook = newProps.onVnodeBeforeUpdate)) { invokeVNodeHook(vnodeHook, parentComponent, n2, n1); } if (dirs) { invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate'); } if (false) {} const areChildrenSVG = isSVG && n2.type !== 'foreignObject'; if (dynamicChildren) { patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds); if (false) {} } else if (!optimized) { // full diff patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false); } if (patchFlag > 0) { // the presence of a patchFlag means this element's render code was // generated by the compiler and can take the fast path. // in this path old node and new node are guaranteed to have the same shape // (i.e. at the exact same position in the source template) if (patchFlag & 16 /* FULL_PROPS */) { // element props contain dynamic keys, full diff needed patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); } else { // class // this flag is matched when the element has dynamic class bindings. if (patchFlag & 2 /* CLASS */) { if (oldProps.class !== newProps.class) { hostPatchProp(el, 'class', null, newProps.class, isSVG); } } // style // this flag is matched when the element has dynamic style bindings if (patchFlag & 4 /* STYLE */) { hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG); } // props // This flag is matched when the element has dynamic prop/attr bindings // other than class and style. The keys of dynamic prop/attrs are saved for // faster iteration. // Note dynamic keys like :[foo]="bar" will cause this optimization to // bail out and go through a full diff because we need to unset the old key if (patchFlag & 8 /* PROPS */) { // if the flag is present then dynamicProps must be non-null const propsToUpdate = n2.dynamicProps; for (let i = 0; i < propsToUpdate.length; i++) { const key = propsToUpdate[i]; const prev = oldProps[key]; const next = newProps[key]; // #1471 force patch value if (next !== prev || key === 'value') { hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren); } } } } // text // This flag is matched when the element has only dynamic text children. if (patchFlag & 1 /* TEXT */) { if (n1.children !== n2.children) { hostSetElementText(el, n2.children); } } } else if (!optimized && dynamicChildren == null) { // unoptimized, full diff patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); } if ((vnodeHook = newProps.onVnodeUpdated) || dirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1); dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated'); }, parentSuspense); } }; // The fast path for blocks. const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => { for (let i = 0; i < newChildren.length; i++) { const oldVNode = oldChildren[i]; const newVNode = newChildren[i]; // Determine the container (parent element) for the patch. const container = // oldVNode may be an errored async setup() component inside Suspense // which will not have a mounted element oldVNode.el && // - In the case of a Fragment, we need to provide the actual parent // of the Fragment itself so it can move its children. (oldVNode.type === Fragment || // - In the case of different nodes, there is going to be a replacement // which also requires the correct parent container !isSameVNodeType(oldVNode, newVNode) || // - In the case of a component, it could contain anything. oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */)) ? hostParentNode(oldVNode.el) : // In other cases, the parent container is not actually used so we // just pass the block element here to avoid a DOM parentNode call. fallbackContainer; patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true); } }; const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => { if (oldProps !== newProps) { for (const key in newProps) { // empty string is not valid prop if ((0,shared_esm_bundler.isReservedProp)(key)) continue; const next = newProps[key]; const prev = oldProps[key]; // defer patching value if (next !== prev && key !== 'value') { hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } if (oldProps !== shared_esm_bundler.EMPTY_OBJ) { for (const key in oldProps) { if (!(0,shared_esm_bundler.isReservedProp)(key) && !(key in newProps)) { hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } } if ('value' in newProps) { hostPatchProp(el, 'value', oldProps.value, newProps.value); } } }; const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText('')); const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText('')); let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2; if (false) {} // check if this is a slot fragment with :slotted scope ids if (fragmentSlotScopeIds) { slotScopeIds = slotScopeIds ? slotScopeIds.concat(fragmentSlotScopeIds) : fragmentSlotScopeIds; } if (n1 == null) { hostInsert(fragmentStartAnchor, container, anchor); hostInsert(fragmentEndAnchor, container, anchor); // a fragment can only have array children // since they are either generated by the compiler, or implicitly created // from arrays. mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else { if (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */ && dynamicChildren && // #2715 the previous fragment could've been a BAILed one as a result // of renderSlot() with no valid children n1.dynamicChildren) { // a stable fragment (template root or <template v-for>) doesn't need to // patch children order, but it may contain dynamicChildren. patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds); if (false) {} else if ( // #2080 if the stable fragment has a key, it's a <template v-for> that may // get moved around. Make sure all root level vnodes inherit el. // #2134 or if it's a component root, it may also get moved around // as the component is being moved. n2.key != null || (parentComponent && n2 === parentComponent.subTree)) { traverseStaticChildren(n1, n2, true /* shallow */); } } else { // keyed / unkeyed, or manual fragments. // for keyed & unkeyed, since they are compiler generated from v-for, // each child is guaranteed to be a block so the fragment will never // have dynamicChildren. patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } } }; const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { n2.slotScopeIds = slotScopeIds; if (n1 == null) { if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized); } else { mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } } else { updateComponent(n1, n2, optimized); } }; const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense)); if (false) {} if ((false)) {} // inject renderer internals for keepAlive if (isKeepAlive(initialVNode)) { instance.ctx.renderer = internals; } // resolve props and slots for setup context { if ((false)) {} setupComponent(instance); if ((false)) {} } // setup() is async. This component relies on async logic to be resolved // before proceeding if (instance.asyncDep) { parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect); // Give it a placeholder if this is not hydration // TODO handle self-defined fallback if (!initialVNode.el) { const placeholder = (instance.subTree = createVNode(Comment)); processCommentNode(null, placeholder, container, anchor); } return; } setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized); if ((false)) {} }; const updateComponent = (n1, n2, optimized) => { const instance = (n2.component = n1.component); if (shouldUpdateComponent(n1, n2, optimized)) { if (instance.asyncDep && !instance.asyncResolved) { // async & still pending - just update props and slots // since the component's reactive effect for render isn't set-up yet if ((false)) {} updateComponentPreRender(instance, n2, optimized); if ((false)) {} return; } else { // normal update instance.next = n2; // in case the child component is also queued, remove it to avoid // double updating the same child component in the same flush. invalidateJob(instance.update); // instance.update is the reactive effect. instance.update(); } } else { // no update needed. just copy over properties n2.component = n1.component; n2.el = n1.el; instance.vnode = n2; } }; const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => { const componentUpdateFn = () => { if (!instance.isMounted) { let vnodeHook; const { el, props } = initialVNode; const { bm, m, parent } = instance; const isAsyncWrapperVNode = isAsyncWrapper(initialVNode); effect.allowRecurse = false; // beforeMount hook if (bm) { (0,shared_esm_bundler.invokeArrayFns)(bm); } // onVnodeBeforeMount if (!isAsyncWrapperVNode && (vnodeHook = props && props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHook, parent, initialVNode); } effect.allowRecurse = true; if (el && hydrateNode) { // vnode has adopted host node - perform hydration instead of mount. const hydrateSubTree = () => { if ((false)) {} instance.subTree = renderComponentRoot(instance); if ((false)) {} if ((false)) {} hydrateNode(el, instance.subTree, instance, parentSuspense, null); if ((false)) {} }; if (isAsyncWrapperVNode) { initialVNode.type.__asyncLoader().then( // note: we are moving the render call into an async callback, // which means it won't track dependencies - but it's ok because // a server-rendered async wrapper is already in resolved state // and it will never need to change. () => !instance.isUnmounted && hydrateSubTree()); } else { hydrateSubTree(); } } else { if ((false)) {} const subTree = (instance.subTree = renderComponentRoot(instance)); if ((false)) {} if ((false)) {} patch(null, subTree, container, anchor, instance, parentSuspense, isSVG); if ((false)) {} initialVNode.el = subTree.el; } // mounted hook if (m) { queuePostRenderEffect(m, parentSuspense); } // onVnodeMounted if (!isAsyncWrapperVNode && (vnodeHook = props && props.onVnodeMounted)) { const scopedInitialVNode = initialVNode; queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense); } // activated hook for keep-alive roots. // #1742 activated hook must be accessed after first render // since the hook may be injected by a child keep-alive if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { instance.a && queuePostRenderEffect(instance.a, parentSuspense); } instance.isMounted = true; if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentAdded(instance); } // #2458: deference mount-only object parameters to prevent memleaks initialVNode = container = anchor = null; } else { // updateComponent // This is triggered by mutation of component's own state (next: null) // OR parent calling processComponent (next: VNode) let { next, bu, u, parent, vnode } = instance; let originNext = next; let vnodeHook; if ((false)) {} // Disallow component effect recursion during pre-lifecycle hooks. effect.allowRecurse = false; if (next) { next.el = vnode.el; updateComponentPreRender(instance, next, optimized); } else { next = vnode; } // beforeUpdate hook if (bu) { (0,shared_esm_bundler.invokeArrayFns)(bu); } // onVnodeBeforeUpdate if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) { invokeVNodeHook(vnodeHook, parent, next, vnode); } effect.allowRecurse = true; // render if ((false)) {} const nextTree = renderComponentRoot(instance); if ((false)) {} const prevTree = instance.subTree; instance.subTree = nextTree; if ((false)) {} patch(prevTree, nextTree, // parent may have changed if it's in a teleport hostParentNode(prevTree.el), // anchor may have changed if it's in a fragment getNextHostNode(prevTree), instance, parentSuspense, isSVG); if ((false)) {} next.el = nextTree.el; if (originNext === null) { // self-triggered update. In case of HOC, update parent component // vnode el. HOC is indicated by parent instance's subTree pointing // to child component's vnode updateHOCHostEl(instance, nextTree.el); } // updated hook if (u) { queuePostRenderEffect(u, parentSuspense); } // onVnodeUpdated if ((vnodeHook = next.props && next.props.onVnodeUpdated)) { queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense); } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentUpdated(instance); } if ((false)) {} } }; // create reactive effect for rendering const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope ); const update = (instance.update = effect.run.bind(effect)); update.id = instance.uid; // allowRecurse // #1801, #2043 component render effects should allow recursive updates effect.allowRecurse = update.allowRecurse = true; if ((false)) {} update(); }; const updateComponentPreRender = (instance, nextVNode, optimized) => { nextVNode.component = instance; const prevProps = instance.vnode.props; instance.vnode = nextVNode; instance.next = null; updateProps(instance, nextVNode.props, prevProps, optimized); updateSlots(instance, nextVNode.children, optimized); pauseTracking(); // props update may have triggered pre-flush watchers. // flush them before the render update. flushPreFlushCbs(undefined, instance.update); resetTracking(); }; const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => { const c1 = n1 && n1.children; const prevShapeFlag = n1 ? n1.shapeFlag : 0; const c2 = n2.children; const { patchFlag, shapeFlag } = n2; // fast path if (patchFlag > 0) { if (patchFlag & 128 /* KEYED_FRAGMENT */) { // this could be either fully-keyed or mixed (some keyed some not) // presence of patchFlag means children are guaranteed to be arrays patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); return; } else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) { // unkeyed patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); return; } } // children has 3 possibilities: text, array or no children. if (shapeFlag & 8 /* TEXT_CHILDREN */) { // text children fast path if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) { unmountChildren(c1, parentComponent, parentSuspense); } if (c2 !== c1) { hostSetElementText(container, c2); } } else { if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) { // prev children was array if (shapeFlag & 16 /* ARRAY_CHILDREN */) { // two arrays, cannot assume anything, do full diff patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else { // no new children, just unmount old unmountChildren(c1, parentComponent, parentSuspense, true); } } else { // prev children was text OR null // new children is array OR null if (prevShapeFlag & 8 /* TEXT_CHILDREN */) { hostSetElementText(container, ''); } // mount new if array if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } } } }; const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { c1 = c1 || shared_esm_bundler.EMPTY_ARR; c2 = c2 || shared_esm_bundler.EMPTY_ARR; const oldLength = c1.length; const newLength = c2.length; const commonLength = Math.min(oldLength, newLength); let i; for (i = 0; i < commonLength; i++) { const nextChild = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } if (oldLength > newLength) { // remove old unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength); } else { // mount new mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength); } }; // can be all-keyed or mixed const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => { let i = 0; const l2 = c2.length; let e1 = c1.length - 1; // prev ending index let e2 = l2 - 1; // next ending index // 1. sync from start // (a b) c // (a b) d e while (i <= e1 && i <= e2) { const n1 = c1[i]; const n2 = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); if (isSameVNodeType(n1, n2)) { patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else { break; } i++; } // 2. sync from end // a (b c) // d e (b c) while (i <= e1 && i <= e2) { const n1 = c1[e1]; const n2 = (c2[e2] = optimized ? cloneIfMounted(c2[e2]) : normalizeVNode(c2[e2])); if (isSameVNodeType(n1, n2)) { patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else { break; } e1--; e2--; } // 3. common sequence + mount // (a b) // (a b) c // i = 2, e1 = 1, e2 = 2 // (a b) // c (a b) // i = 0, e1 = -1, e2 = 0 if (i > e1) { if (i <= e2) { const nextPos = e2 + 1; const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor; while (i <= e2) { patch(null, (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); i++; } } } // 4. common sequence + unmount // (a b) c // (a b) // i = 2, e1 = 2, e2 = 1 // a (b c) // (b c) // i = 0, e1 = 0, e2 = -1 else if (i > e2) { while (i <= e1) { unmount(c1[i], parentComponent, parentSuspense, true); i++; } } // 5. unknown sequence // [i ... e1 + 1]: a b [c d e] f g // [i ... e2 + 1]: a b [e d c h] f g // i = 2, e1 = 4, e2 = 5 else { const s1 = i; // prev starting index const s2 = i; // next starting index // 5.1 build key:index map for newChildren const keyToNewIndexMap = new Map(); for (i = s2; i <= e2; i++) { const nextChild = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); if (nextChild.key != null) { if (false) {} keyToNewIndexMap.set(nextChild.key, i); } } // 5.2 loop through old children left to be patched and try to patch // matching nodes & remove nodes that are no longer present let j; let patched = 0; const toBePatched = e2 - s2 + 1; let moved = false; // used to track whether any node has moved let maxNewIndexSoFar = 0; // works as Map<newIndex, oldIndex> // Note that oldIndex is offset by +1 // and oldIndex = 0 is a special value indicating the new node has // no corresponding old node. // used for determining longest stable subsequence const newIndexToOldIndexMap = new Array(toBePatched); for (i = 0; i < toBePatched; i++) newIndexToOldIndexMap[i] = 0; for (i = s1; i <= e1; i++) { const prevChild = c1[i]; if (patched >= toBePatched) { // all new children have been patched so this can only be a removal unmount(prevChild, parentComponent, parentSuspense, true); continue; } let newIndex; if (prevChild.key != null) { newIndex = keyToNewIndexMap.get(prevChild.key); } else { // key-less node, try to locate a key-less node of the same type for (j = s2; j <= e2; j++) { if (newIndexToOldIndexMap[j - s2] === 0 && isSameVNodeType(prevChild, c2[j])) { newIndex = j; break; } } } if (newIndex === undefined) { unmount(prevChild, parentComponent, parentSuspense, true); } else { newIndexToOldIndexMap[newIndex - s2] = i + 1; if (newIndex >= maxNewIndexSoFar) { maxNewIndexSoFar = newIndex; } else { moved = true; } patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); patched++; } } // 5.3 move and mount // generate longest stable subsequence only when nodes have moved const increasingNewIndexSequence = moved ? getSequence(newIndexToOldIndexMap) : shared_esm_bundler.EMPTY_ARR; j = increasingNewIndexSequence.length - 1; // looping backwards so that we can use last patched node as anchor for (i = toBePatched - 1; i >= 0; i--) { const nextIndex = s2 + i; const nextChild = c2[nextIndex]; const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor; if (newIndexToOldIndexMap[i] === 0) { // mount new patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } else if (moved) { // move if: // There is no stable subsequence (e.g. a reverse) // OR current node is not among the stable sequence if (j < 0 || i !== increasingNewIndexSequence[j]) { move(nextChild, container, anchor, 2 /* REORDER */); } else { j--; } } } } }; const move = (vnode, container, anchor, moveType, parentSuspense = null) => { const { el, type, transition, children, shapeFlag } = vnode; if (shapeFlag & 6 /* COMPONENT */) { move(vnode.component.subTree, container, anchor, moveType); return; } if (shapeFlag & 128 /* SUSPENSE */) { vnode.suspense.move(container, anchor, moveType); return; } if (shapeFlag & 64 /* TELEPORT */) { type.move(vnode, container, anchor, internals); return; } if (type === Fragment) { hostInsert(el, container, anchor); for (let i = 0; i < children.length; i++) { move(children[i], container, anchor, moveType); } hostInsert(vnode.anchor, container, anchor); return; } if (type === Static) { moveStaticNode(vnode, container, anchor); return; } // single nodes const needTransition = moveType !== 2 /* REORDER */ && shapeFlag & 1 /* ELEMENT */ && transition; if (needTransition) { if (moveType === 0 /* ENTER */) { transition.beforeEnter(el); hostInsert(el, container, anchor); queuePostRenderEffect(() => transition.enter(el), parentSuspense); } else { const { leave, delayLeave, afterLeave } = transition; const remove = () => hostInsert(el, container, anchor); const performLeave = () => { leave(el, () => { remove(); afterLeave && afterLeave(); }); }; if (delayLeave) { delayLeave(el, remove, performLeave); } else { performLeave(); } } } else { hostInsert(el, container, anchor); } }; const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => { const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode; // unset ref if (ref != null) { setRef(ref, null, parentSuspense, vnode, true); } if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { parentComponent.ctx.deactivate(vnode); return; } const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs; const shouldInvokeVnodeHook = !isAsyncWrapper(vnode); let vnodeHook; if (shouldInvokeVnodeHook && (vnodeHook = props && props.onVnodeBeforeUnmount)) { invokeVNodeHook(vnodeHook, parentComponent, vnode); } if (shapeFlag & 6 /* COMPONENT */) { unmountComponent(vnode.component, parentSuspense, doRemove); } else { if (shapeFlag & 128 /* SUSPENSE */) { vnode.suspense.unmount(parentSuspense, doRemove); return; } if (shouldInvokeDirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount'); } if (shapeFlag & 64 /* TELEPORT */) { vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove); } else if (dynamicChildren && // #1153: fast path should not be taken for non-stable (v-for) fragments (type !== Fragment || (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) { // fast path for block nodes: only need to unmount dynamic children. unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true); } else if ((type === Fragment && patchFlag & (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) || (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) { unmountChildren(children, parentComponent, parentSuspense); } if (doRemove) { remove(vnode); } } if ((shouldInvokeVnodeHook && (vnodeHook = props && props.onVnodeUnmounted)) || shouldInvokeDirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); shouldInvokeDirs && invokeDirectiveHook(vnode, null, parentComponent, 'unmounted'); }, parentSuspense); } }; const remove = vnode => { const { type, el, anchor, transition } = vnode; if (type === Fragment) { removeFragment(el, anchor); return; } if (type === Static) { removeStaticNode(vnode); return; } const performRemove = () => { hostRemove(el); if (transition && !transition.persisted && transition.afterLeave) { transition.afterLeave(); } }; if (vnode.shapeFlag & 1 /* ELEMENT */ && transition && !transition.persisted) { const { leave, delayLeave } = transition; const performLeave = () => leave(el, performRemove); if (delayLeave) { delayLeave(vnode.el, performRemove, performLeave); } else { performLeave(); } } else { performRemove(); } }; const removeFragment = (cur, end) => { // For fragments, directly remove all contained DOM nodes. // (fragment child nodes cannot have transition) let next; while (cur !== end) { next = hostNextSibling(cur); hostRemove(cur); cur = next; } hostRemove(end); }; const unmountComponent = (instance, parentSuspense, doRemove) => { if (false) {} const { bum, scope, update, subTree, um } = instance; // beforeUnmount hook if (bum) { (0,shared_esm_bundler.invokeArrayFns)(bum); } // stop effects in component scope scope.stop(); // update may be null if a component is unmounted before its async // setup has resolved. if (update) { // so that scheduler will no longer invoke it update.active = false; unmount(subTree, instance, parentSuspense, doRemove); } // unmounted hook if (um) { queuePostRenderEffect(um, parentSuspense); } queuePostRenderEffect(() => { instance.isUnmounted = true; }, parentSuspense); // A component with async dep inside a pending suspense is unmounted before // its async dep resolves. This should remove the dep from the suspense, and // cause the suspense to resolve immediately if that was the last dep. if (parentSuspense && parentSuspense.pendingBranch && !parentSuspense.isUnmounted && instance.asyncDep && !instance.asyncResolved && instance.suspenseId === parentSuspense.pendingId) { parentSuspense.deps--; if (parentSuspense.deps === 0) { parentSuspense.resolve(); } } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentRemoved(instance); } }; const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => { for (let i = start; i < children.length; i++) { unmount(children[i], parentComponent, parentSuspense, doRemove, optimized); } }; const getNextHostNode = vnode => { if (vnode.shapeFlag & 6 /* COMPONENT */) { return getNextHostNode(vnode.component.subTree); } if (vnode.shapeFlag & 128 /* SUSPENSE */) { return vnode.suspense.next(); } return hostNextSibling((vnode.anchor || vnode.el)); }; const render = (vnode, container, isSVG) => { if (vnode == null) { if (container._vnode) { unmount(container._vnode, null, null, true); } } else { patch(container._vnode || null, vnode, container, null, null, null, isSVG); } flushPostFlushCbs(); container._vnode = vnode; }; const internals = { p: patch, um: unmount, m: move, r: remove, mt: mountComponent, mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, n: getNextHostNode, o: options }; let hydrate; let hydrateNode; if (createHydrationFns) { [hydrate, hydrateNode] = createHydrationFns(internals); } return { render, hydrate, createApp: createAppAPI(render, hydrate) }; } function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) { if ((0,shared_esm_bundler.isArray)(rawRef)) { rawRef.forEach((r, i) => setRef(r, oldRawRef && ((0,shared_esm_bundler.isArray)(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount)); return; } if (isAsyncWrapper(vnode) && !isUnmount) { // when mounting async components, nothing needs to be done, // because the template ref is forwarded to inner component return; } const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ ? getExposeProxy(vnode.component) || vnode.component.proxy : vnode.el; const value = isUnmount ? null : refValue; const { i: owner, r: ref } = rawRef; if (false) {} const oldRef = oldRawRef && oldRawRef.r; const refs = owner.refs === shared_esm_bundler.EMPTY_OBJ ? (owner.refs = {}) : owner.refs; const setupState = owner.setupState; // dynamic ref changed. unset old ref if (oldRef != null && oldRef !== ref) { if ((0,shared_esm_bundler.isString)(oldRef)) { refs[oldRef] = null; if ((0,shared_esm_bundler.hasOwn)(setupState, oldRef)) { setupState[oldRef] = null; } } else if (isRef(oldRef)) { oldRef.value = null; } } if ((0,shared_esm_bundler.isString)(ref)) { const doSet = () => { { refs[ref] = value; } if ((0,shared_esm_bundler.hasOwn)(setupState, ref)) { setupState[ref] = value; } }; // #1789: for non-null values, set them after render // null values means this is unmount and it should not overwrite another // ref with the same key if (value) { doSet.id = -1; queuePostRenderEffect(doSet, parentSuspense); } else { doSet(); } } else if (isRef(ref)) { const doSet = () => { ref.value = value; }; if (value) { doSet.id = -1; queuePostRenderEffect(doSet, parentSuspense); } else { doSet(); } } else if ((0,shared_esm_bundler.isFunction)(ref)) { callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]); } else if ((false)) {} } function invokeVNodeHook(hook, instance, vnode, prevVNode = null) { callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [ vnode, prevVNode ]); } /** * #1156 * When a component is HMR-enabled, we need to make sure that all static nodes * inside a block also inherit the DOM element from the previous tree so that * HMR updates (which are full updates) can retrieve the element for patching. * * #2080 * Inside keyed `template` fragment static children, if a fragment is moved, * the children will always be moved. Therefore, in order to ensure correct move * position, el should be inherited from previous nodes. */ function traverseStaticChildren(n1, n2, shallow = false) { const ch1 = n1.children; const ch2 = n2.children; if ((0,shared_esm_bundler.isArray)(ch1) && (0,shared_esm_bundler.isArray)(ch2)) { for (let i = 0; i < ch1.length; i++) { // this is only called in the optimized path so array children are // guaranteed to be vnodes const c1 = ch1[i]; let c2 = ch2[i]; if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) { if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) { c2 = ch2[i] = cloneIfMounted(ch2[i]); c2.el = c1.el; } if (!shallow) traverseStaticChildren(c1, c2); } // also inherit for comment nodes, but not placeholders (e.g. v-if which // would have received .el during block patch) if (false) {} } } } // https://en.wikipedia.org/wiki/Longest_increasing_subsequence function getSequence(arr) { const p = arr.slice(); const result = [0]; let i, j, u, v, c; const len = arr.length; for (i = 0; i < len; i++) { const arrI = arr[i]; if (arrI !== 0) { j = result[result.length - 1]; if (arr[j] < arrI) { p[i] = j; result.push(i); continue; } u = 0; v = result.length - 1; while (u < v) { c = (u + v) >> 1; if (arr[result[c]] < arrI) { u = c + 1; } else { v = c; } } if (arrI < arr[result[u]]) { if (u > 0) { p[i] = result[u - 1]; } result[u] = i; } } } u = result.length; v = result[u - 1]; while (u-- > 0) { result[u] = v; v = p[v]; } return result; } const isTeleport = (type) => type.__isTeleport; const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === ''); const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement; const resolveTarget = (props, select) => { const targetSelector = props && props.to; if ((0,shared_esm_bundler.isString)(targetSelector)) { if (!select) { ( false) && 0; return null; } else { const target = select(targetSelector); if (!target) { ( false) && 0; } return target; } } else { if (false) {} return targetSelector; } }; const TeleportImpl = { __isTeleport: true, process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) { const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals; const disabled = isTeleportDisabled(n2.props); let { shapeFlag, children, dynamicChildren } = n2; // #3302 // HMR updated, force full diff if (false) {} if (n1 == null) { // insert anchors in the main view const placeholder = (n2.el = ( false) ? 0 : createText('')); const mainAnchor = (n2.anchor = ( false) ? 0 : createText('')); insert(placeholder, container, anchor); insert(mainAnchor, container, anchor); const target = (n2.target = resolveTarget(n2.props, querySelector)); const targetAnchor = (n2.targetAnchor = createText('')); if (target) { insert(targetAnchor, target); // #2652 we could be teleporting from a non-SVG tree into an SVG tree isSVG = isSVG || isTargetSVG(target); } else if (false) {} const mount = (container, anchor) => { // Teleport *always* has Array children. This is enforced in both the // compiler and vnode children normalization. if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized); } }; if (disabled) { mount(container, mainAnchor); } else if (target) { mount(target, targetAnchor); } } else { // update content n2.el = n1.el; const mainAnchor = (n2.anchor = n1.anchor); const target = (n2.target = n1.target); const targetAnchor = (n2.targetAnchor = n1.targetAnchor); const wasDisabled = isTeleportDisabled(n1.props); const currentContainer = wasDisabled ? container : target; const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; isSVG = isSVG || isTargetSVG(target); if (dynamicChildren) { // fast path when the teleport happens to be a block root patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds); // even in block tree mode we need to make sure all root-level nodes // in the teleport inherit previous DOM references so that they can // be moved in future patches. traverseStaticChildren(n1, n2, true); } else if (!optimized) { patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false); } if (disabled) { if (!wasDisabled) { // enabled -> disabled // move into main container moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */); } } else { // target changed if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { const nextTarget = (n2.target = resolveTarget(n2.props, querySelector)); if (nextTarget) { moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */); } else if ((false)) {} } else if (wasDisabled) { // disabled -> enabled // move into teleport target moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */); } } } }, remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) { const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode; if (target) { hostRemove(targetAnchor); } // an unmounted teleport should always remove its children if not disabled if (doRemove || !isTeleportDisabled(props)) { hostRemove(anchor); if (shapeFlag & 16 /* ARRAY_CHILDREN */) { for (let i = 0; i < children.length; i++) { const child = children[i]; unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren); } } } }, move: moveTeleport, hydrate: hydrateTeleport }; function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) { // move target anchor if this is a target change. if (moveType === 0 /* TARGET_CHANGE */) { insert(vnode.targetAnchor, container, parentAnchor); } const { el, anchor, shapeFlag, children, props } = vnode; const isReorder = moveType === 2 /* REORDER */; // move main view anchor if this is a re-order. if (isReorder) { insert(el, container, parentAnchor); } // if this is a re-order and teleport is enabled (content is in target) // do not move children. So the opposite is: only move children if this // is not a reorder, or the teleport is disabled if (!isReorder || isTeleportDisabled(props)) { // Teleport has either Array children or no children. if (shapeFlag & 16 /* ARRAY_CHILDREN */) { for (let i = 0; i < children.length; i++) { move(children[i], container, parentAnchor, 2 /* REORDER */); } } } // move main view anchor if this is a re-order. if (isReorder) { insert(anchor, container, parentAnchor); } } function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) { const target = (vnode.target = resolveTarget(vnode.props, querySelector)); if (target) { // if multiple teleports rendered to the same target element, we need to // pick up from where the last teleport finished instead of the first node const targetNode = target._lpa || target.firstChild; if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) { if (isTeleportDisabled(vnode.props)) { vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized); vnode.targetAnchor = targetNode; } else { vnode.anchor = nextSibling(node); vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized); } target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor); } } return vnode.anchor && nextSibling(vnode.anchor); } // Force-casted public typing for h and TSX props inference const Teleport = TeleportImpl; const COMPONENTS = 'components'; const DIRECTIVES = 'directives'; /** * @private */ function resolveComponent(name, maybeSelfReference) { return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; } const NULL_DYNAMIC_COMPONENT = Symbol(); /** * @private */ function resolveDynamicComponent(component) { if ((0,shared_esm_bundler.isString)(component)) { return resolveAsset(COMPONENTS, component, false) || component; } else { // invalid types will fallthrough to createVNode and raise warning return (component || NULL_DYNAMIC_COMPONENT); } } /** * @private */ function resolveDirective(name) { return resolveAsset(DIRECTIVES, name); } // implementation function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { const instance = currentRenderingInstance || currentInstance; if (instance) { const Component = instance.type; // explicit self name has highest priority if (type === COMPONENTS) { const selfName = getComponentName(Component); if (selfName && (selfName === name || selfName === (0,shared_esm_bundler.camelize)(name) || selfName === (0,shared_esm_bundler.capitalize)((0,shared_esm_bundler.camelize)(name)))) { return Component; } } const res = // local registration // check instance[type] first which is resolved for options API resolve(instance[type] || Component[type], name) || // global registration resolve(instance.appContext[type], name); if (!res && maybeSelfReference) { // fallback to implicit self-reference return Component; } if (false) {} return res; } else if ((false)) {} } function resolve(registry, name) { return (registry && (registry[name] || registry[(0,shared_esm_bundler.camelize)(name)] || registry[(0,shared_esm_bundler.capitalize)((0,shared_esm_bundler.camelize)(name))])); } const Fragment = Symbol(( false) ? 0 : undefined); const Text = Symbol(( false) ? 0 : undefined); const Comment = Symbol(( false) ? 0 : undefined); const Static = Symbol(( false) ? 0 : undefined); // Since v-if and v-for are the two possible ways node structure can dynamically // change, once we consider v-if branches and each v-for fragment a block, we // can divide a template into nested blocks, and within each block the node // structure would be stable. This allows us to skip most children diffing // and only worry about the dynamic nodes (indicated by patch flags). const blockStack = []; let currentBlock = null; /** * Open a block. * This must be called before `createBlock`. It cannot be part of `createBlock` * because the children of the block are evaluated before `createBlock` itself * is called. The generated code typically looks like this: * * ```js * function render() { * return (openBlock(),createBlock('div', null, [...])) * } * ``` * disableTracking is true when creating a v-for fragment block, since a v-for * fragment always diffs its children. * * @private */ function openBlock(disableTracking = false) { blockStack.push((currentBlock = disableTracking ? null : [])); } function closeBlock() { blockStack.pop(); currentBlock = blockStack[blockStack.length - 1] || null; } // Whether we should be tracking dynamic child nodes inside a block. // Only tracks when this value is > 0 // We are not using a simple boolean because this value may need to be // incremented/decremented by nested usage of v-once (see below) let isBlockTreeEnabled = 1; /** * Block tracking sometimes needs to be disabled, for example during the * creation of a tree that needs to be cached by v-once. The compiler generates * code like this: * * ``` js * _cache[1] || ( * setBlockTracking(-1), * _cache[1] = createVNode(...), * setBlockTracking(1), * _cache[1] * ) * ``` * * @private */ function setBlockTracking(value) { isBlockTreeEnabled += value; } function setupBlock(vnode) { // save current block children on the block vnode vnode.dynamicChildren = isBlockTreeEnabled > 0 ? currentBlock || shared_esm_bundler.EMPTY_ARR : null; // close block closeBlock(); // a block is always going to be patched, so track it as a child of its // parent block if (isBlockTreeEnabled > 0 && currentBlock) { currentBlock.push(vnode); } return vnode; } /** * @private */ function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) { return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */)); } /** * Create a block root vnode. Takes the same exact arguments as `createVNode`. * A block root keeps track of dynamic nodes within the block in the * `dynamicChildren` array. * * @private */ function createBlock(type, props, children, patchFlag, dynamicProps) { return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */)); } function isVNode(value) { return value ? value.__v_isVNode === true : false; } function isSameVNodeType(n1, n2) { if (false) {} return n1.type === n2.type && n1.key === n2.key; } let vnodeArgsTransformer; /** * Internal API for registering an arguments transform for createVNode * used for creating stubs in the test-utils * It is *internal* but needs to be exposed for test-utils to pick up proper * typings */ function transformVNodeArgs(transformer) { vnodeArgsTransformer = transformer; } const createVNodeWithArgsTransform = (...args) => { return _createVNode(...(vnodeArgsTransformer ? vnodeArgsTransformer(args, currentRenderingInstance) : args)); }; const InternalObjectKey = `__vInternal`; const normalizeKey = ({ key }) => key != null ? key : null; const normalizeRef = ({ ref }) => { return (ref != null ? (0,shared_esm_bundler.isString)(ref) || isRef(ref) || (0,shared_esm_bundler.isFunction)(ref) ? { i: currentRenderingInstance, r: ref } : ref : null); }; function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) { const vnode = { __v_isVNode: true, __v_skip: true, type, props, key: props && normalizeKey(props), ref: props && normalizeRef(props), scopeId: currentScopeId, slotScopeIds: null, children, component: null, suspense: null, ssContent: null, ssFallback: null, dirs: null, transition: null, el: null, anchor: null, target: null, targetAnchor: null, staticCount: 0, shapeFlag, patchFlag, dynamicProps, dynamicChildren: null, appContext: null }; if (needFullChildrenNormalization) { normalizeChildren(vnode, children); // normalize suspense children if (shapeFlag & 128 /* SUSPENSE */) { type.normalize(vnode); } } else if (children) { // compiled element vnode - if children is passed, only possible types are // string or Array. vnode.shapeFlag |= (0,shared_esm_bundler.isString)(children) ? 8 /* TEXT_CHILDREN */ : 16 /* ARRAY_CHILDREN */; } // validate key if (false) {} // track vnode for block tree if (isBlockTreeEnabled > 0 && // avoid a block node from tracking itself !isBlockNode && // has current parent block currentBlock && // presence of a patch flag indicates this node needs patching on updates. // component nodes also should always be patched, because even if the // component doesn't need to update, it needs to persist the instance on to // the next vnode so that it can be properly unmounted later. (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) && // the EVENTS flag is only for hydration and if it is the only flag, the // vnode should not be considered dynamic due to handler caching. vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) { currentBlock.push(vnode); } return vnode; } const createVNode = (( false) ? 0 : _createVNode); function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) { if (!type || type === NULL_DYNAMIC_COMPONENT) { if (false) {} type = Comment; } if (isVNode(type)) { // createVNode receiving an existing vnode. This happens in cases like // <component :is="vnode"/> // #2078 make sure to merge refs during the clone instead of overwriting it const cloned = cloneVNode(type, props, true /* mergeRef: true */); if (children) { normalizeChildren(cloned, children); } return cloned; } // class component normalization. if (isClassComponent(type)) { type = type.__vccOpts; } // class & style normalization. if (props) { // for reactive or proxy objects, we need to clone it to enable mutation. props = guardReactiveProps(props); let { class: klass, style } = props; if (klass && !(0,shared_esm_bundler.isString)(klass)) { props.class = (0,shared_esm_bundler.normalizeClass)(klass); } if ((0,shared_esm_bundler.isObject)(style)) { // reactive state objects need to be cloned since they are likely to be // mutated if (isProxy(style) && !(0,shared_esm_bundler.isArray)(style)) { style = (0,shared_esm_bundler.extend)({}, style); } props.style = (0,shared_esm_bundler.normalizeStyle)(style); } } // encode the vnode type information into a bitmap const shapeFlag = (0,shared_esm_bundler.isString)(type) ? 1 /* ELEMENT */ : isSuspense(type) ? 128 /* SUSPENSE */ : isTeleport(type) ? 64 /* TELEPORT */ : (0,shared_esm_bundler.isObject)(type) ? 4 /* STATEFUL_COMPONENT */ : (0,shared_esm_bundler.isFunction)(type) ? 2 /* FUNCTIONAL_COMPONENT */ : 0; if (false) {} return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true); } function guardReactiveProps(props) { if (!props) return null; return isProxy(props) || InternalObjectKey in props ? (0,shared_esm_bundler.extend)({}, props) : props; } function cloneVNode(vnode, extraProps, mergeRef = false) { // This is intentionally NOT using spread or extend to avoid the runtime // key enumeration cost. const { props, ref, patchFlag, children } = vnode; const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props; const cloned = { __v_isVNode: true, __v_skip: true, type: vnode.type, props: mergedProps, key: mergedProps && normalizeKey(mergedProps), ref: extraProps && extraProps.ref ? // #2078 in the case of <component :is="vnode" ref="extra"/> // if the vnode itself already has a ref, cloneVNode will need to merge // the refs so the single vnode can be set on multiple refs mergeRef && ref ? (0,shared_esm_bundler.isArray)(ref) ? ref.concat(normalizeRef(extraProps)) : [ref, normalizeRef(extraProps)] : normalizeRef(extraProps) : ref, scopeId: vnode.scopeId, slotScopeIds: vnode.slotScopeIds, children: false ? 0 : children, target: vnode.target, targetAnchor: vnode.targetAnchor, staticCount: vnode.staticCount, shapeFlag: vnode.shapeFlag, // if the vnode is cloned with extra props, we can no longer assume its // existing patch flag to be reliable and need to add the FULL_PROPS flag. // note: perserve flag for fragments since they use the flag for children // fast paths only. patchFlag: extraProps && vnode.type !== Fragment ? patchFlag === -1 // hoisted node ? 16 /* FULL_PROPS */ : patchFlag | 16 /* FULL_PROPS */ : patchFlag, dynamicProps: vnode.dynamicProps, dynamicChildren: vnode.dynamicChildren, appContext: vnode.appContext, dirs: vnode.dirs, transition: vnode.transition, // These should technically only be non-null on mounted VNodes. However, // they *should* be copied for kept-alive vnodes. So we just always copy // them since them being non-null during a mount doesn't affect the logic as // they will simply be overwritten. component: vnode.component, suspense: vnode.suspense, ssContent: vnode.ssContent && cloneVNode(vnode.ssContent), ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback), el: vnode.el, anchor: vnode.anchor }; return cloned; } /** * Dev only, for HMR of hoisted vnodes reused in v-for * https://github.com/vitejs/vite/issues/2022 */ function deepCloneVNode(vnode) { const cloned = cloneVNode(vnode); if (isArray(vnode.children)) { cloned.children = vnode.children.map(deepCloneVNode); } return cloned; } /** * @private */ function createTextVNode(text = ' ', flag = 0) { return createVNode(Text, null, text, flag); } /** * @private */ function createStaticVNode(content, numberOfNodes) { // A static vnode can contain multiple stringified elements, and the number // of elements is necessary for hydration. const vnode = createVNode(Static, null, content); vnode.staticCount = numberOfNodes; return vnode; } /** * @private */ function createCommentVNode(text = '', // when used as the v-else branch, the comment node must be created as a // block to ensure correct updates. asBlock = false) { return asBlock ? (openBlock(), createBlock(Comment, null, text)) : createVNode(Comment, null, text); } function normalizeVNode(child) { if (child == null || typeof child === 'boolean') { // empty placeholder return createVNode(Comment); } else if ((0,shared_esm_bundler.isArray)(child)) { // fragment return createVNode(Fragment, null, // #3666, avoid reference pollution when reusing vnode child.slice()); } else if (typeof child === 'object') { // already vnode, this should be the most common since compiled templates // always produce all-vnode children arrays return cloneIfMounted(child); } else { // strings and numbers return createVNode(Text, null, String(child)); } } // optimized normalization for template-compiled render fns function cloneIfMounted(child) { return child.el === null || child.memo ? child : cloneVNode(child); } function normalizeChildren(vnode, children) { let type = 0; const { shapeFlag } = vnode; if (children == null) { children = null; } else if ((0,shared_esm_bundler.isArray)(children)) { type = 16 /* ARRAY_CHILDREN */; } else if (typeof children === 'object') { if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) { // Normalize slot to plain children for plain element and Teleport const slot = children.default; if (slot) { // _c marker is added by withCtx() indicating this is a compiled slot slot._c && (slot._d = false); normalizeChildren(vnode, slot()); slot._c && (slot._d = true); } return; } else { type = 32 /* SLOTS_CHILDREN */; const slotFlag = children._; if (!slotFlag && !(InternalObjectKey in children)) { children._ctx = currentRenderingInstance; } else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) { // a child component receives forwarded slots from the parent. // its slot type is determined by its parent's slot type. if (currentRenderingInstance.slots._ === 1 /* STABLE */) { children._ = 1 /* STABLE */; } else { children._ = 2 /* DYNAMIC */; vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */; } } } } else if ((0,shared_esm_bundler.isFunction)(children)) { children = { default: children, _ctx: currentRenderingInstance }; type = 32 /* SLOTS_CHILDREN */; } else { children = String(children); // force teleport children to array so it can be moved around if (shapeFlag & 64 /* TELEPORT */) { type = 16 /* ARRAY_CHILDREN */; children = [createTextVNode(children)]; } else { type = 8 /* TEXT_CHILDREN */; } } vnode.children = children; vnode.shapeFlag |= type; } function mergeProps(...args) { const ret = {}; for (let i = 0; i < args.length; i++) { const toMerge = args[i]; for (const key in toMerge) { if (key === 'class') { if (ret.class !== toMerge.class) { ret.class = (0,shared_esm_bundler.normalizeClass)([ret.class, toMerge.class]); } } else if (key === 'style') { ret.style = (0,shared_esm_bundler.normalizeStyle)([ret.style, toMerge.style]); } else if ((0,shared_esm_bundler.isOn)(key)) { const existing = ret[key]; const incoming = toMerge[key]; if (existing !== incoming && !((0,shared_esm_bundler.isArray)(existing) && existing.includes(incoming))) { ret[key] = existing ? [].concat(existing, incoming) : incoming; } } else if (key !== '') { ret[key] = toMerge[key]; } } } return ret; } /** * Actual implementation */ function renderList(source, renderItem, cache, index) { let ret; const cached = (cache && cache[index]); if ((0,shared_esm_bundler.isArray)(source) || (0,shared_esm_bundler.isString)(source)) { ret = new Array(source.length); for (let i = 0, l = source.length; i < l; i++) { ret[i] = renderItem(source[i], i, undefined, cached && cached[i]); } } else if (typeof source === 'number') { if (false) {} ret = new Array(source); for (let i = 0; i < source; i++) { ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]); } } else if ((0,shared_esm_bundler.isObject)(source)) { if (source[Symbol.iterator]) { ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i])); } else { const keys = Object.keys(source); ret = new Array(keys.length); for (let i = 0, l = keys.length; i < l; i++) { const key = keys[i]; ret[i] = renderItem(source[key], key, i, cached && cached[i]); } } } else { ret = []; } if (cache) { cache[index] = ret; } return ret; } /** * Compiler runtime helper for creating dynamic slots object * @private */ function createSlots(slots, dynamicSlots) { for (let i = 0; i < dynamicSlots.length; i++) { const slot = dynamicSlots[i]; // array of dynamic slot generated by <template v-for="..." #[...]> if ((0,shared_esm_bundler.isArray)(slot)) { for (let j = 0; j < slot.length; j++) { slots[slot[j].name] = slot[j].fn; } } else if (slot) { // conditional single slot generated by <template v-if="..." #foo> slots[slot.name] = slot.fn; } } return slots; } /** * Compiler runtime helper for rendering `<slot/>` * @private */ function renderSlot(slots, name, props = {}, // this is not a user-facing function, so the fallback is always generated by // the compiler and guaranteed to be a function returning an array fallback, noSlotted) { if (currentRenderingInstance.isCE) { return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback()); } let slot = slots[name]; if (false) {} // a compiled slot disables block tracking by default to avoid manual // invocation interfering with template-based block tracking, but in // `renderSlot` we can be sure that it's template-based so we can force // enable it. if (slot && slot._c) { slot._d = false; } openBlock(); const validSlotContent = slot && ensureValidVNode(slot(props)); const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */ ? 64 /* STABLE_FRAGMENT */ : -2 /* BAIL */); if (!noSlotted && rendered.scopeId) { rendered.slotScopeIds = [rendered.scopeId + '-s']; } if (slot && slot._c) { slot._d = true; } return rendered; } function ensureValidVNode(vnodes) { return vnodes.some(child => { if (!isVNode(child)) return true; if (child.type === Comment) return false; if (child.type === Fragment && !ensureValidVNode(child.children)) return false; return true; }) ? vnodes : null; } /** * For prefixing keys in v-on="obj" with "on" * @private */ function toHandlers(obj) { const ret = {}; if (false) {} for (const key in obj) { ret[(0,shared_esm_bundler.toHandlerKey)(key)] = obj[key]; } return ret; } /** * #2437 In Vue 3, functional components do not have a public instance proxy but * they exist in the internal parent chain. For code that relies on traversing * public $parent chains, skip functional ones and go to the parent instead. */ const getPublicInstance = (i) => { if (!i) return null; if (isStatefulComponent(i)) return getExposeProxy(i) || i.proxy; return getPublicInstance(i.parent); }; const publicPropertiesMap = (0,shared_esm_bundler.extend)(Object.create(null), { $: i => i, $el: i => i.vnode.el, $data: i => i.data, $props: i => (( false) ? 0 : i.props), $attrs: i => (( false) ? 0 : i.attrs), $slots: i => (( false) ? 0 : i.slots), $refs: i => (( false) ? 0 : i.refs), $parent: i => getPublicInstance(i.parent), $root: i => getPublicInstance(i.root), $emit: i => i.emit, $options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type), $forceUpdate: i => () => queueJob(i.update), $nextTick: i => nextTick.bind(i.proxy), $watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : shared_esm_bundler.NOOP) }); const PublicInstanceProxyHandlers = { get({ _: instance }, key) { const { ctx, setupState, data, props, accessCache, type, appContext } = instance; // for internal formatters to know that this is a Vue instance if (false) {} // prioritize <script setup> bindings during dev. // this allows even properties that start with _ or $ to be used - so that // it aligns with the production behavior where the render fn is inlined and // indeed has access to all declared variables. if (false) {} // data / props / ctx // This getter gets called for every property access on the render context // during render and is a major hotspot. The most expensive part of this // is the multiple hasOwn() calls. It's much faster to do a simple property // access on a plain object, so we use an accessCache object (with null // prototype) to memoize what access type a key corresponds to. let normalizedProps; if (key[0] !== '$') { const n = accessCache[key]; if (n !== undefined) { switch (n) { case 0 /* SETUP */: return setupState[key]; case 1 /* DATA */: return data[key]; case 3 /* CONTEXT */: return ctx[key]; case 2 /* PROPS */: return props[key]; // default: just fallthrough } } else if (setupState !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(setupState, key)) { accessCache[key] = 0 /* SETUP */; return setupState[key]; } else if (data !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(data, key)) { accessCache[key] = 1 /* DATA */; return data[key]; } else if ( // only cache other properties when instance has declared (thus stable) // props (normalizedProps = instance.propsOptions[0]) && (0,shared_esm_bundler.hasOwn)(normalizedProps, key)) { accessCache[key] = 2 /* PROPS */; return props[key]; } else if (ctx !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(ctx, key)) { accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) { accessCache[key] = 4 /* OTHER */; } } const publicGetter = publicPropertiesMap[key]; let cssModule, globalProperties; // public $xxx properties if (publicGetter) { if (key === '$attrs') { track(instance, "get" /* GET */, key); ( false) && 0; } return publicGetter(instance); } else if ( // css module (injected by vue-loader) (cssModule = type.__cssModules) && (cssModule = cssModule[key])) { return cssModule; } else if (ctx !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(ctx, key)) { // user may set custom properties to `this` that start with `$` accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } else if ( // global properties ((globalProperties = appContext.config.globalProperties), (0,shared_esm_bundler.hasOwn)(globalProperties, key))) { { return globalProperties[key]; } } else if (false) {} }, set({ _: instance }, key, value) { const { data, setupState, ctx } = instance; if (setupState !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(setupState, key)) { setupState[key] = value; } else if (data !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(data, key)) { data[key] = value; } else if ((0,shared_esm_bundler.hasOwn)(instance.props, key)) { ( false) && 0; return false; } if (key[0] === '$' && key.slice(1) in instance) { ( false) && 0; return false; } else { if (false) {} else { ctx[key] = value; } } return true; }, has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) { let normalizedProps; return (accessCache[key] !== undefined || (data !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(data, key)) || (setupState !== shared_esm_bundler.EMPTY_OBJ && (0,shared_esm_bundler.hasOwn)(setupState, key)) || ((normalizedProps = propsOptions[0]) && (0,shared_esm_bundler.hasOwn)(normalizedProps, key)) || (0,shared_esm_bundler.hasOwn)(ctx, key) || (0,shared_esm_bundler.hasOwn)(publicPropertiesMap, key) || (0,shared_esm_bundler.hasOwn)(appContext.config.globalProperties, key)); } }; if (false) {} const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ (0,shared_esm_bundler.extend)({}, PublicInstanceProxyHandlers, { get(target, key) { // fast path for unscopables when using `with` block if (key === Symbol.unscopables) { return; } return PublicInstanceProxyHandlers.get(target, key, target); }, has(_, key) { const has = key[0] !== '_' && !(0,shared_esm_bundler.isGloballyWhitelisted)(key); if (false) {} return has; } }); // dev only // In dev mode, the proxy target exposes the same properties as seen on `this` // for easier console inspection. In prod mode it will be an empty object so // these properties definitions can be skipped. function createDevRenderContext(instance) { const target = {}; // expose internal instance for proxy handlers Object.defineProperty(target, `_`, { configurable: true, enumerable: false, get: () => instance }); // expose public properties Object.keys(publicPropertiesMap).forEach(key => { Object.defineProperty(target, key, { configurable: true, enumerable: false, get: () => publicPropertiesMap[key](instance), // intercepted by the proxy so no need for implementation, // but needed to prevent set errors set: NOOP }); }); return target; } // dev only function exposePropsOnRenderContext(instance) { const { ctx, propsOptions: [propsOptions] } = instance; if (propsOptions) { Object.keys(propsOptions).forEach(key => { Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => instance.props[key], set: NOOP }); }); } } // dev only function exposeSetupStateOnRenderContext(instance) { const { ctx, setupState } = instance; Object.keys(toRaw(setupState)).forEach(key => { if (!setupState.__isScriptSetup) { if (key[0] === '$' || key[0] === '_') { runtime_core_esm_bundler_warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` + `which are reserved prefixes for Vue internals.`); return; } Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => setupState[key], set: NOOP }); } }); } const emptyAppContext = createAppContext(); let uid$1 = 0; function createComponentInstance(vnode, parent, suspense) { const type = vnode.type; // inherit parent app context - or - if root, adopt from root vnode const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext; const instance = { uid: uid$1++, vnode, type, parent, appContext, root: null, next: null, subTree: null, update: null, scope: new EffectScope(true /* detached */), render: null, proxy: null, exposed: null, exposeProxy: null, withProxy: null, provides: parent ? parent.provides : Object.create(appContext.provides), accessCache: null, renderCache: [], // local resovled assets components: null, directives: null, // resolved props and emits options propsOptions: normalizePropsOptions(type, appContext), emitsOptions: normalizeEmitsOptions(type, appContext), // emit emit: null, emitted: null, // props default value propsDefaults: shared_esm_bundler.EMPTY_OBJ, // inheritAttrs inheritAttrs: type.inheritAttrs, // state ctx: shared_esm_bundler.EMPTY_OBJ, data: shared_esm_bundler.EMPTY_OBJ, props: shared_esm_bundler.EMPTY_OBJ, attrs: shared_esm_bundler.EMPTY_OBJ, slots: shared_esm_bundler.EMPTY_OBJ, refs: shared_esm_bundler.EMPTY_OBJ, setupState: shared_esm_bundler.EMPTY_OBJ, setupContext: null, // suspense related suspense, suspenseId: suspense ? suspense.pendingId : 0, asyncDep: null, asyncResolved: false, // lifecycle hooks // not using enums here because it results in computed properties isMounted: false, isUnmounted: false, isDeactivated: false, bc: null, c: null, bm: null, m: null, bu: null, u: null, um: null, bum: null, da: null, a: null, rtg: null, rtc: null, ec: null, sp: null }; if ((false)) {} else { instance.ctx = { _: instance }; } instance.root = parent ? parent.root : instance; instance.emit = emit$1.bind(null, instance); // apply custom element special handling if (vnode.ce) { vnode.ce(instance); } return instance; } let currentInstance = null; const getCurrentInstance = () => currentInstance || currentRenderingInstance; const setCurrentInstance = (instance) => { currentInstance = instance; instance.scope.on(); }; const unsetCurrentInstance = () => { currentInstance && currentInstance.scope.off(); currentInstance = null; }; const isBuiltInTag = /*#__PURE__*/ (/* unused pure expression or super */ null && (makeMap('slot,component'))); function validateComponentName(name, config) { const appIsNativeTag = config.isNativeTag || NO; if (isBuiltInTag(name) || appIsNativeTag(name)) { runtime_core_esm_bundler_warn('Do not use built-in or reserved HTML elements as component id: ' + name); } } function isStatefulComponent(instance) { return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */; } let isInSSRComponentSetup = false; function setupComponent(instance, isSSR = false) { isInSSRComponentSetup = isSSR; const { props, children } = instance.vnode; const isStateful = isStatefulComponent(instance); initProps(instance, props, isStateful, isSSR); initSlots(instance, children); const setupResult = isStateful ? setupStatefulComponent(instance, isSSR) : undefined; isInSSRComponentSetup = false; return setupResult; } function setupStatefulComponent(instance, isSSR) { const Component = instance.type; if ((false)) {} // 0. create render proxy property access cache instance.accessCache = Object.create(null); // 1. create public instance / render proxy // also mark it raw so it's never observed instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers)); if ((false)) {} // 2. call setup() const { setup } = Component; if (setup) { const setupContext = (instance.setupContext = setup.length > 1 ? createSetupContext(instance) : null); setCurrentInstance(instance); pauseTracking(); const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [( false) ? 0 : instance.props, setupContext]); resetTracking(); unsetCurrentInstance(); if ((0,shared_esm_bundler.isPromise)(setupResult)) { setupResult.then(unsetCurrentInstance, unsetCurrentInstance); if (isSSR) { // return the promise so server-renderer can wait on it return setupResult .then((resolvedResult) => { handleSetupResult(instance, resolvedResult, isSSR); }) .catch(e => { handleError(e, instance, 0 /* SETUP_FUNCTION */); }); } else { // async setup returned Promise. // bail here and wait for re-entry. instance.asyncDep = setupResult; } } else { handleSetupResult(instance, setupResult, isSSR); } } else { finishComponentSetup(instance, isSSR); } } function handleSetupResult(instance, setupResult, isSSR) { if ((0,shared_esm_bundler.isFunction)(setupResult)) { // setup returned an inline render function if (instance.type.__ssrInlineRender) { // when the function's name is `ssrRender` (compiled by SFC inline mode), // set it as ssrRender instead. instance.ssrRender = setupResult; } else { instance.render = setupResult; } } else if ((0,shared_esm_bundler.isObject)(setupResult)) { if (false) {} // setup returned bindings. // assuming a render function compiled from template is present. if (( false) || __VUE_PROD_DEVTOOLS__) { instance.devtoolsRawSetupState = setupResult; } instance.setupState = proxyRefs(setupResult); if ((false)) {} } else if (false) {} finishComponentSetup(instance, isSSR); } let compile; let installWithProxy; /** * For runtime-dom to register the compiler. * Note the exported method uses any to avoid d.ts relying on the compiler types. */ function registerRuntimeCompiler(_compile) { compile = _compile; installWithProxy = i => { if (i.render._rc) { i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers); } }; } // dev only const runtime_core_esm_bundler_isRuntimeOnly = () => !compile; function finishComponentSetup(instance, isSSR, skipOptions) { const Component = instance.type; // template / render function normalization // could be already set when returned from setup() if (!instance.render) { // only do on-the-fly compile if not in SSR - SSR on-the-fly compliation // is done by server-renderer if (!isSSR && compile && !Component.render) { const template = Component.template; if (template) { if ((false)) {} const { isCustomElement, compilerOptions } = instance.appContext.config; const { delimiters, compilerOptions: componentCompilerOptions } = Component; const finalCompilerOptions = (0,shared_esm_bundler.extend)((0,shared_esm_bundler.extend)({ isCustomElement, delimiters }, compilerOptions), componentCompilerOptions); Component.render = compile(template, finalCompilerOptions); if ((false)) {} } } instance.render = (Component.render || shared_esm_bundler.NOOP); // for runtime-compiled render functions using `with` blocks, the render // proxy used needs a different `has` handler which is more performant and // also only allows a whitelist of globals to fallthrough. if (installWithProxy) { installWithProxy(instance); } } // support for 2.x options if (__VUE_OPTIONS_API__ && !(false )) { setCurrentInstance(instance); pauseTracking(); applyOptions(instance); resetTracking(); unsetCurrentInstance(); } // warn missing template/render // the runtime compilation of template in SSR is done by server-render if (false) {} } function createAttrsProxy(instance) { return new Proxy(instance.attrs, ( false) ? 0 : { get(target, key) { track(instance, "get" /* GET */, '$attrs'); return target[key]; } }); } function createSetupContext(instance) { const expose = exposed => { if (false) {} instance.exposed = exposed || {}; }; let attrs; if ((false)) {} else { return { get attrs() { return attrs || (attrs = createAttrsProxy(instance)); }, slots: instance.slots, emit: instance.emit, expose }; } } function getExposeProxy(instance) { if (instance.exposed) { return (instance.exposeProxy || (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), { get(target, key) { if (key in target) { return target[key]; } else if (key in publicPropertiesMap) { return publicPropertiesMap[key](instance); } } }))); } } const classifyRE = /(?:^|[-_])(\w)/g; const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, ''); function getComponentName(Component) { return (0,shared_esm_bundler.isFunction)(Component) ? Component.displayName || Component.name : Component.name; } /* istanbul ignore next */ function formatComponentName(instance, Component, isRoot = false) { let name = getComponentName(Component); if (!name && Component.__file) { const match = Component.__file.match(/([^/\\]+)\.\w+$/); if (match) { name = match[1]; } } if (!name && instance && instance.parent) { // try to infer the name based on reverse resolution const inferFromRegistry = (registry) => { for (const key in registry) { if (registry[key] === Component) { return key; } } }; name = inferFromRegistry(instance.components || instance.parent.type.components) || inferFromRegistry(instance.appContext.components); } return name ? classify(name) : isRoot ? `App` : `Anonymous`; } function isClassComponent(value) { return (0,shared_esm_bundler.isFunction)(value) && '__vccOpts' in value; } const stack = []; function pushWarningContext(vnode) { stack.push(vnode); } function popWarningContext() { stack.pop(); } function runtime_core_esm_bundler_warn(msg, ...args) { // avoid props formatting or warn handler tracking deps that might be mutated // during patch, leading to infinite recursion. pauseTracking(); const instance = stack.length ? stack[stack.length - 1].component : null; const appWarnHandler = instance && instance.appContext.config.warnHandler; const trace = getComponentTrace(); if (appWarnHandler) { callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [ msg + args.join(''), instance && instance.proxy, trace .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) .join('\n'), trace ]); } else { const warnArgs = [`[Vue warn]: ${msg}`, ...args]; /* istanbul ignore if */ if (trace.length && // avoid spamming console during tests !false) { warnArgs.push(`\n`, ...formatTrace(trace)); } console.warn(...warnArgs); } resetTracking(); } function getComponentTrace() { let currentVNode = stack[stack.length - 1]; if (!currentVNode) { return []; } // we can't just use the stack because it will be incomplete during updates // that did not start from the root. Re-construct the parent chain using // instance parent pointers. const normalizedStack = []; while (currentVNode) { const last = normalizedStack[0]; if (last && last.vnode === currentVNode) { last.recurseCount++; } else { normalizedStack.push({ vnode: currentVNode, recurseCount: 0 }); } const parentInstance = currentVNode.component && currentVNode.component.parent; currentVNode = parentInstance && parentInstance.vnode; } return normalizedStack; } /* istanbul ignore next */ function formatTrace(trace) { const logs = []; trace.forEach((entry, i) => { logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); }); return logs; } function formatTraceEntry({ vnode, recurseCount }) { const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; const isRoot = vnode.component ? vnode.component.parent == null : false; const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; const close = `>` + postfix; return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; } /* istanbul ignore next */ function formatProps(props) { const res = []; const keys = Object.keys(props); keys.slice(0, 3).forEach(key => { res.push(...formatProp(key, props[key])); }); if (keys.length > 3) { res.push(` ...`); } return res; } /* istanbul ignore next */ function formatProp(key, value, raw) { if ((0,shared_esm_bundler.isString)(value)) { value = JSON.stringify(value); return raw ? value : [`${key}=${value}`]; } else if (typeof value === 'number' || typeof value === 'boolean' || value == null) { return raw ? value : [`${key}=${value}`]; } else if (isRef(value)) { value = formatProp(key, reactivity_esm_bundler_toRaw(value.value), true); return raw ? value : [`${key}=Ref<`, value, `>`]; } else if ((0,shared_esm_bundler.isFunction)(value)) { return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; } else { value = reactivity_esm_bundler_toRaw(value); return raw ? value : [`${key}=`, value]; } } const ErrorTypeStrings = { ["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook', ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook', ["c" /* CREATED */]: 'created hook', ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook', ["m" /* MOUNTED */]: 'mounted hook', ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook', ["u" /* UPDATED */]: 'updated', ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook', ["um" /* UNMOUNTED */]: 'unmounted hook', ["a" /* ACTIVATED */]: 'activated hook', ["da" /* DEACTIVATED */]: 'deactivated hook', ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook', ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook', ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook', [0 /* SETUP_FUNCTION */]: 'setup function', [1 /* RENDER_FUNCTION */]: 'render function', [2 /* WATCH_GETTER */]: 'watcher getter', [3 /* WATCH_CALLBACK */]: 'watcher callback', [4 /* WATCH_CLEANUP */]: 'watcher cleanup function', [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler', [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler', [7 /* VNODE_HOOK */]: 'vnode hook', [8 /* DIRECTIVE_HOOK */]: 'directive hook', [9 /* TRANSITION_HOOK */]: 'transition hook', [10 /* APP_ERROR_HANDLER */]: 'app errorHandler', [11 /* APP_WARN_HANDLER */]: 'app warnHandler', [12 /* FUNCTION_REF */]: 'ref function', [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader', [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next' }; function callWithErrorHandling(fn, instance, type, args) { let res; try { res = args ? fn(...args) : fn(); } catch (err) { handleError(err, instance, type); } return res; } function callWithAsyncErrorHandling(fn, instance, type, args) { if ((0,shared_esm_bundler.isFunction)(fn)) { const res = callWithErrorHandling(fn, instance, type, args); if (res && (0,shared_esm_bundler.isPromise)(res)) { res.catch(err => { handleError(err, instance, type); }); } return res; } const values = []; for (let i = 0; i < fn.length; i++) { values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); } return values; } function handleError(err, instance, type, throwInDev = true) { const contextVNode = instance ? instance.vnode : null; if (instance) { let cur = instance.parent; // the exposed instance is the render proxy to keep it consistent with 2.x const exposedInstance = instance.proxy; // in production the hook receives only the error code const errorInfo = ( false) ? 0 : type; while (cur) { const errorCapturedHooks = cur.ec; if (errorCapturedHooks) { for (let i = 0; i < errorCapturedHooks.length; i++) { if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { return; } } } cur = cur.parent; } // app-level handling const appErrorHandler = instance.appContext.config.errorHandler; if (appErrorHandler) { callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]); return; } } logError(err, type, contextVNode, throwInDev); } function logError(err, type, contextVNode, throwInDev = true) { if ((false)) {} else { // recover in prod to reduce the impact on end-user console.error(err); } } let isFlushing = false; let isFlushPending = false; const runtime_core_esm_bundler_queue = []; let flushIndex = 0; const pendingPreFlushCbs = []; let activePreFlushCbs = null; let preFlushIndex = 0; const pendingPostFlushCbs = []; let activePostFlushCbs = null; let postFlushIndex = 0; const resolvedPromise = Promise.resolve(); let currentFlushPromise = null; let currentPreFlushParentJob = null; const RECURSION_LIMIT = 100; function nextTick(fn) { const p = currentFlushPromise || resolvedPromise; return fn ? p.then(this ? fn.bind(this) : fn) : p; } // #2768 // Use binary-search to find a suitable position in the queue, // so that the queue maintains the increasing order of job's id, // which can prevent the job from being skipped and also can avoid repeated patching. function findInsertionIndex(id) { // the start index should be `flushIndex + 1` let start = flushIndex + 1; let end = runtime_core_esm_bundler_queue.length; while (start < end) { const middle = (start + end) >>> 1; const middleJobId = getId(runtime_core_esm_bundler_queue[middle]); middleJobId < id ? (start = middle + 1) : (end = middle); } return start; } function queueJob(job) { // the dedupe search uses the startIndex argument of Array.includes() // by default the search index includes the current job that is being run // so it cannot recursively trigger itself again. // if the job is a watch() callback, the search will start with a +1 index to // allow it recursively trigger itself - it is the user's responsibility to // ensure it doesn't end up in an infinite loop. if ((!runtime_core_esm_bundler_queue.length || !runtime_core_esm_bundler_queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) && job !== currentPreFlushParentJob) { if (job.id == null) { runtime_core_esm_bundler_queue.push(job); } else { runtime_core_esm_bundler_queue.splice(findInsertionIndex(job.id), 0, job); } queueFlush(); } } function queueFlush() { if (!isFlushing && !isFlushPending) { isFlushPending = true; currentFlushPromise = resolvedPromise.then(flushJobs); } } function invalidateJob(job) { const i = runtime_core_esm_bundler_queue.indexOf(job); if (i > flushIndex) { runtime_core_esm_bundler_queue.splice(i, 1); } } function queueCb(cb, activeQueue, pendingQueue, index) { if (!(0,shared_esm_bundler.isArray)(cb)) { if (!activeQueue || !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) { pendingQueue.push(cb); } } else { // if cb is an array, it is a component lifecycle hook which can only be // triggered by a job, which is already deduped in the main queue, so // we can skip duplicate check here to improve perf pendingQueue.push(...cb); } queueFlush(); } function queuePreFlushCb(cb) { queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); } function queuePostFlushCb(cb) { queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); } function flushPreFlushCbs(seen, parentJob = null) { if (pendingPreFlushCbs.length) { currentPreFlushParentJob = parentJob; activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; pendingPreFlushCbs.length = 0; if ((false)) {} for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { if (false) {} activePreFlushCbs[preFlushIndex](); } activePreFlushCbs = null; preFlushIndex = 0; currentPreFlushParentJob = null; // recursively flush until it drains flushPreFlushCbs(seen, parentJob); } } function flushPostFlushCbs(seen) { if (pendingPostFlushCbs.length) { const deduped = [...new Set(pendingPostFlushCbs)]; pendingPostFlushCbs.length = 0; // #1947 already has active queue, nested flushPostFlushCbs call if (activePostFlushCbs) { activePostFlushCbs.push(...deduped); return; } activePostFlushCbs = deduped; if ((false)) {} activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { if (false) {} activePostFlushCbs[postFlushIndex](); } activePostFlushCbs = null; postFlushIndex = 0; } } const getId = (job) => job.id == null ? Infinity : job.id; function flushJobs(seen) { isFlushPending = false; isFlushing = true; if ((false)) {} flushPreFlushCbs(seen); // Sort queue before flush. // This ensures that: // 1. Components are updated from parent to child. (because parent is always // created before the child so its render effect will have smaller // priority number) // 2. If a component is unmounted during a parent component's update, // its update can be skipped. runtime_core_esm_bundler_queue.sort((a, b) => getId(a) - getId(b)); // conditional usage of checkRecursiveUpdate must be determined out of // try ... catch block since Rollup by default de-optimizes treeshaking // inside try-catch. This can leave all warning code unshaked. Although // they would get eventually shaken by a minifier like terser, some minifiers // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610) const check = ( false) ? 0 : shared_esm_bundler.NOOP; try { for (flushIndex = 0; flushIndex < runtime_core_esm_bundler_queue.length; flushIndex++) { const job = runtime_core_esm_bundler_queue[flushIndex]; if (job && job.active !== false) { if (false) {} // console.log(`running:`, job.id) callWithErrorHandling(job, null, 14 /* SCHEDULER */); } } } finally { flushIndex = 0; runtime_core_esm_bundler_queue.length = 0; flushPostFlushCbs(seen); isFlushing = false; currentFlushPromise = null; // some postFlushCb queued jobs! // keep flushing until it drains. if (runtime_core_esm_bundler_queue.length || pendingPreFlushCbs.length || pendingPostFlushCbs.length) { flushJobs(seen); } } } function checkRecursiveUpdates(seen, fn) { if (!seen.has(fn)) { seen.set(fn, 1); } else { const count = seen.get(fn); if (count > RECURSION_LIMIT) { const instance = fn.ownerInstance; const componentName = instance && getComponentName(instance.type); runtime_core_esm_bundler_warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` + `This means you have a reactive effect that is mutating its own ` + `dependencies and thus recursively triggering itself. Possible sources ` + `include component template, render function, updated hook or ` + `watcher source function.`); return true; } else { seen.set(fn, count + 1); } } } // Simple effect. function watchEffect(effect, options) { return doWatch(effect, null, options); } function watchPostEffect(effect, options) { return doWatch(effect, null, (( false) ? 0 : { flush: 'post' })); } function watchSyncEffect(effect, options) { return doWatch(effect, null, (( false) ? 0 : { flush: 'sync' })); } // initial value for watchers to trigger on undefined initial values const INITIAL_WATCHER_VALUE = {}; // implementation function watch(source, cb, options) { if (false) {} return doWatch(source, cb, options); } function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = shared_esm_bundler.EMPTY_OBJ) { if (false) {} const warnInvalidSource = (s) => { runtime_core_esm_bundler_warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` + `a reactive object, or an array of these types.`); }; const instance = currentInstance; let getter; let forceTrigger = false; let isMultiSource = false; if (isRef(source)) { getter = () => source.value; forceTrigger = !!source._shallow; } else if (isReactive(source)) { getter = () => source; deep = true; } else if ((0,shared_esm_bundler.isArray)(source)) { isMultiSource = true; forceTrigger = source.some(isReactive); getter = () => source.map(s => { if (isRef(s)) { return s.value; } else if (isReactive(s)) { return traverse(s); } else if ((0,shared_esm_bundler.isFunction)(s)) { return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */); } else { ( false) && 0; } }); } else if ((0,shared_esm_bundler.isFunction)(source)) { if (cb) { // getter with cb getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */); } else { // no cb -> simple effect getter = () => { if (instance && instance.isUnmounted) { return; } if (cleanup) { cleanup(); } return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]); }; } } else { getter = shared_esm_bundler.NOOP; ( false) && 0; } if (cb && deep) { const baseGetter = getter; getter = () => traverse(baseGetter()); } let cleanup; let onInvalidate = (fn) => { cleanup = effect.onStop = () => { callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */); }; }; // in SSR there is no need to setup an actual effect, and it should be noop // unless it's eager if (isInSSRComponentSetup) { // we will also not call the invalidate callback (+ runner is not set up) onInvalidate = shared_esm_bundler.NOOP; if (!cb) { getter(); } else if (immediate) { callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [ getter(), isMultiSource ? [] : undefined, onInvalidate ]); } return shared_esm_bundler.NOOP; } let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE; const job = () => { if (!effect.active) { return; } if (cb) { // watch(source, cb) const newValue = effect.run(); if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => (0,shared_esm_bundler.hasChanged)(v, oldValue[i])) : (0,shared_esm_bundler.hasChanged)(newValue, oldValue)) || (false )) { // cleanup before running cb again if (cleanup) { cleanup(); } callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [ newValue, // pass undefined as the old value when it's changed for the first time oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, onInvalidate ]); oldValue = newValue; } } else { // watchEffect effect.run(); } }; // important: mark the job as a watcher callback so that scheduler knows // it is allowed to self-trigger (#1727) job.allowRecurse = !!cb; let scheduler; if (flush === 'sync') { scheduler = job; // the scheduler function gets called directly } else if (flush === 'post') { scheduler = () => queuePostRenderEffect(job, instance && instance.suspense); } else { // default: 'pre' scheduler = () => { if (!instance || instance.isMounted) { queuePreFlushCb(job); } else { // with 'pre' option, the first call must happen before // the component is mounted so it is called synchronously. job(); } }; } const effect = new ReactiveEffect(getter, scheduler); if ((false)) {} // initial run if (cb) { if (immediate) { job(); } else { oldValue = effect.run(); } } else if (flush === 'post') { queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense); } else { effect.run(); } return () => { effect.stop(); if (instance && instance.scope) { (0,shared_esm_bundler.remove)(instance.scope.effects, effect); } }; } // this.$watch function instanceWatch(source, value, options) { const publicThis = this.proxy; const getter = (0,shared_esm_bundler.isString)(source) ? source.includes('.') ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis, publicThis); let cb; if ((0,shared_esm_bundler.isFunction)(value)) { cb = value; } else { cb = value.handler; options = value; } const cur = currentInstance; setCurrentInstance(this); const res = doWatch(getter, cb.bind(publicThis), options); if (cur) { setCurrentInstance(cur); } else { unsetCurrentInstance(); } return res; } function createPathGetter(ctx, path) { const segments = path.split('.'); return () => { let cur = ctx; for (let i = 0; i < segments.length && cur; i++) { cur = cur[segments[i]]; } return cur; }; } function traverse(value, seen) { if (!(0,shared_esm_bundler.isObject)(value) || value["__v_skip" /* SKIP */]) { return value; } seen = seen || new Set(); if (seen.has(value)) { return value; } seen.add(value); if (isRef(value)) { traverse(value.value, seen); } else if ((0,shared_esm_bundler.isArray)(value)) { for (let i = 0; i < value.length; i++) { traverse(value[i], seen); } } else if ((0,shared_esm_bundler.isSet)(value) || (0,shared_esm_bundler.isMap)(value)) { value.forEach((v) => { traverse(v, seen); }); } else if ((0,shared_esm_bundler.isPlainObject)(value)) { for (const key in value) { traverse(value[key], seen); } } return value; } // dev only const warnRuntimeUsage = (method) => runtime_core_esm_bundler_warn(`${method}() is a compiler-hint helper that is only usable inside ` + `<script setup> of a single file component. Its arguments should be ` + `compiled away and passing it at runtime has no effect.`); // implementation function defineProps() { if ((false)) {} return null; } // implementation function defineEmits() { if ((false)) {} return null; } /** * Vue `<script setup>` compiler macro for declaring a component's exposed * instance properties when it is accessed by a parent component via template * refs. * * `<script setup>` components are closed by default - i.e. varaibles inside * the `<script setup>` scope is not exposed to parent unless explicitly exposed * via `defineExpose`. * * This is only usable inside `<script setup>`, is compiled away in the * output and should **not** be actually called at runtime. */ function defineExpose(exposed) { if ((false)) {} } /** * Vue `<script setup>` compiler macro for providing props default values when * using type-based `defineProps` declaration. * * Example usage: * ```ts * withDefaults(defineProps<{ * size?: number * labels?: string[] * }>(), { * size: 3, * labels: () => ['default label'] * }) * ``` * * This is only usable inside `<script setup>`, is compiled away in the output * and should **not** be actually called at runtime. */ function withDefaults(props, defaults) { if ((false)) {} return null; } function useSlots() { return getContext().slots; } function useAttrs() { return getContext().attrs; } function getContext() { const i = getCurrentInstance(); if (false) {} return i.setupContext || (i.setupContext = createSetupContext(i)); } /** * Runtime helper for merging default declarations. Imported by compiled code * only. * @internal */ function mergeDefaults(raw, defaults) { const props = (0,shared_esm_bundler.isArray)(raw) ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {}) : raw; for (const key in defaults) { const opt = props[key]; if (opt) { if ((0,shared_esm_bundler.isArray)(opt) || (0,shared_esm_bundler.isFunction)(opt)) { props[key] = { type: opt, default: defaults[key] }; } else { opt.default = defaults[key]; } } else if (opt === null) { props[key] = { default: defaults[key] }; } else if ((false)) {} } return props; } /** * Used to create a proxy for the rest element when destructuring props with * defineProps(). * @internal */ function createPropsRestProxy(props, excludedKeys) { const ret = {}; for (const key in props) { if (!excludedKeys.includes(key)) { Object.defineProperty(ret, key, { enumerable: true, get: () => props[key] }); } } return ret; } /** * `<script setup>` helper for persisting the current instance context over * async/await flows. * * `@vue/compiler-sfc` converts the following: * * ```ts * const x = await foo() * ``` * * into: * * ```ts * let __temp, __restore * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp) * ``` * @internal */ function withAsyncContext(getAwaitable) { const ctx = getCurrentInstance(); if (false) {} let awaitable = getAwaitable(); unsetCurrentInstance(); if ((0,shared_esm_bundler.isPromise)(awaitable)) { awaitable = awaitable.catch(e => { setCurrentInstance(ctx); throw e; }); } return [awaitable, () => setCurrentInstance(ctx)]; } // Actual implementation function h(type, propsOrChildren, children) { const l = arguments.length; if (l === 2) { if ((0,shared_esm_bundler.isObject)(propsOrChildren) && !(0,shared_esm_bundler.isArray)(propsOrChildren)) { // single vnode without props if (isVNode(propsOrChildren)) { return createVNode(type, null, [propsOrChildren]); } // props without children return createVNode(type, propsOrChildren); } else { // omit props return createVNode(type, null, propsOrChildren); } } else { if (l > 3) { children = Array.prototype.slice.call(arguments, 2); } else if (l === 3 && isVNode(children)) { children = [children]; } return createVNode(type, propsOrChildren, children); } } const ssrContextKey = Symbol(( false) ? 0 : ``); const useSSRContext = () => { { const ctx = inject(ssrContextKey); if (!ctx) { runtime_core_esm_bundler_warn(`Server rendering context not provided. Make sure to only call ` + `useSSRContext() conditionally in the server build.`); } return ctx; } }; function initCustomFormatter() { /* eslint-disable no-restricted-globals */ if (true) { return; } const vueStyle = { style: 'color:#3ba776' }; const numberStyle = { style: 'color:#0b1bc9' }; const stringStyle = { style: 'color:#b62e24' }; const keywordStyle = { style: 'color:#9d288c' }; // custom formatter for Chrome // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html const formatter = { header(obj) { // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup if (!(0,shared_esm_bundler.isObject)(obj)) { return null; } if (obj.__isVue) { return ['div', vueStyle, `VueInstance`]; } else if (isRef(obj)) { return [ 'div', {}, ['span', vueStyle, genRefFlag(obj)], '<', formatValue(obj.value), `>` ]; } else if (isReactive(obj)) { return [ 'div', {}, ['span', vueStyle, 'Reactive'], '<', formatValue(obj), `>${isReadonly(obj) ? ` (readonly)` : ``}` ]; } else if (isReadonly(obj)) { return [ 'div', {}, ['span', vueStyle, 'Readonly'], '<', formatValue(obj), '>' ]; } return null; }, hasBody(obj) { return obj && obj.__isVue; }, body(obj) { if (obj && obj.__isVue) { return [ 'div', {}, ...formatInstance(obj.$) ]; } } }; function formatInstance(instance) { const blocks = []; if (instance.type.props && instance.props) { blocks.push(createInstanceBlock('props', reactivity_esm_bundler_toRaw(instance.props))); } if (instance.setupState !== shared_esm_bundler.EMPTY_OBJ) { blocks.push(createInstanceBlock('setup', instance.setupState)); } if (instance.data !== shared_esm_bundler.EMPTY_OBJ) { blocks.push(createInstanceBlock('data', reactivity_esm_bundler_toRaw(instance.data))); } const computed = extractKeys(instance, 'computed'); if (computed) { blocks.push(createInstanceBlock('computed', computed)); } const injected = extractKeys(instance, 'inject'); if (injected) { blocks.push(createInstanceBlock('injected', injected)); } blocks.push([ 'div', {}, [ 'span', { style: keywordStyle.style + ';opacity:0.66' }, '$ (internal): ' ], ['object', { object: instance }] ]); return blocks; } function createInstanceBlock(type, target) { target = (0,shared_esm_bundler.extend)({}, target); if (!Object.keys(target).length) { return ['span', {}]; } return [ 'div', { style: 'line-height:1.25em;margin-bottom:0.6em' }, [ 'div', { style: 'color:#476582' }, type ], [ 'div', { style: 'padding-left:1.25em' }, ...Object.keys(target).map(key => { return [ 'div', {}, ['span', keywordStyle, key + ': '], formatValue(target[key], false) ]; }) ] ]; } function formatValue(v, asRaw = true) { if (typeof v === 'number') { return ['span', numberStyle, v]; } else if (typeof v === 'string') { return ['span', stringStyle, JSON.stringify(v)]; } else if (typeof v === 'boolean') { return ['span', keywordStyle, v]; } else if ((0,shared_esm_bundler.isObject)(v)) { return ['object', { object: asRaw ? reactivity_esm_bundler_toRaw(v) : v }]; } else { return ['span', stringStyle, String(v)]; } } function extractKeys(instance, type) { const Comp = instance.type; if ((0,shared_esm_bundler.isFunction)(Comp)) { return; } const extracted = {}; for (const key in instance.ctx) { if (isKeyOfType(Comp, key, type)) { extracted[key] = instance.ctx[key]; } } return extracted; } function isKeyOfType(Comp, key, type) { const opts = Comp[type]; if (((0,shared_esm_bundler.isArray)(opts) && opts.includes(key)) || ((0,shared_esm_bundler.isObject)(opts) && key in opts)) { return true; } if (Comp.extends && isKeyOfType(Comp.extends, key, type)) { return true; } if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) { return true; } } function genRefFlag(v) { if (v._shallow) { return `ShallowRef`; } if (v.effect) { return `ComputedRef`; } return `Ref`; } if (window.devtoolsFormatters) { window.devtoolsFormatters.push(formatter); } else { window.devtoolsFormatters = [formatter]; } } function withMemo(memo, render, cache, index) { const cached = cache[index]; if (cached && isMemoSame(cached, memo)) { return cached; } const ret = render(); // shallow clone ret.memo = memo.slice(); return (cache[index] = ret); } function isMemoSame(cached, memo) { const prev = cached.memo; if (prev.length != memo.length) { return false; } for (let i = 0; i < prev.length; i++) { if (prev[i] !== memo[i]) { return false; } } // make sure to let parent block track it when returning cached if (isBlockTreeEnabled > 0 && currentBlock) { currentBlock.push(cached); } return true; } // Core API ------------------------------------------------------------------ const version = "3.2.22"; const _ssrUtils = { createComponentInstance, setupComponent, renderComponentRoot, setCurrentRenderingInstance, isVNode, normalizeVNode }; /** * SSR utils for \@vue/server-renderer. Only exposed in cjs builds. * @internal */ const ssrUtils = (_ssrUtils ); /** * @internal only exposed in compat builds */ const resolveFilter = null; /** * @internal only exposed in compat builds. */ const compatUtils = (null); ;// CONCATENATED MODULE: ./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js const svgNS = 'http://www.w3.org/2000/svg'; const doc = (typeof document !== 'undefined' ? document : null); const staticTemplateCache = new Map(); const nodeOps = { insert: (child, parent, anchor) => { parent.insertBefore(child, anchor || null); }, remove: child => { const parent = child.parentNode; if (parent) { parent.removeChild(child); } }, createElement: (tag, isSVG, is, props) => { const el = isSVG ? doc.createElementNS(svgNS, tag) : doc.createElement(tag, is ? { is } : undefined); if (tag === 'select' && props && props.multiple != null) { el.setAttribute('multiple', props.multiple); } return el; }, createText: text => doc.createTextNode(text), createComment: text => doc.createComment(text), setText: (node, text) => { node.nodeValue = text; }, setElementText: (el, text) => { el.textContent = text; }, parentNode: node => node.parentNode, nextSibling: node => node.nextSibling, querySelector: selector => doc.querySelector(selector), setScopeId(el, id) { el.setAttribute(id, ''); }, cloneNode(el) { const cloned = el.cloneNode(true); // #3072 // - in `patchDOMProp`, we store the actual value in the `el._value` property. // - normally, elements using `:value` bindings will not be hoisted, but if // the bound value is a constant, e.g. `:value="true"` - they do get // hoisted. // - in production, hoisted nodes are cloned when subsequent inserts, but // cloneNode() does not copy the custom property we attached. // - This may need to account for other custom DOM properties we attach to // elements in addition to `_value` in the future. if (`_value` in el) { cloned._value = el._value; } return cloned; }, // __UNSAFE__ // Reason: innerHTML. // Static content here can only come from compiled templates. // As long as the user only uses trusted templates, this is safe. insertStaticContent(content, parent, anchor, isSVG) { // <parent> before | first ... last | anchor </parent> const before = anchor ? anchor.previousSibling : parent.lastChild; let template = staticTemplateCache.get(content); if (!template) { const t = doc.createElement('template'); t.innerHTML = isSVG ? `<svg>${content}</svg>` : content; template = t.content; if (isSVG) { // remove outer svg wrapper const wrapper = template.firstChild; while (wrapper.firstChild) { template.appendChild(wrapper.firstChild); } template.removeChild(wrapper); } staticTemplateCache.set(content, template); } parent.insertBefore(template.cloneNode(true), anchor); return [ // first before ? before.nextSibling : parent.firstChild, // last anchor ? anchor.previousSibling : parent.lastChild ]; } }; // compiler should normalize class + :class bindings on the same element // into a single binding ['staticClass', dynamic] function patchClass(el, value, isSVG) { // directly setting className should be faster than setAttribute in theory // if this is an element during a transition, take the temporary transition // classes into account. const transitionClasses = el._vtc; if (transitionClasses) { value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' '); } if (value == null) { el.removeAttribute('class'); } else if (isSVG) { el.setAttribute('class', value); } else { el.className = value; } } function patchStyle(el, prev, next) { const style = el.style; const isCssString = (0,shared_esm_bundler.isString)(next); if (next && !isCssString) { for (const key in next) { setStyle(style, key, next[key]); } if (prev && !(0,shared_esm_bundler.isString)(prev)) { for (const key in prev) { if (next[key] == null) { setStyle(style, key, ''); } } } } else { const currentDisplay = style.display; if (isCssString) { if (prev !== next) { style.cssText = next; } } else if (prev) { el.removeAttribute('style'); } // indicates that the `display` of the element is controlled by `v-show`, // so we always keep the current `display` value regardless of the `style` // value, thus handing over control to `v-show`. if ('_vod' in el) { style.display = currentDisplay; } } } const importantRE = /\s*!important$/; function setStyle(style, name, val) { if ((0,shared_esm_bundler.isArray)(val)) { val.forEach(v => setStyle(style, name, v)); } else { if (name.startsWith('--')) { // custom property definition style.setProperty(name, val); } else { const prefixed = autoPrefix(style, name); if (importantRE.test(val)) { // !important style.setProperty((0,shared_esm_bundler.hyphenate)(prefixed), val.replace(importantRE, ''), 'important'); } else { style[prefixed] = val; } } } } const prefixes = ['Webkit', 'Moz', 'ms']; const prefixCache = {}; function autoPrefix(style, rawName) { const cached = prefixCache[rawName]; if (cached) { return cached; } let name = (0,shared_esm_bundler.camelize)(rawName); if (name !== 'filter' && name in style) { return (prefixCache[rawName] = name); } name = (0,shared_esm_bundler.capitalize)(name); for (let i = 0; i < prefixes.length; i++) { const prefixed = prefixes[i] + name; if (prefixed in style) { return (prefixCache[rawName] = prefixed); } } return rawName; } const xlinkNS = 'http://www.w3.org/1999/xlink'; function patchAttr(el, key, value, isSVG, instance) { if (isSVG && key.startsWith('xlink:')) { if (value == null) { el.removeAttributeNS(xlinkNS, key.slice(6, key.length)); } else { el.setAttributeNS(xlinkNS, key, value); } } else { // note we are only checking boolean attributes that don't have a // corresponding dom prop of the same name here. const isBoolean = (0,shared_esm_bundler.isSpecialBooleanAttr)(key); if (value == null || (isBoolean && !(0,shared_esm_bundler.includeBooleanAttr)(value))) { el.removeAttribute(key); } else { el.setAttribute(key, isBoolean ? '' : value); } } } // __UNSAFE__ // functions. The user is responsible for using them with only trusted content. function patchDOMProp(el, key, value, // the following args are passed only due to potential innerHTML/textContent // overriding existing VNodes, in which case the old tree must be properly // unmounted. prevChildren, parentComponent, parentSuspense, unmountChildren) { if (key === 'innerHTML' || key === 'textContent') { if (prevChildren) { unmountChildren(prevChildren, parentComponent, parentSuspense); } el[key] = value == null ? '' : value; return; } if (key === 'value' && el.tagName !== 'PROGRESS') { // store value as _value as well since // non-string values will be stringified. el._value = value; const newValue = value == null ? '' : value; if (el.value !== newValue) { el.value = newValue; } if (value == null) { el.removeAttribute(key); } return; } if (value === '' || value == null) { const type = typeof el[key]; if (type === 'boolean') { // e.g. <select multiple> compiles to { multiple: '' } el[key] = (0,shared_esm_bundler.includeBooleanAttr)(value); return; } else if (value == null && type === 'string') { // e.g. <div :id="null"> el[key] = ''; el.removeAttribute(key); return; } else if (type === 'number') { // e.g. <img :width="null"> // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error try { el[key] = 0; } catch (_a) { } el.removeAttribute(key); return; } } // some properties perform value validation and throw try { el[key] = value; } catch (e) { if ((false)) {} } } // Async edge case fix requires storing an event listener's attach timestamp. let _getNow = Date.now; let skipTimestampCheck = false; if (typeof window !== 'undefined') { // Determine what event timestamp the browser is using. Annoyingly, the // timestamp can either be hi-res (relative to page load) or low-res // (relative to UNIX epoch), so in order to compare time we have to use the // same timestamp type when saving the flush timestamp. if (_getNow() > document.createEvent('Event').timeStamp) { // if the low-res timestamp which is bigger than the event timestamp // (which is evaluated AFTER) it means the event is using a hi-res timestamp, // and we need to use the hi-res version for event listeners as well. _getNow = () => performance.now(); } // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation // and does not fire microtasks in between event propagation, so safe to exclude. const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i); skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53); } // To avoid the overhead of repeatedly calling performance.now(), we cache // and use the same timestamp for all event listeners attached in the same tick. let cachedNow = 0; const p = Promise.resolve(); const runtime_dom_esm_bundler_reset = () => { cachedNow = 0; }; const getNow = () => cachedNow || (p.then(runtime_dom_esm_bundler_reset), (cachedNow = _getNow())); function addEventListener(el, event, handler, options) { el.addEventListener(event, handler, options); } function removeEventListener(el, event, handler, options) { el.removeEventListener(event, handler, options); } function patchEvent(el, rawName, prevValue, nextValue, instance = null) { // vei = vue event invokers const invokers = el._vei || (el._vei = {}); const existingInvoker = invokers[rawName]; if (nextValue && existingInvoker) { // patch existingInvoker.value = nextValue; } else { const [name, options] = parseName(rawName); if (nextValue) { // add const invoker = (invokers[rawName] = createInvoker(nextValue, instance)); addEventListener(el, name, invoker, options); } else if (existingInvoker) { // remove removeEventListener(el, name, existingInvoker, options); invokers[rawName] = undefined; } } } const optionsModifierRE = /(?:Once|Passive|Capture)$/; function parseName(name) { let options; if (optionsModifierRE.test(name)) { options = {}; let m; while ((m = name.match(optionsModifierRE))) { name = name.slice(0, name.length - m[0].length); options[m[0].toLowerCase()] = true; } } return [(0,shared_esm_bundler.hyphenate)(name.slice(2)), options]; } function createInvoker(initialValue, instance) { const invoker = (e) => { // async edge case #6566: inner click event triggers patch, event handler // attached to outer element during patch, and triggered again. This // happens because browsers fire microtask ticks between event propagation. // the solution is simple: we save the timestamp when a handler is attached, // and the handler would only fire if the event passed to it was fired // AFTER it was attached. const timeStamp = e.timeStamp || _getNow(); if (skipTimestampCheck || timeStamp >= invoker.attached - 1) { callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]); } }; invoker.value = initialValue; invoker.attached = getNow(); return invoker; } function patchStopImmediatePropagation(e, value) { if ((0,shared_esm_bundler.isArray)(value)) { const originalStop = e.stopImmediatePropagation; e.stopImmediatePropagation = () => { originalStop.call(e); e._stopped = true; }; return value.map(fn => (e) => !e._stopped && fn(e)); } else { return value; } } const nativeOnRE = /^on[a-z]/; const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => { if (key === 'class') { patchClass(el, nextValue, isSVG); } else if (key === 'style') { patchStyle(el, prevValue, nextValue); } else if ((0,shared_esm_bundler.isOn)(key)) { // ignore v-model listeners if (!(0,shared_esm_bundler.isModelListener)(key)) { patchEvent(el, key, prevValue, nextValue, parentComponent); } } else if (key[0] === '.' ? ((key = key.slice(1)), true) : key[0] === '^' ? ((key = key.slice(1)), false) : shouldSetAsProp(el, key, nextValue, isSVG)) { patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren); } else { // special case for <input v-model type="checkbox"> with // :true-value & :false-value // store value as dom properties since non-string values will be // stringified. if (key === 'true-value') { el._trueValue = nextValue; } else if (key === 'false-value') { el._falseValue = nextValue; } patchAttr(el, key, nextValue, isSVG); } }; function shouldSetAsProp(el, key, value, isSVG) { if (isSVG) { // most keys must be set as attribute on svg elements to work // ...except innerHTML & textContent if (key === 'innerHTML' || key === 'textContent') { return true; } // or native onclick with function values if (key in el && nativeOnRE.test(key) && (0,shared_esm_bundler.isFunction)(value)) { return true; } return false; } // spellcheck and draggable are numerated attrs, however their // corresponding DOM properties are actually booleans - this leads to // setting it with a string "false" value leading it to be coerced to // `true`, so we need to always treat them as attributes. // Note that `contentEditable` doesn't have this problem: its DOM // property is also enumerated string values. if (key === 'spellcheck' || key === 'draggable') { return false; } // #1787, #2840 form property on form elements is readonly and must be set as // attribute. if (key === 'form') { return false; } // #1526 <input list> must be set as attribute if (key === 'list' && el.tagName === 'INPUT') { return false; } // #2766 <textarea type> must be set as attribute if (key === 'type' && el.tagName === 'TEXTAREA') { return false; } // native onclick with string value, must be set as attribute if (nativeOnRE.test(key) && (0,shared_esm_bundler.isString)(value)) { return false; } return key in el; } function defineCustomElement(options, hydate) { const Comp = defineComponent(options); class VueCustomElement extends VueElement { constructor(initialProps) { super(Comp, initialProps, hydate); } } VueCustomElement.def = Comp; return VueCustomElement; } const defineSSRCustomElement = ((options) => { // @ts-ignore return defineCustomElement(options, hydrate); }); const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class { }); class VueElement extends BaseClass { constructor(_def, _props = {}, hydrate) { super(); this._def = _def; this._props = _props; /** * @internal */ this._instance = null; this._connected = false; this._resolved = false; this._numberProps = null; if (this.shadowRoot && hydrate) { hydrate(this._createVNode(), this.shadowRoot); } else { if (false) {} this.attachShadow({ mode: 'open' }); } } connectedCallback() { this._connected = true; if (!this._instance) { this._resolveDef(); } } disconnectedCallback() { this._connected = false; nextTick(() => { if (!this._connected) { render(null, this.shadowRoot); this._instance = null; } }); } /** * resolve inner component definition (handle possible async component) */ _resolveDef() { if (this._resolved) { return; } this._resolved = true; // set initial attrs for (let i = 0; i < this.attributes.length; i++) { this._setAttr(this.attributes[i].name); } // watch future attr changes new MutationObserver(mutations => { for (const m of mutations) { this._setAttr(m.attributeName); } }).observe(this, { attributes: true }); const resolve = (def) => { const { props, styles } = def; const hasOptions = !(0,shared_esm_bundler.isArray)(props); const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []; // cast Number-type props set before resolve let numberProps; if (hasOptions) { for (const key in this._props) { const opt = props[key]; if (opt === Number || (opt && opt.type === Number)) { this._props[key] = (0,shared_esm_bundler.toNumber)(this._props[key]); (numberProps || (numberProps = Object.create(null)))[key] = true; } } } this._numberProps = numberProps; // check if there are props set pre-upgrade or connect for (const key of Object.keys(this)) { if (key[0] !== '_') { this._setProp(key, this[key], true, false); } } // defining getter/setters on prototype for (const key of rawKeys.map(shared_esm_bundler.camelize)) { Object.defineProperty(this, key, { get() { return this._getProp(key); }, set(val) { this._setProp(key, val); } }); } // apply CSS this._applyStyles(styles); // initial render this._update(); }; const asyncDef = this._def.__asyncLoader; if (asyncDef) { asyncDef().then(resolve); } else { resolve(this._def); } } _setAttr(key) { let value = this.getAttribute(key); if (this._numberProps && this._numberProps[key]) { value = (0,shared_esm_bundler.toNumber)(value); } this._setProp((0,shared_esm_bundler.camelize)(key), value, false); } /** * @internal */ _getProp(key) { return this._props[key]; } /** * @internal */ _setProp(key, val, shouldReflect = true, shouldUpdate = true) { if (val !== this._props[key]) { this._props[key] = val; if (shouldUpdate && this._instance) { this._update(); } // reflect if (shouldReflect) { if (val === true) { this.setAttribute((0,shared_esm_bundler.hyphenate)(key), ''); } else if (typeof val === 'string' || typeof val === 'number') { this.setAttribute((0,shared_esm_bundler.hyphenate)(key), val + ''); } else if (!val) { this.removeAttribute((0,shared_esm_bundler.hyphenate)(key)); } } } } _update() { render(this._createVNode(), this.shadowRoot); } _createVNode() { const vnode = createVNode(this._def, (0,shared_esm_bundler.extend)({}, this._props)); if (!this._instance) { vnode.ce = instance => { this._instance = instance; instance.isCE = true; // HMR if ((false)) {} // intercept emit instance.emit = (event, ...args) => { this.dispatchEvent(new CustomEvent(event, { detail: args })); }; // locate nearest Vue custom element parent for provide/inject let parent = this; while ((parent = parent && (parent.parentNode || parent.host))) { if (parent instanceof VueElement) { instance.parent = parent._instance; break; } } }; } return vnode; } _applyStyles(styles) { if (styles) { styles.forEach(css => { const s = document.createElement('style'); s.textContent = css; this.shadowRoot.appendChild(s); // record for HMR if ((false)) {} }); } } } function useCssModule(name = '$style') { /* istanbul ignore else */ { const instance = getCurrentInstance(); if (!instance) { ( false) && 0; return shared_esm_bundler.EMPTY_OBJ; } const modules = instance.type.__cssModules; if (!modules) { ( false) && 0; return shared_esm_bundler.EMPTY_OBJ; } const mod = modules[name]; if (!mod) { ( false) && 0; return shared_esm_bundler.EMPTY_OBJ; } return mod; } } /** * Runtime helper for SFC's CSS variable injection feature. * @private */ function useCssVars(getter) { const instance = getCurrentInstance(); /* istanbul ignore next */ if (!instance) { ( false) && 0; return; } const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy)); watchPostEffect(setVars); onMounted(() => { const ob = new MutationObserver(setVars); ob.observe(instance.subTree.el.parentNode, { childList: true }); onUnmounted(() => ob.disconnect()); }); } function setVarsOnVNode(vnode, vars) { if (vnode.shapeFlag & 128 /* SUSPENSE */) { const suspense = vnode.suspense; vnode = suspense.activeBranch; if (suspense.pendingBranch && !suspense.isHydrating) { suspense.effects.push(() => { setVarsOnVNode(suspense.activeBranch, vars); }); } } // drill down HOCs until it's a non-component vnode while (vnode.component) { vnode = vnode.component.subTree; } if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) { setVarsOnNode(vnode.el, vars); } else if (vnode.type === Fragment) { vnode.children.forEach(c => setVarsOnVNode(c, vars)); } else if (vnode.type === Static) { let { el, anchor } = vnode; while (el) { setVarsOnNode(el, vars); if (el === anchor) break; el = el.nextSibling; } } } function setVarsOnNode(el, vars) { if (el.nodeType === 1) { const style = el.style; for (const key in vars) { style.setProperty(`--${key}`, vars[key]); } } } const TRANSITION = 'transition'; const ANIMATION = 'animation'; // DOM Transition is a higher-order-component based on the platform-agnostic // base Transition component, with DOM-specific logic. const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots); Transition.displayName = 'Transition'; const DOMTransitionPropsValidators = { name: String, type: String, css: { type: Boolean, default: true }, duration: [String, Number, Object], enterFromClass: String, enterActiveClass: String, enterToClass: String, appearFromClass: String, appearActiveClass: String, appearToClass: String, leaveFromClass: String, leaveActiveClass: String, leaveToClass: String }; const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ (0,shared_esm_bundler.extend)({}, BaseTransition.props, DOMTransitionPropsValidators)); /** * #3227 Incoming hooks may be merged into arrays when wrapping Transition * with custom HOCs. */ const runtime_dom_esm_bundler_callHook = (hook, args = []) => { if ((0,shared_esm_bundler.isArray)(hook)) { hook.forEach(h => h(...args)); } else if (hook) { hook(...args); } }; /** * Check if a hook expects a callback (2nd arg), which means the user * intends to explicitly control the end of the transition. */ const hasExplicitCallback = (hook) => { return hook ? (0,shared_esm_bundler.isArray)(hook) ? hook.some(h => h.length > 1) : hook.length > 1 : false; }; function resolveTransitionProps(rawProps) { const baseProps = {}; for (const key in rawProps) { if (!(key in DOMTransitionPropsValidators)) { baseProps[key] = rawProps[key]; } } if (rawProps.css === false) { return baseProps; } const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps; const durations = normalizeDuration(duration); const enterDuration = durations && durations[0]; const leaveDuration = durations && durations[1]; const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps; const finishEnter = (el, isAppear, done) => { removeTransitionClass(el, isAppear ? appearToClass : enterToClass); removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass); done && done(); }; const finishLeave = (el, done) => { removeTransitionClass(el, leaveToClass); removeTransitionClass(el, leaveActiveClass); done && done(); }; const makeEnterHook = (isAppear) => { return (el, done) => { const hook = isAppear ? onAppear : onEnter; const resolve = () => finishEnter(el, isAppear, done); runtime_dom_esm_bundler_callHook(hook, [el, resolve]); nextFrame(() => { removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass); addTransitionClass(el, isAppear ? appearToClass : enterToClass); if (!hasExplicitCallback(hook)) { whenTransitionEnds(el, type, enterDuration, resolve); } }); }; }; return (0,shared_esm_bundler.extend)(baseProps, { onBeforeEnter(el) { runtime_dom_esm_bundler_callHook(onBeforeEnter, [el]); addTransitionClass(el, enterFromClass); addTransitionClass(el, enterActiveClass); }, onBeforeAppear(el) { runtime_dom_esm_bundler_callHook(onBeforeAppear, [el]); addTransitionClass(el, appearFromClass); addTransitionClass(el, appearActiveClass); }, onEnter: makeEnterHook(false), onAppear: makeEnterHook(true), onLeave(el, done) { const resolve = () => finishLeave(el, done); addTransitionClass(el, leaveFromClass); // force reflow so *-leave-from classes immediately take effect (#2593) forceReflow(); addTransitionClass(el, leaveActiveClass); nextFrame(() => { removeTransitionClass(el, leaveFromClass); addTransitionClass(el, leaveToClass); if (!hasExplicitCallback(onLeave)) { whenTransitionEnds(el, type, leaveDuration, resolve); } }); runtime_dom_esm_bundler_callHook(onLeave, [el, resolve]); }, onEnterCancelled(el) { finishEnter(el, false); runtime_dom_esm_bundler_callHook(onEnterCancelled, [el]); }, onAppearCancelled(el) { finishEnter(el, true); runtime_dom_esm_bundler_callHook(onAppearCancelled, [el]); }, onLeaveCancelled(el) { finishLeave(el); runtime_dom_esm_bundler_callHook(onLeaveCancelled, [el]); } }); } function normalizeDuration(duration) { if (duration == null) { return null; } else if ((0,shared_esm_bundler.isObject)(duration)) { return [NumberOf(duration.enter), NumberOf(duration.leave)]; } else { const n = NumberOf(duration); return [n, n]; } } function NumberOf(val) { const res = (0,shared_esm_bundler.toNumber)(val); if ((false)) {} return res; } function validateDuration(val) { if (typeof val !== 'number') { warn(`<transition> explicit duration is not a valid number - ` + `got ${JSON.stringify(val)}.`); } else if (isNaN(val)) { warn(`<transition> explicit duration is NaN - ` + 'the duration expression might be incorrect.'); } } function addTransitionClass(el, cls) { cls.split(/\s+/).forEach(c => c && el.classList.add(c)); (el._vtc || (el._vtc = new Set())).add(cls); } function removeTransitionClass(el, cls) { cls.split(/\s+/).forEach(c => c && el.classList.remove(c)); const { _vtc } = el; if (_vtc) { _vtc.delete(cls); if (!_vtc.size) { el._vtc = undefined; } } } function nextFrame(cb) { requestAnimationFrame(() => { requestAnimationFrame(cb); }); } let endId = 0; function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) { const id = (el._endId = ++endId); const resolveIfNotStale = () => { if (id === el._endId) { resolve(); } }; if (explicitTimeout) { return setTimeout(resolveIfNotStale, explicitTimeout); } const { type, timeout, propCount } = getTransitionInfo(el, expectedType); if (!type) { return resolve(); } const endEvent = type + 'end'; let ended = 0; const end = () => { el.removeEventListener(endEvent, onEnd); resolveIfNotStale(); }; const onEnd = (e) => { if (e.target === el && ++ended >= propCount) { end(); } }; setTimeout(() => { if (ended < propCount) { end(); } }, timeout + 1); el.addEventListener(endEvent, onEnd); } function getTransitionInfo(el, expectedType) { const styles = window.getComputedStyle(el); // JSDOM may return undefined for transition properties const getStyleProperties = (key) => (styles[key] || '').split(', '); const transitionDelays = getStyleProperties(TRANSITION + 'Delay'); const transitionDurations = getStyleProperties(TRANSITION + 'Duration'); const transitionTimeout = getTimeout(transitionDelays, transitionDurations); const animationDelays = getStyleProperties(ANIMATION + 'Delay'); const animationDurations = getStyleProperties(ANIMATION + 'Duration'); const animationTimeout = getTimeout(animationDelays, animationDurations); let type = null; let timeout = 0; let propCount = 0; /* istanbul ignore if */ if (expectedType === TRANSITION) { if (transitionTimeout > 0) { type = TRANSITION; timeout = transitionTimeout; propCount = transitionDurations.length; } } else if (expectedType === ANIMATION) { if (animationTimeout > 0) { type = ANIMATION; timeout = animationTimeout; propCount = animationDurations.length; } } else { timeout = Math.max(transitionTimeout, animationTimeout); type = timeout > 0 ? transitionTimeout > animationTimeout ? TRANSITION : ANIMATION : null; propCount = type ? type === TRANSITION ? transitionDurations.length : animationDurations.length : 0; } const hasTransform = type === TRANSITION && /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']); return { type, timeout, propCount, hasTransform }; } function getTimeout(delays, durations) { while (delays.length < durations.length) { delays = delays.concat(delays); } return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i]))); } // Old versions of Chromium (below 61.0.3163.100) formats floating pointer // numbers in a locale-dependent way, using a comma instead of a dot. // If comma is not replaced with a dot, the input will be rounded down // (i.e. acting as a floor function) causing unexpected behaviors function toMs(s) { return Number(s.slice(0, -1).replace(',', '.')) * 1000; } // synchronously force layout to put elements into a certain state function forceReflow() { return document.body.offsetHeight; } const positionMap = new WeakMap(); const newPositionMap = new WeakMap(); const TransitionGroupImpl = { name: 'TransitionGroup', props: /*#__PURE__*/ (0,shared_esm_bundler.extend)({}, TransitionPropsValidators, { tag: String, moveClass: String }), setup(props, { slots }) { const instance = getCurrentInstance(); const state = useTransitionState(); let prevChildren; let children; onUpdated(() => { // children is guaranteed to exist after initial render if (!prevChildren.length) { return; } const moveClass = props.moveClass || `${props.name || 'v'}-move`; if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) { return; } // we divide the work into three loops to avoid mixing DOM reads and writes // in each iteration - which helps prevent layout thrashing. prevChildren.forEach(callPendingCbs); prevChildren.forEach(recordPosition); const movedChildren = prevChildren.filter(applyTranslation); // force reflow to put everything in position forceReflow(); movedChildren.forEach(c => { const el = c.el; const style = el.style; addTransitionClass(el, moveClass); style.transform = style.webkitTransform = style.transitionDuration = ''; const cb = (el._moveCb = (e) => { if (e && e.target !== el) { return; } if (!e || /transform$/.test(e.propertyName)) { el.removeEventListener('transitionend', cb); el._moveCb = null; removeTransitionClass(el, moveClass); } }); el.addEventListener('transitionend', cb); }); }); return () => { const rawProps = reactivity_esm_bundler_toRaw(props); const cssTransitionProps = resolveTransitionProps(rawProps); let tag = rawProps.tag || Fragment; prevChildren = children; children = slots.default ? getTransitionRawChildren(slots.default()) : []; for (let i = 0; i < children.length; i++) { const child = children[i]; if (child.key != null) { setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); } else if ((false)) {} } if (prevChildren) { for (let i = 0; i < prevChildren.length; i++) { const child = prevChildren[i]; setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); positionMap.set(child, child.el.getBoundingClientRect()); } } return createVNode(tag, null, children); }; } }; const TransitionGroup = TransitionGroupImpl; function callPendingCbs(c) { const el = c.el; if (el._moveCb) { el._moveCb(); } if (el._enterCb) { el._enterCb(); } } function recordPosition(c) { newPositionMap.set(c, c.el.getBoundingClientRect()); } function applyTranslation(c) { const oldPos = positionMap.get(c); const newPos = newPositionMap.get(c); const dx = oldPos.left - newPos.left; const dy = oldPos.top - newPos.top; if (dx || dy) { const s = c.el.style; s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`; s.transitionDuration = '0s'; return c; } } function hasCSSTransform(el, root, moveClass) { // Detect whether an element with the move class applied has // CSS transitions. Since the element may be inside an entering // transition at this very moment, we make a clone of it and remove // all other transition classes applied to ensure only the move class // is applied. const clone = el.cloneNode(); if (el._vtc) { el._vtc.forEach(cls => { cls.split(/\s+/).forEach(c => c && clone.classList.remove(c)); }); } moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c)); clone.style.display = 'none'; const container = (root.nodeType === 1 ? root : root.parentNode); container.appendChild(clone); const { hasTransform } = getTransitionInfo(clone); container.removeChild(clone); return hasTransform; } const getModelAssigner = (vnode) => { const fn = vnode.props['onUpdate:modelValue']; return (0,shared_esm_bundler.isArray)(fn) ? value => (0,shared_esm_bundler.invokeArrayFns)(fn, value) : fn; }; function onCompositionStart(e) { e.target.composing = true; } function onCompositionEnd(e) { const target = e.target; if (target.composing) { target.composing = false; runtime_dom_esm_bundler_trigger(target, 'input'); } } function runtime_dom_esm_bundler_trigger(el, type) { const e = document.createEvent('HTMLEvents'); e.initEvent(type, true, true); el.dispatchEvent(e); } // We are exporting the v-model runtime directly as vnode hooks so that it can // be tree-shaken in case v-model is never used. const vModelText = { created(el, { modifiers: { lazy, trim, number } }, vnode) { el._assign = getModelAssigner(vnode); const castToNumber = number || (vnode.props && vnode.props.type === 'number'); addEventListener(el, lazy ? 'change' : 'input', e => { if (e.target.composing) return; let domValue = el.value; if (trim) { domValue = domValue.trim(); } else if (castToNumber) { domValue = (0,shared_esm_bundler.toNumber)(domValue); } el._assign(domValue); }); if (trim) { addEventListener(el, 'change', () => { el.value = el.value.trim(); }); } if (!lazy) { addEventListener(el, 'compositionstart', onCompositionStart); addEventListener(el, 'compositionend', onCompositionEnd); // Safari < 10.2 & UIWebView doesn't fire compositionend when // switching focus before confirming composition choice // this also fixes the issue where some browsers e.g. iOS Chrome // fires "change" instead of "input" on autocomplete. addEventListener(el, 'change', onCompositionEnd); } }, // set value on mounted so it's after min/max for type="range" mounted(el, { value }) { el.value = value == null ? '' : value; }, beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) { el._assign = getModelAssigner(vnode); // avoid clearing unresolved text. #2302 if (el.composing) return; if (document.activeElement === el) { if (lazy) { return; } if (trim && el.value.trim() === value) { return; } if ((number || el.type === 'number') && (0,shared_esm_bundler.toNumber)(el.value) === value) { return; } } const newValue = value == null ? '' : value; if (el.value !== newValue) { el.value = newValue; } } }; const vModelCheckbox = { // #4096 array checkboxes need to be deep traversed deep: true, created(el, _, vnode) { el._assign = getModelAssigner(vnode); addEventListener(el, 'change', () => { const modelValue = el._modelValue; const elementValue = getValue(el); const checked = el.checked; const assign = el._assign; if ((0,shared_esm_bundler.isArray)(modelValue)) { const index = (0,shared_esm_bundler.looseIndexOf)(modelValue, elementValue); const found = index !== -1; if (checked && !found) { assign(modelValue.concat(elementValue)); } else if (!checked && found) { const filtered = [...modelValue]; filtered.splice(index, 1); assign(filtered); } } else if ((0,shared_esm_bundler.isSet)(modelValue)) { const cloned = new Set(modelValue); if (checked) { cloned.add(elementValue); } else { cloned.delete(elementValue); } assign(cloned); } else { assign(getCheckboxValue(el, checked)); } }); }, // set initial checked on mount to wait for true-value/false-value mounted: setChecked, beforeUpdate(el, binding, vnode) { el._assign = getModelAssigner(vnode); setChecked(el, binding, vnode); } }; function setChecked(el, { value, oldValue }, vnode) { el._modelValue = value; if ((0,shared_esm_bundler.isArray)(value)) { el.checked = (0,shared_esm_bundler.looseIndexOf)(value, vnode.props.value) > -1; } else if ((0,shared_esm_bundler.isSet)(value)) { el.checked = value.has(vnode.props.value); } else if (value !== oldValue) { el.checked = (0,shared_esm_bundler.looseEqual)(value, getCheckboxValue(el, true)); } } const vModelRadio = { created(el, { value }, vnode) { el.checked = (0,shared_esm_bundler.looseEqual)(value, vnode.props.value); el._assign = getModelAssigner(vnode); addEventListener(el, 'change', () => { el._assign(getValue(el)); }); }, beforeUpdate(el, { value, oldValue }, vnode) { el._assign = getModelAssigner(vnode); if (value !== oldValue) { el.checked = (0,shared_esm_bundler.looseEqual)(value, vnode.props.value); } } }; const vModelSelect = { // <select multiple> value need to be deep traversed deep: true, created(el, { value, modifiers: { number } }, vnode) { const isSetModel = (0,shared_esm_bundler.isSet)(value); addEventListener(el, 'change', () => { const selectedVal = Array.prototype.filter .call(el.options, (o) => o.selected) .map((o) => number ? (0,shared_esm_bundler.toNumber)(getValue(o)) : getValue(o)); el._assign(el.multiple ? isSetModel ? new Set(selectedVal) : selectedVal : selectedVal[0]); }); el._assign = getModelAssigner(vnode); }, // set value in mounted & updated because <select> relies on its children // <option>s. mounted(el, { value }) { setSelected(el, value); }, beforeUpdate(el, _binding, vnode) { el._assign = getModelAssigner(vnode); }, updated(el, { value }) { setSelected(el, value); } }; function setSelected(el, value) { const isMultiple = el.multiple; if (isMultiple && !(0,shared_esm_bundler.isArray)(value) && !(0,shared_esm_bundler.isSet)(value)) { ( false) && 0; return; } for (let i = 0, l = el.options.length; i < l; i++) { const option = el.options[i]; const optionValue = getValue(option); if (isMultiple) { if ((0,shared_esm_bundler.isArray)(value)) { option.selected = (0,shared_esm_bundler.looseIndexOf)(value, optionValue) > -1; } else { option.selected = value.has(optionValue); } } else { if ((0,shared_esm_bundler.looseEqual)(getValue(option), value)) { if (el.selectedIndex !== i) el.selectedIndex = i; return; } } } if (!isMultiple && el.selectedIndex !== -1) { el.selectedIndex = -1; } } // retrieve raw value set via :value bindings function getValue(el) { return '_value' in el ? el._value : el.value; } // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings function getCheckboxValue(el, checked) { const key = checked ? '_trueValue' : '_falseValue'; return key in el ? el[key] : checked; } const vModelDynamic = { created(el, binding, vnode) { callModelHook(el, binding, vnode, null, 'created'); }, mounted(el, binding, vnode) { callModelHook(el, binding, vnode, null, 'mounted'); }, beforeUpdate(el, binding, vnode, prevVNode) { callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate'); }, updated(el, binding, vnode, prevVNode) { callModelHook(el, binding, vnode, prevVNode, 'updated'); } }; function callModelHook(el, binding, vnode, prevVNode, hook) { let modelToUse; switch (el.tagName) { case 'SELECT': modelToUse = vModelSelect; break; case 'TEXTAREA': modelToUse = vModelText; break; default: switch (vnode.props && vnode.props.type) { case 'checkbox': modelToUse = vModelCheckbox; break; case 'radio': modelToUse = vModelRadio; break; default: modelToUse = vModelText; } } const fn = modelToUse[hook]; fn && fn(el, binding, vnode, prevVNode); } // SSR vnode transforms, only used when user includes client-oriented render // function in SSR function initVModelForSSR() { vModelText.getSSRProps = ({ value }) => ({ value }); vModelRadio.getSSRProps = ({ value }, vnode) => { if (vnode.props && (0,shared_esm_bundler.looseEqual)(vnode.props.value, value)) { return { checked: true }; } }; vModelCheckbox.getSSRProps = ({ value }, vnode) => { if ((0,shared_esm_bundler.isArray)(value)) { if (vnode.props && (0,shared_esm_bundler.looseIndexOf)(value, vnode.props.value) > -1) { return { checked: true }; } } else if ((0,shared_esm_bundler.isSet)(value)) { if (vnode.props && value.has(vnode.props.value)) { return { checked: true }; } } else if (value) { return { checked: true }; } }; } const systemModifiers = ['ctrl', 'shift', 'alt', 'meta']; const modifierGuards = { stop: e => e.stopPropagation(), prevent: e => e.preventDefault(), self: e => e.target !== e.currentTarget, ctrl: e => !e.ctrlKey, shift: e => !e.shiftKey, alt: e => !e.altKey, meta: e => !e.metaKey, left: e => 'button' in e && e.button !== 0, middle: e => 'button' in e && e.button !== 1, right: e => 'button' in e && e.button !== 2, exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m)) }; /** * @private */ const withModifiers = (fn, modifiers) => { return (event, ...args) => { for (let i = 0; i < modifiers.length; i++) { const guard = modifierGuards[modifiers[i]]; if (guard && guard(event, modifiers)) return; } return fn(event, ...args); }; }; // Kept for 2.x compat. // Note: IE11 compat for `spacebar` and `del` is removed for now. const keyNames = { esc: 'escape', space: ' ', up: 'arrow-up', left: 'arrow-left', right: 'arrow-right', down: 'arrow-down', delete: 'backspace' }; /** * @private */ const withKeys = (fn, modifiers) => { return (event) => { if (!('key' in event)) { return; } const eventKey = (0,shared_esm_bundler.hyphenate)(event.key); if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) { return fn(event); } }; }; const vShow = { beforeMount(el, { value }, { transition }) { el._vod = el.style.display === 'none' ? '' : el.style.display; if (transition && value) { transition.beforeEnter(el); } else { setDisplay(el, value); } }, mounted(el, { value }, { transition }) { if (transition && value) { transition.enter(el); } }, updated(el, { value, oldValue }, { transition }) { if (!value === !oldValue) return; if (transition) { if (value) { transition.beforeEnter(el); setDisplay(el, true); transition.enter(el); } else { transition.leave(el, () => { setDisplay(el, false); }); } } else { setDisplay(el, value); } }, beforeUnmount(el, { value }) { setDisplay(el, value); } }; function setDisplay(el, value) { el.style.display = value ? el._vod : 'none'; } // SSR vnode transforms, only used when user includes client-oriented render // function in SSR function initVShowForSSR() { vShow.getSSRProps = ({ value }) => { if (!value) { return { style: { display: 'none' } }; } }; } const rendererOptions = (0,shared_esm_bundler.extend)({ patchProp }, nodeOps); // lazy create the renderer - this makes core renderer logic tree-shakable // in case the user only imports reactivity utilities from Vue. let renderer; let enabledHydration = false; function ensureRenderer() { return (renderer || (renderer = createRenderer(rendererOptions))); } function ensureHydrationRenderer() { renderer = enabledHydration ? renderer : createHydrationRenderer(rendererOptions); enabledHydration = true; return renderer; } // use explicit type casts here to avoid import() calls in rolled-up d.ts const render = ((...args) => { ensureRenderer().render(...args); }); const hydrate = ((...args) => { ensureHydrationRenderer().hydrate(...args); }); const createApp = ((...args) => { const app = ensureRenderer().createApp(...args); if ((false)) {} const { mount } = app; app.mount = (containerOrSelector) => { const container = normalizeContainer(containerOrSelector); if (!container) return; const component = app._component; if (!(0,shared_esm_bundler.isFunction)(component) && !component.render && !component.template) { // __UNSAFE__ // Reason: potential execution of JS expressions in in-DOM template. // The user must make sure the in-DOM template is trusted. If it's // rendered by the server, the template should not contain any user data. component.template = container.innerHTML; } // clear content before mounting container.innerHTML = ''; const proxy = mount(container, false, container instanceof SVGElement); if (container instanceof Element) { container.removeAttribute('v-cloak'); container.setAttribute('data-v-app', ''); } return proxy; }; return app; }); const createSSRApp = ((...args) => { const app = ensureHydrationRenderer().createApp(...args); if ((false)) {} const { mount } = app; app.mount = (containerOrSelector) => { const container = normalizeContainer(containerOrSelector); if (container) { return mount(container, true, container instanceof SVGElement); } }; return app; }); function injectNativeTagCheck(app) { // Inject `isNativeTag` // this is used for component name validation (dev only) Object.defineProperty(app.config, 'isNativeTag', { value: (tag) => isHTMLTag(tag) || isSVGTag(tag), writable: false }); } // dev only function injectCompilerOptionsCheck(app) { if (isRuntimeOnly()) { const isCustomElement = app.config.isCustomElement; Object.defineProperty(app.config, 'isCustomElement', { get() { return isCustomElement; }, set() { warn(`The \`isCustomElement\` config option is deprecated. Use ` + `\`compilerOptions.isCustomElement\` instead.`); } }); const compilerOptions = app.config.compilerOptions; const msg = `The \`compilerOptions\` config option is only respected when using ` + `a build of Vue.js that includes the runtime compiler (aka "full build"). ` + `Since you are using the runtime-only build, \`compilerOptions\` ` + `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` + `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` + `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` + `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`; Object.defineProperty(app.config, 'compilerOptions', { get() { warn(msg); return compilerOptions; }, set() { warn(msg); } }); } } function normalizeContainer(container) { if ((0,shared_esm_bundler.isString)(container)) { const res = document.querySelector(container); if (false) {} return res; } if (false) {} return container; } let ssrDirectiveInitialized = false; /** * @internal */ const initDirectivesForSSR = () => { if (!ssrDirectiveInitialized) { ssrDirectiveInitialized = true; initVModelForSSR(); initVShowForSSR(); } } ; /***/ }), /***/ "./node_modules/@vue/shared/dist/shared.esm-bundler.js": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "EMPTY_ARR": () => (/* binding */ EMPTY_ARR), /* harmony export */ "EMPTY_OBJ": () => (/* binding */ EMPTY_OBJ), /* harmony export */ "NO": () => (/* binding */ NO), /* harmony export */ "NOOP": () => (/* binding */ NOOP), /* harmony export */ "PatchFlagNames": () => (/* binding */ PatchFlagNames), /* harmony export */ "camelize": () => (/* binding */ camelize), /* harmony export */ "capitalize": () => (/* binding */ capitalize), /* harmony export */ "def": () => (/* binding */ def), /* harmony export */ "escapeHtml": () => (/* binding */ escapeHtml), /* harmony export */ "escapeHtmlComment": () => (/* binding */ escapeHtmlComment), /* harmony export */ "extend": () => (/* binding */ extend), /* harmony export */ "generateCodeFrame": () => (/* binding */ generateCodeFrame), /* harmony export */ "getGlobalThis": () => (/* binding */ getGlobalThis), /* harmony export */ "hasChanged": () => (/* binding */ hasChanged), /* harmony export */ "hasOwn": () => (/* binding */ hasOwn), /* harmony export */ "hyphenate": () => (/* binding */ hyphenate), /* harmony export */ "includeBooleanAttr": () => (/* binding */ includeBooleanAttr), /* harmony export */ "invokeArrayFns": () => (/* binding */ invokeArrayFns), /* harmony export */ "isArray": () => (/* binding */ isArray), /* harmony export */ "isBooleanAttr": () => (/* binding */ isBooleanAttr), /* harmony export */ "isDate": () => (/* binding */ isDate), /* harmony export */ "isFunction": () => (/* binding */ isFunction), /* harmony export */ "isGloballyWhitelisted": () => (/* binding */ isGloballyWhitelisted), /* harmony export */ "isHTMLTag": () => (/* binding */ isHTMLTag), /* harmony export */ "isIntegerKey": () => (/* binding */ isIntegerKey), /* harmony export */ "isKnownHtmlAttr": () => (/* binding */ isKnownHtmlAttr), /* harmony export */ "isKnownSvgAttr": () => (/* binding */ isKnownSvgAttr), /* harmony export */ "isMap": () => (/* binding */ isMap), /* harmony export */ "isModelListener": () => (/* binding */ isModelListener), /* harmony export */ "isNoUnitNumericStyleProp": () => (/* binding */ isNoUnitNumericStyleProp), /* harmony export */ "isObject": () => (/* binding */ isObject), /* harmony export */ "isOn": () => (/* binding */ isOn), /* harmony export */ "isPlainObject": () => (/* binding */ isPlainObject), /* harmony export */ "isPromise": () => (/* binding */ isPromise), /* harmony export */ "isReservedProp": () => (/* binding */ isReservedProp), /* harmony export */ "isSSRSafeAttrName": () => (/* binding */ isSSRSafeAttrName), /* harmony export */ "isSVGTag": () => (/* binding */ isSVGTag), /* harmony export */ "isSet": () => (/* binding */ isSet), /* harmony export */ "isSpecialBooleanAttr": () => (/* binding */ isSpecialBooleanAttr), /* harmony export */ "isString": () => (/* binding */ isString), /* harmony export */ "isSymbol": () => (/* binding */ isSymbol), /* harmony export */ "isVoidTag": () => (/* binding */ isVoidTag), /* harmony export */ "looseEqual": () => (/* binding */ looseEqual), /* harmony export */ "looseIndexOf": () => (/* binding */ looseIndexOf), /* harmony export */ "makeMap": () => (/* binding */ makeMap), /* harmony export */ "normalizeClass": () => (/* binding */ normalizeClass), /* harmony export */ "normalizeProps": () => (/* binding */ normalizeProps), /* harmony export */ "normalizeStyle": () => (/* binding */ normalizeStyle), /* harmony export */ "objectToString": () => (/* binding */ objectToString), /* harmony export */ "parseStringStyle": () => (/* binding */ parseStringStyle), /* harmony export */ "propsToAttrMap": () => (/* binding */ propsToAttrMap), /* harmony export */ "remove": () => (/* binding */ remove), /* harmony export */ "slotFlagsText": () => (/* binding */ slotFlagsText), /* harmony export */ "stringifyStyle": () => (/* binding */ stringifyStyle), /* harmony export */ "toDisplayString": () => (/* binding */ toDisplayString), /* harmony export */ "toHandlerKey": () => (/* binding */ toHandlerKey), /* harmony export */ "toNumber": () => (/* binding */ toNumber), /* harmony export */ "toRawType": () => (/* binding */ toRawType), /* harmony export */ "toTypeString": () => (/* binding */ toTypeString) /* harmony export */ }); /** * Make a map and return a function for checking if a key * is in that map. * IMPORTANT: all calls of this function must be prefixed with * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ function makeMap(str, expectsLowerCase) { const map = Object.create(null); const list = str.split(','); for (let i = 0; i < list.length; i++) { map[list[i]] = true; } return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]; } /** * dev only flag -> name mapping */ const PatchFlagNames = { [1 /* TEXT */]: `TEXT`, [2 /* CLASS */]: `CLASS`, [4 /* STYLE */]: `STYLE`, [8 /* PROPS */]: `PROPS`, [16 /* FULL_PROPS */]: `FULL_PROPS`, [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`, [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`, [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`, [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`, [512 /* NEED_PATCH */]: `NEED_PATCH`, [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`, [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`, [-1 /* HOISTED */]: `HOISTED`, [-2 /* BAIL */]: `BAIL` }; /** * Dev only */ const slotFlagsText = { [1 /* STABLE */]: 'STABLE', [2 /* DYNAMIC */]: 'DYNAMIC', [3 /* FORWARDED */]: 'FORWARDED' }; const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' + 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' + 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt'; const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED); const range = 2; function generateCodeFrame(source, start = 0, end = source.length) { // Split the content into individual lines but capture the newline sequence // that separated each line. This is important because the actual sequence is // needed to properly take into account the full line length for offset // comparison let lines = source.split(/(\r?\n)/); // Separate the lines and newline sequences into separate arrays for easier referencing const newlineSequences = lines.filter((_, idx) => idx % 2 === 1); lines = lines.filter((_, idx) => idx % 2 === 0); let count = 0; const res = []; for (let i = 0; i < lines.length; i++) { count += lines[i].length + ((newlineSequences[i] && newlineSequences[i].length) || 0); if (count >= start) { for (let j = i - range; j <= i + range || end > count; j++) { if (j < 0 || j >= lines.length) continue; const line = j + 1; res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); const lineLength = lines[j].length; const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0; if (j === i) { // push underline const pad = start - (count - (lineLength + newLineSeqLength)); const length = Math.max(1, end > count ? lineLength - pad : end - start); res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); } else if (j > i) { if (end > count) { const length = Math.max(Math.min(end - count, lineLength), 1); res.push(` | ` + '^'.repeat(length)); } count += lineLength + newLineSeqLength; } } break; } } return res.join('\n'); } /** * On the client we only need to offer special cases for boolean attributes that * have different names from their corresponding dom properties: * - itemscope -> N/A * - allowfullscreen -> allowFullscreen * - formnovalidate -> formNoValidate * - ismap -> isMap * - nomodule -> noModule * - novalidate -> noValidate * - readonly -> readOnly */ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs); /** * The full list is needed during SSR to produce the correct initial markup. */ const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` + `loop,open,required,reversed,scoped,seamless,` + `checked,muted,multiple,selected`); /** * Boolean attributes should be included if the value is truthy or ''. * e.g. <select multiple> compiles to { multiple: '' } */ function includeBooleanAttr(value) { return !!value || value === ''; } const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; const attrValidationCache = {}; function isSSRSafeAttrName(name) { if (attrValidationCache.hasOwnProperty(name)) { return attrValidationCache[name]; } const isUnsafe = unsafeAttrCharRE.test(name); if (isUnsafe) { console.error(`unsafe attribute name: ${name}`); } return (attrValidationCache[name] = !isUnsafe); } const propsToAttrMap = { acceptCharset: 'accept-charset', className: 'class', htmlFor: 'for', httpEquiv: 'http-equiv' }; /** * CSS properties that accept plain numbers */ const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` + `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` + `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` + `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` + `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` + `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` + // SVG `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` + `stroke-miterlimit,stroke-opacity,stroke-width`); /** * Known attributes, this is used for stringification of runtime static nodes * so that we don't stringify bindings that cannot be set from HTML. * Don't also forget to allow `data-*` and `aria-*`! * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes */ const isKnownHtmlAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` + `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` + `border,buffered,capture,challenge,charset,checked,cite,class,code,` + `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` + `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` + `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` + `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` + `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` + `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` + `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` + `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` + `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` + `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` + `start,step,style,summary,tabindex,target,title,translate,type,usemap,` + `value,width,wrap`); /** * Generated from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute */ const isKnownSvgAttr = /*#__PURE__*/ makeMap(`xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,` + `arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,` + `baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,` + `clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,` + `color-interpolation-filters,color-profile,color-rendering,` + `contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,` + `descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,` + `dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,` + `fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,` + `font-family,font-size,font-size-adjust,font-stretch,font-style,` + `font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,` + `glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,` + `gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,` + `horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,` + `k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,` + `lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,` + `marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,` + `mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,` + `name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,` + `overflow,overline-position,overline-thickness,panose-1,paint-order,path,` + `pathLength,patternContentUnits,patternTransform,patternUnits,ping,` + `pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,` + `preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,` + `rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,` + `restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,` + `specularConstant,specularExponent,speed,spreadMethod,startOffset,` + `stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,` + `strikethrough-position,strikethrough-thickness,string,stroke,` + `stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,` + `stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,` + `systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,` + `text-decoration,text-rendering,textLength,to,transform,transform-origin,` + `type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,` + `unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,` + `v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,` + `vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,` + `writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,` + `xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,` + `xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`); function normalizeStyle(value) { if (isArray(value)) { const res = {}; for (let i = 0; i < value.length; i++) { const item = value[i]; const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); if (normalized) { for (const key in normalized) { res[key] = normalized[key]; } } } return res; } else if (isString(value)) { return value; } else if (isObject(value)) { return value; } } const listDelimiterRE = /;(?![^(]*\))/g; const propertyDelimiterRE = /:(.+)/; function parseStringStyle(cssText) { const ret = {}; cssText.split(listDelimiterRE).forEach(item => { if (item) { const tmp = item.split(propertyDelimiterRE); tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); } }); return ret; } function stringifyStyle(styles) { let ret = ''; if (!styles || isString(styles)) { return ret; } for (const key in styles) { const value = styles[key]; const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); if (isString(value) || (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) { // only render valid values ret += `${normalizedKey}:${value};`; } } return ret; } function normalizeClass(value) { let res = ''; if (isString(value)) { res = value; } else if (isArray(value)) { for (let i = 0; i < value.length; i++) { const normalized = normalizeClass(value[i]); if (normalized) { res += normalized + ' '; } } } else if (isObject(value)) { for (const name in value) { if (value[name]) { res += name + ' '; } } } return res.trim(); } function normalizeProps(props) { if (!props) return null; let { class: klass, style } = props; if (klass && !isString(klass)) { props.class = normalizeClass(klass); } if (style) { props.style = normalizeStyle(style); } return props; } // These tag configs are shared between compiler-dom and runtime-dom, so they // https://developer.mozilla.org/en-US/docs/Web/HTML/Element const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' + 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' + 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' + 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' + 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' + 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' + 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' + 'option,output,progress,select,textarea,details,dialog,menu,' + 'summary,template,blockquote,iframe,tfoot'; // https://developer.mozilla.org/en-US/docs/Web/SVG/Element const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' + 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' + 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' + 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' + 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' + 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' + 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' + 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' + 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' + 'text,textPath,title,tspan,unknown,use,view'; const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'; const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS); const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS); const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS); const escapeRE = /["'&<>]/; function escapeHtml(string) { const str = '' + string; const match = escapeRE.exec(str); if (!match) { return str; } let html = ''; let escaped; let index; let lastIndex = 0; for (index = match.index; index < str.length; index++) { switch (str.charCodeAt(index)) { case 34: // " escaped = '"'; break; case 38: // & escaped = '&'; break; case 39: // ' escaped = '''; break; case 60: // < escaped = '<'; break; case 62: // > escaped = '>'; break; default: continue; } if (lastIndex !== index) { html += str.slice(lastIndex, index); } lastIndex = index + 1; html += escaped; } return lastIndex !== index ? html + str.slice(lastIndex, index) : html; } // https://www.w3.org/TR/html52/syntax.html#comments const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g; function escapeHtmlComment(src) { return src.replace(commentStripRE, ''); } function looseCompareArrays(a, b) { if (a.length !== b.length) return false; let equal = true; for (let i = 0; equal && i < a.length; i++) { equal = looseEqual(a[i], b[i]); } return equal; } function looseEqual(a, b) { if (a === b) return true; let aValidType = isDate(a); let bValidType = isDate(b); if (aValidType || bValidType) { return aValidType && bValidType ? a.getTime() === b.getTime() : false; } aValidType = isArray(a); bValidType = isArray(b); if (aValidType || bValidType) { return aValidType && bValidType ? looseCompareArrays(a, b) : false; } aValidType = isObject(a); bValidType = isObject(b); if (aValidType || bValidType) { /* istanbul ignore if: this if will probably never be called */ if (!aValidType || !bValidType) { return false; } const aKeysCount = Object.keys(a).length; const bKeysCount = Object.keys(b).length; if (aKeysCount !== bKeysCount) { return false; } for (const key in a) { const aHasKey = a.hasOwnProperty(key); const bHasKey = b.hasOwnProperty(key); if ((aHasKey && !bHasKey) || (!aHasKey && bHasKey) || !looseEqual(a[key], b[key])) { return false; } } } return String(a) === String(b); } function looseIndexOf(arr, val) { return arr.findIndex(item => looseEqual(item, val)); } /** * For converting {{ interpolation }} values to displayed strings. * @private */ const toDisplayString = (val) => { return val == null ? '' : isArray(val) || (isObject(val) && (val.toString === objectToString || !isFunction(val.toString))) ? JSON.stringify(val, replacer, 2) : String(val); }; const replacer = (_key, val) => { // can't use isRef here since @vue/shared has no deps if (val && val.__v_isRef) { return replacer(_key, val.value); } else if (isMap(val)) { return { [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => { entries[`${key} =>`] = val; return entries; }, {}) }; } else if (isSet(val)) { return { [`Set(${val.size})`]: [...val.values()] }; } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { return String(val); } return val; }; const EMPTY_OBJ = ( false) ? 0 : {}; const EMPTY_ARR = ( false) ? 0 : []; const NOOP = () => { }; /** * Always return false. */ const NO = () => false; const onRE = /^on[^a-z]/; const isOn = (key) => onRE.test(key); const isModelListener = (key) => key.startsWith('onUpdate:'); const extend = Object.assign; const remove = (arr, el) => { const i = arr.indexOf(el); if (i > -1) { arr.splice(i, 1); } }; const hasOwnProperty = Object.prototype.hasOwnProperty; const hasOwn = (val, key) => hasOwnProperty.call(val, key); const isArray = Array.isArray; const isMap = (val) => toTypeString(val) === '[object Map]'; const isSet = (val) => toTypeString(val) === '[object Set]'; const isDate = (val) => val instanceof Date; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; const isSymbol = (val) => typeof val === 'symbol'; const isObject = (val) => val !== null && typeof val === 'object'; const isPromise = (val) => { return isObject(val) && isFunction(val.then) && isFunction(val.catch); }; const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const toRawType = (value) => { // extract "RawType" from strings like "[object RawType]" return toTypeString(value).slice(8, -1); }; const isPlainObject = (val) => toTypeString(val) === '[object Object]'; const isIntegerKey = (key) => isString(key) && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key; const isReservedProp = /*#__PURE__*/ makeMap( // the leading comma is intentional so empty string "" is also included ',key,ref,' + 'onVnodeBeforeMount,onVnodeMounted,' + 'onVnodeBeforeUpdate,onVnodeUpdated,' + 'onVnodeBeforeUnmount,onVnodeUnmounted'); const cacheStringFunction = (fn) => { const cache = Object.create(null); return ((str) => { const hit = cache[str]; return hit || (cache[str] = fn(str)); }); }; const camelizeRE = /-(\w)/g; /** * @private */ const camelize = cacheStringFunction((str) => { return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); }); const hyphenateRE = /\B([A-Z])/g; /** * @private */ const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase()); /** * @private */ const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1)); /** * @private */ const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``); // compare whether a value has changed, accounting for NaN. const hasChanged = (value, oldValue) => !Object.is(value, oldValue); const invokeArrayFns = (fns, arg) => { for (let i = 0; i < fns.length; i++) { fns[i](arg); } }; const def = (obj, key, value) => { Object.defineProperty(obj, key, { configurable: true, enumerable: false, value }); }; const toNumber = (val) => { const n = parseFloat(val); return isNaN(n) ? val : n; }; let _globalThis; const getGlobalThis = () => { return (_globalThis || (_globalThis = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : {})); }; /***/ }), /***/ "./src/save/main.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, "body {\n background-color: #f0f0f2;\n margin: 0;\n padding: 0;\n font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\",\n \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\ndiv.main {\n width: 900px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0, 0, 0, 0.02);\n}\n@media (max-width: 700px) {\n div.main {\n margin: 0 auto;\n width: auto;\n }\n}\nh1 {\n line-height: 130%;\n text-align: center;\n font-weight: bold;\n font-size: xxx-large;\n margin-top: 3.2em;\n margin-bottom: 3.3em;\n}\nh2 {\n line-height: 130%;\n text-align: center;\n font-weight: bold;\n font-size: x-large;\n margin-top: 1.2em;\n margin-bottom: 2.3em;\n}\ndiv {\n margin: 0px;\n padding: 0px;\n text-align: justify;\n}\np {\n text-indent: 2em;\n display: block;\n line-height: 1.3em;\n margin-top: 0.4em;\n margin-bottom: 0.4em;\n}\nimg {\n vertical-align: text-bottom;\n max-width: 90%;\n}\n.title {\n margin-bottom: 0.7em;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/save/toc.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, "img {\n max-width: 100%;\n max-height: 15em;\n}\n.introduction {\n font-size: smaller;\n max-height: 18em;\n overflow-y: scroll;\n}\n.introduction p {\n text-indent: 0;\n}\n.bookurl {\n text-align: center;\n font-size: smaller;\n padding-top: 1em;\n padding-bottom: 0.5em;\n margin-top: 0.4em;\n}\n.bookurl > a {\n color: gray;\n}\n.info h3 {\n padding-left: 0.5em;\n margin-top: -1.2em;\n margin-bottom: 0.5em;\n}\n.section {\n margin-top: 1.5em;\n display: grid;\n grid-template-columns: 30% 30% 30%;\n}\n.section > h2:first-child {\n grid-column-end: span 3;\n}\n.section > .chapter {\n padding-bottom: 0.3em;\n text-align: center;\n}\n.main > h1 {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n}\na.disabled {\n pointer-events: none;\n cursor: default;\n color: gray;\n}\n.author::before {\n content: \"作者:\";\n}\n.author {\n text-align: center;\n margin-top: -3em;\n margin-bottom: 3em;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/ChapterList.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ".section {\n margin-top: 1.5em;\n display: grid;\n grid-template-columns: 32% 32% 32%;\n}\n.section > h3:first-child {\n grid-column-end: span 3;\n text-align: center;\n}\n.section > div.chapter {\n text-align: center;\n padding-top: 0.5em;\n padding-bottom: 0.3em;\n padding-left: 23px;\n padding-right: 20px;\n border: 1px solid #d9d9d9;\n border-radius: 5px;\n margin-left: 10px;\n margin-top: 5px;\n margin-right: 0;\n margin-bottom: 0;\n}\n.section a.disabled {\n pointer-events: none;\n cursor: default;\n}\n.section a {\n text-decoration: none;\n}\ndiv.chapter.good {\n background: #41b883;\n}\ndiv.chapter.bad {\n background: #ff9900;\n}\ndiv.chapter.bad a,\ndiv.chapter.good a {\n color: white;\n}\ndiv.chapter-list-loading {\n padding-top: 5em;\n padding-bottom: 5em;\n text-align: center;\n}\ndiv.chapter-list {\n max-height: 200px;\n overflow-y: scroll;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/FilterTab.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ".filter-setting {\n padding-top: 0.4em;\n padding-bottom: 0.8em;\n text-align: center;\n}\n.filter-input + .filter-setter {\n margin-top: 1em;\n}\n.filter-description {\n font-size: larger;\n color: cornflowerblue;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/button.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ".button-div {\n position: fixed;\n top: 15%;\n right: 5%;\n z-index: 5000;\n}\n\n.button-div button {\n border-style: none;\n text-align: center;\n vertical-align: baseline;\n background-color: rgba(128, 128, 128, 0.2);\n padding: 3px;\n border-radius: 12px;\n min-width: auto;\n min-height: auto;\n}\n\n.button-div img.start,\n.button-div img.jump {\n height: 2em;\n}\n.button-div img.setting {\n height: 1em;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/dialog.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ".overlay {\n visibility: hidden;\n opacity: 0;\n z-index: 100000;\n position: fixed;\n top: -50%;\n left: -50%;\n height: 200%;\n width: 200%;\n background-color: black;\n}\n.overlay.open {\n opacity: 0.8;\n visibility: visible;\n transition: opacity 0.2s ease-in;\n}\n.overlay:not(.open) {\n transition: visibility 0.2s step-end, opacity 0.2s ease-in;\n}\n\n.out {\n position: fixed;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n\n display: flex;\n justify-content: center;\n align-items: center;\n\n z-index: 100001;\n}\n\n.dialog {\n width: 720px;\n max-height: 70%;\n display: none;\n opacity: 0;\n z-index: 100100;\n position: fixed;\n margin: 0;\n padding: 0;\n}\n.dialog.open {\n opacity: 1;\n display: block;\n transition: opacity 0.2s ease-in;\n}\n\n.dialog > * {\n box-sizing: border-box;\n}\n.dialog > .titlebar {\n background-color: white;\n min-height: 24px;\n position: relative;\n}\n.dialog-title {\n padding: 10px;\n text-transform: uppercase;\n background: #ff7bac;\n color: #ffffff;\n margin: 0;\n font-size: 1.5em;\n text-align: center;\n}\n.dialog-close {\n background: #ff7bac;\n color: #ffffff;\n\n font-style: normal;\n font-weight: 400;\n font-variant: normal;\n text-transform: none;\n line-height: 1;\n user-select: none;\n\n cursor: pointer;\n font-size: 120%;\n margin: 0;\n padding: 0;\n width: 3.6em;\n height: 92%;\n border: 1px solid transparent;\n transition-duration: 0.2s;\n display: block;\n\n position: absolute;\n right: 0;\n top: 0;\n white-space: nowrap;\n}\n\n.dialog > .body {\n background-color: white;\n border: 1px solid rgb(255 125 175 / 80%);\n text-align: left;\n\n line-height: 1.5;\n padding: 1em;\n\n overflow: auto;\n min-width: 280px;\n\n height: calc(100% - 2.1em);\n max-height: 900px;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/progress.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, "#nd-progress {\n position: fixed;\n bottom: 8%;\n right: 3%;\n z-index: 2147483647;\n border-style: none;\n text-align: center;\n vertical-align: baseline;\n background-color: rgba(210, 210, 210, 0.2);\n padding: 6px;\n border-radius: 12px;\n}\n#chapter-progress {\n --color: green;\n --position: 0%;\n width: 200px;\n height: 10px;\n border-radius: 30px;\n background-color: #ccc;\n background-image: radial-gradient(\n closest-side circle at var(--position),\n var(--color),\n var(--color) 100%,\n transparent\n ),\n linear-gradient(var(--color), var(--color));\n background-image: -webkit-radial-gradient(\n var(--position),\n circle closest-side,\n var(--color),\n var(--color) 100%,\n transparent\n ),\n -webkit-linear-gradient(var(--color), var(--color));\n background-size: 100%, var(--position);\n background-repeat: no-repeat;\n}\n#zip-progress {\n --color: yellow;\n --position: 0%;\n width: 200px;\n height: 10px;\n border-radius: 30px;\n background-color: #ccc;\n background-image: radial-gradient(\n closest-side circle at var(--position),\n var(--color),\n var(--color) 100%,\n transparent\n ),\n linear-gradient(var(--color), var(--color));\n background-image: -webkit-radial-gradient(\n var(--position),\n circle closest-side,\n var(--color),\n var(--color) 100%,\n transparent\n ),\n -webkit-linear-gradient(var(--color), var(--color));\n background-size: 100%, var(--position);\n background-repeat: no-repeat;\n margin-top: 5px;\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./src/ui/setting.css": /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ".nd-setting-body input[type=\"checkbox\"],\n.nd-setting-body input[type=\"radio\"],\n.nd-setting-body input[type=\"text\"] {\n position: static;\n opacity: 1;\n all: revert;\n}\n.nd-setting-body {\n background: #e0e0e0;\n padding: 1em;\n border-top-right-radius: 3px;\n}\n.nd-setting-body hr {\n margin-top: 0.8em;\n margin-bottom: 0.8em;\n}\n\n.tab-button {\n padding: 6px 10px;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n border: 1px solid #ccc;\n cursor: pointer;\n background: #f0f0f0;\n margin-bottom: -1px;\n margin-right: -1px;\n}\n.tab-button:hover {\n background: #e0e0e0;\n}\n.tab-button.active {\n background: #e0e0e0;\n}\n\n.nd-setting-footer {\n background: #e0e0e0;\n padding-bottom: 0.7em;\n text-align: center;\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.nd-setting-footer > button {\n all: revert;\n}\n\n/* 彩色斜纹 来自:https://www.zhangxinxu.com/wordpress/2021/05/css-html-hr/ */\n.hr-twill-colorful {\n border: 0;\n padding: 3px;\n background: linear-gradient(135deg, red, orange, green, blue, purple);\n --mask-image: repeating-linear-gradient(\n 135deg,\n #000 0px,\n #000 1px,\n transparent 1px,\n transparent 6px\n );\n -webkit-mask-image: var(--mask-image);\n mask-image: var(--mask-image);\n}\n/* 两头虚 来自:https://www.zhangxinxu.com/wordpress/2021/05/css-html-hr/ */\n.hr-edge-weak {\n border: 0;\n padding-top: 1px;\n background: linear-gradient(to right, transparent, #d0d0d5, transparent);\n}\n", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./node_modules/css-loader/dist/runtime/api.js": /***/ ((module) => { "use strict"; /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ module.exports = function (cssWithMappingToString) { var list = []; // return the list of modules as css string list.toString = function toString() { return this.map(function (item) { var content = ""; var needLayer = typeof item[5] !== "undefined"; if (item[4]) { content += "@supports (".concat(item[4], ") {"); } if (item[2]) { content += "@media ".concat(item[2], " {"); } if (needLayer) { content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {"); } content += cssWithMappingToString(item); if (needLayer) { content += "}"; } if (item[2]) { content += "}"; } if (item[4]) { content += "}"; } return content; }).join(""); }; // import a list of modules into the list list.i = function i(modules, media, dedupe, supports, layer) { if (typeof modules === "string") { modules = [[null, modules, undefined]]; } var alreadyImportedModules = {}; if (dedupe) { for (var k = 0; k < this.length; k++) { var id = this[k][0]; if (id != null) { alreadyImportedModules[id] = true; } } } for (var _k = 0; _k < modules.length; _k++) { var item = [].concat(modules[_k]); if (dedupe && alreadyImportedModules[item[0]]) { continue; } if (typeof layer !== "undefined") { if (typeof item[5] === "undefined") { item[5] = layer; } else { item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}"); item[5] = layer; } } if (media) { if (!item[2]) { item[2] = media; } else { item[1] = "@media ".concat(item[2], " {").concat(item[1], "}"); item[2] = media; } } if (supports) { if (!item[4]) { item[4] = "".concat(supports); } else { item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}"); item[4] = supports; } } list.push(item); } }; return list; }; /***/ }), /***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js": /***/ ((module) => { "use strict"; module.exports = function (i) { return i[1]; }; /***/ }), /***/ "./node_modules/file-saver/dist/FileSaver.min.js": /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(a,b){if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof __webpack_require__.g&&__webpack_require__.g.global===__webpack_require__.g?__webpack_require__.g:void 0,a=f.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g, true&&(module.exports=g)}); //# sourceMappingURL=FileSaver.min.js.map /***/ }), /***/ "./src/save/chapter.html.j2": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\"/> <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/> <meta name=\"referrer\" content=\"same-origin\"/> <meta name=\"generator\" content=\"https://github.com/yingziwu/novel-downloader\"/> <meta name=\"source\" content=\"{{ chapterUrl }}\"/> <link href=\"style.css\" rel=\"stylesheet\"/> <title>{{ chapterName }}</title> </head> <body> <div class=\"main\"> <h2>{{ chapterName }}</h2> {{ outerHTML }} </div> </body> </html> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/save/index.html.j2": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\"/> <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/> <meta name=\"referrer\" content=\"same-origin\"/> <meta name=\"generator\" content=\"https://github.com/yingziwu/novel-downloader\"/> <meta name=\"date-creation\" content=\"{{ creationDate }}\"/> <link href=\"style.css\" rel=\"stylesheet\"/> <title>{{ bookname }}</title> <style></style> </head> <body> <div class=\"main\"> <h1>{{ bookname }}</h1> <h3 class=\"author\">{{ author }}</h3> <div class=\"info\"> {% if cover -%} <img class=\"cover\" data-src-address=\"{{ cover.name }}\"/> {%- endif %} {% if introductionHTML -%} <div> <h3>简介</h3> <div class=\"introduction\">{{ introductionHTML }}</div> </div> {%- endif %} </div> <div class=\"bookurl\"> <a href=\"{{ bookUrl }}\">打开原始网站</a> </div> <hr/> {% for sectionObj in sectionsObj -%} <div id=\"section{{ sectionObj.sectionNumber }}\" class=\"section\"> {% if sectionObj.sectionName %} <h2 class=\"section-label\">{{ sectionObj.sectionName }}</h2> {% endif %} {% for chapter in sectionObj.chpaters -%} <div class=\"chapter\"> {% if not (chapter.contentHTML or chapter.status === Status.saved) -%} <a class=\"disabled\" href=\"{{ chapter.chapterHtmlFileName }}\">{{ chapter.chapterName }}</a> {%- else -%} <a href=\"{{ chapter.chapterHtmlFileName }}\">{{ chapter.chapterName }}</a> {%- endif %} </div> {%- endfor %} </div> {%- endfor %} </div> </body> </html>"; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/save/section.html.j2": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\"/> <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/> <meta name=\"referrer\" content=\"same-origin\"/> <meta name=\"generator\" content=\"https://github.com/yingziwu/novel-downloader\"/> <link href=\"style.css\" rel=\"stylesheet\"/> <title>{{ sectionName }}</title> </head> <body> <div class=\"main\"><h1>{{ sectionName }}</h1></div> </body> </html> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/ChapterList.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div> <div v-if=\"loading\"> <div class=\"loading\"><h2>正在载入章节列表中,请耐心等待……</h2></div> </div> <div class=\"chapter-list\" v-else> <div v-for=\"sectionObj in sectionsObj\" v-show=\"isSectionSeen(sectionObj)\" v-bind:key=\"sectionObj.sectionNumber\" class=\"section\"> <h3 class=\"section-label\" v-if=\"sectionObj.sectionName\"> {{ sectionObj.sectionName }} </h3> <div v-for=\"chapter in sectionObj.chpaters\" v-show=\"isChapterSeen(chapter)\" v-bind:key=\"chapter.chapterNumber\" class=\"chapter\" v-bind:class=\"{\n good: this.filter(chapter),\n bad: !this.filter(chapter),\n }\" v-bind:title=\"chapter.chapterNumber\"> <a v-bind:href=\"chapter.chapterUrl\" v-bind:class=\"{\n disabled: this.isChapterDisabled(chapter),\n }\" target=\"_blank\" rel=\"noopener noreferrer\">{{ chapter.chapterName }}</a> </div> </div> </div> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/FilterTab.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div> <div class=\"filter-setting\"> <div v-if=\"filterType !== 'null'\" class=\"filter-input\"> <p>请输入过滤的条件:<input type=\"text\" v-model=\"arg\"/></p> </div> <div class=\"filter-setter\"> <div> <span>当前过滤方法:</span> <select v-model=\"filterType\"> <option v-for=\"filterOption in filterOptionList\" v-bind:value=\"filterOption[0]\"> {{ filterOption[1][\"abbreviation\"] }} </option> </select> </div> <input type=\"checkbox\" id=\"hiddenBad\" v-model=\"hiddenBad\"/> <label for=\"hiddenBad\">只显示符合条件章节</label> <div class=\"filter-description\" v-html=\"filterDescription\"></div> </div> </div> <chapter-list/> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/button.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div class=\"button-div\" id=\"button-div\"> <div v-if=\"uiObj.type !== 'error'\"> <div class=\"jump\" v-if=\"uiObj.type === 'jump'\"> <button class=\"jump\"> <img class=\"jump\" v-bind:src=\"imgJump\" v-on:click=\"jumpButtonClick\"/> </button> </div> <div class=\"download\" v-if=\"uiObj.type === 'download'\"> <button class=\"start\"> <img class=\"start\" v-bind:src=\"imgStart\" v-on:click=\"startButtonClick\"/> </button> <button class=\"setting\" v-if=\"isSettingSeen\"> <img class=\"setting\" v-bind:src=\"imgSetting\" v-on:click=\"settingButtonClick\"/> </button> </div> </div> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/dialog.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div class=\"overlay\" v-bind:class=\"{ open: myPrivateStatus }\" v-if=\"myPrivateStatus\"></div> <div class=\"out\" v-if=\"myPrivateStatus\"> <div id=\"dialog\" class=\"dialog\" v-bind:class=\"{ open: myPrivateStatus }\"> <div class=\"titlebar\"> <h1 class=\"dialog-title\">{{ dialogTitle }}</h1> <button class=\"dialog-close\" v-on:click=\"dialogClose\">❌</button> </div> <div class=\"body\"> <slot></slot> </div> </div> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/progress.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div> <div id=\"nd-progress\" v-if=\"ntProgressSeen\"> <div v-if=\"chapterProgressSeen\" id=\"chapter-progress\" v-bind:style=\"{'--position': chapterPercent+'%'}\" v-bind:title=\"chapterProgressTitle\"></div> <div v-if=\"zipProgressSeen\" id=\"zip-progress\" title=\"ZIP\" v-bind:style=\"{'--position': zipPercent+'%'}\"></div> </div> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./src/ui/setting.html": /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); // Module var code = "<div> <dialog-ui dialog-title=\"设置\" v-bind:status=\"openStatus\" v-on:dialogclose=\"closeSetting\" v-if=\"openStatus === 'true'\"> <div class=\"nd-setting\"> <div class=\"nd-setting-tab\"> <button v-bind:class=\"['tab-button', { active: currentTab === 'tab-1'}]\" v-on:click=\"currentTab = 'tab-1'\"> 基本设置 </button> <button v-bind:class=\"['tab-button', { active: currentTab === 'tab-2'}]\" v-on:click=\"currentTab = 'tab-2'\"> 自定义筛选条件 </button> </div> <div class=\"nd-setting-body\"> <div id=\"nd-setting-tab-1\" class=\"tab-page\" v-show=\"currentTab === 'tab-1'\"> <div> <input type=\"checkbox\" id=\"debug\" v-model=\"setting.enableDebug\"/> <label for=\"debug\">启用调式模式。(输出更详细日志)</label> </div> <hr class=\"hr-twill-colorful\"/> <div> <h3>自定义保存参数</h3> <ul> <li v-for=\"item of saveOptions\"> <input type=\"radio\" v-bind:id=\"item.key\" v-bind:value=\"item.key\" v-model=\"setting.chooseSaveOption\"/> <label v-bind:for=\"item.key\">{{ item.value }}</label> </li> </ul> </div> </div> <div id=\"nd-setting-tab-2\" class=\"tab-page\" v-show=\"currentTab === 'tab-2'\"> <filter-tab v-on:filterupdate=\"saveFilter\"/> </div> </div> <div class=\"nd-setting-footer\"> <button v-on:click=\"closeAndSaveSetting\">Save</button> <button v-on:click=\"closeSetting\">Cancel</button> </div> </div> </dialog-ui> </div> "; // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code); /***/ }), /***/ "./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/debug.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.debug = void 0; const download_1 = __webpack_require__("./src/router/download.ts"); const file_saver_1 = __webpack_require__("./node_modules/file-saver/dist/FileSaver.min.js"); async function debug() { const rule = await (0, download_1.getRule)(); const book = await rule.bookParse(); unsafeWindow.rule = rule; unsafeWindow.book = book; unsafeWindow.saveAs = file_saver_1.saveAs; const { parse, fetchAndParse, gfetchAndParse } = await Promise.resolve().then(() => __webpack_require__("./src/rules/lib/readability.ts")); const readability = { parse, fetchAndParse, gfetchAndParse, }; unsafeWindow.readability = readability; return; } exports.debug = debug; /***/ }), /***/ "./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, "ScriptHandler version": GM_1._GM_info.version, "Novel-downloader version": GM_1._GM_info.script.version, enableDebug: setting_1.enableDebug.value, }; /***/ }), /***/ "./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"); function init() { 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; } const 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; } const tfi = await _formatImage(elem, builder); if (!tfi) { return; } const [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((img) => img.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 = ``; 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 = ``; 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 lastElementTemp = builder.dom.lastElementChild; if (lastElementTemp?.nodeName.toLowerCase() === "p") { const textElem = document.createTextNode(textContent); lastElementTemp.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((ele) => ele.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 previousSiblingBr = getPreviousSibling(elem); if (nextSibling === null) { if (previousSiblingBr?.nodeName.toLowerCase() === "br") { temp0(); const tPText = textContent + "\n\n"; builder.text = builder.text + tPText; return; } else if (previousSiblingBr === 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 (previousSiblingBr === 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 lastElementBr = builder.dom.lastElementChild; if (lastElementBr?.nodeName.toLowerCase() === "p") { const br = document.createElement("br"); const textElem = document.createTextNode(textContent); lastElementBr.appendChild(br); lastElementBr.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": { const elems = [node]; let j = i + 1; let jnodeName = nodeName; do { if (j >= childNodes.length) { break; } const 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, 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/createEl.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.createStyle = exports.createEl = void 0; function createEl(el) { const _el = document.createElement("div"); _el.innerHTML = el; if (_el.childElementCount === 1 && _el.firstElementChild) { return _el.firstElementChild; } else { throw new Error("Create HTMLElement Failed!"); } } exports.createEl = createEl; function createStyle(style, id) { const el = createEl(`<style>${style}</style>`); if (id) { el.id = id; } document.head.appendChild(el); return el; } exports.createStyle = createStyle; /***/ }), /***/ "./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 log_1 = __webpack_require__("./src/log.ts"); 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, method, headers, data, cookie, binary, nocache, revalidate, timeout, context, responseType, overrideMimeType, anonymous, username, 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) { 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}`); } }) .catch((error) => log_1.log.error(error)); } 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; }) .catch((error) => log_1.log.error(error)); } } exports.getText = getText; async function getHtmlDOM(url, charset, init) { const htmlText = await getText(url, charset, init); if (!htmlText) { throw new Error("Fetch Content failed!"); } return new DOMParser().parseFromString(htmlText, "text/html"); } exports.getHtmlDOM = getHtmlDOM; async function ggetText(url, charset, init) { 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}`); } }) .catch((error) => log_1.log.error(error)); } 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; }) .catch((error) => log_1.log.error(error)); } } exports.ggetText = ggetText; async function ggetHtmlDOM(url, charset, init) { const htmlText = await ggetText(url, charset, init); if (!htmlText) { throw new Error("Fetch Content failed!"); } return new DOMParser().parseFromString(htmlText, "text/html"); } exports.ggetHtmlDOM = ggetHtmlDOM; /***/ }), /***/ "./src/lib/misc.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.regexpEscape = exports.deepcopy = exports.LocalStorageExpired = exports.calculateMd5 = exports.storageAvailable = exports.sandboxed = exports.sleep = exports.concurrencyRun = exports.rm = void 0; const CryptoJS = __webpack_require__("crypto-js"); function rm(selector, all = false, dom) { if (all) { const rs = dom.querySelectorAll(selector); rs.forEach((e) => e.remove()); } else { const 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]; const 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]; const 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 = () => { 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; function deepcopy(obj) { return JSON.parse(JSON.stringify(obj)); } exports.deepcopy = deepcopy; function regexpEscape(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } exports.regexpEscape = regexpEscape; /***/ }), /***/ "./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 new Error("[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++; } }) .catch((error) => log_1.log.error(error)); } addToSavedZip(savedZip, nonStreamingFile, chunk) { savedZip.add(nonStreamingFile); nonStreamingFile.push(chunk, true); } async generateAsync(onUpdate) { 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; const file_saver_1 = __webpack_require__("./node_modules/file-saver/dist/FileSaver.min.js"); if (setting_1.enableDebug.value) { loglevel_1.default.setLevel("trace"); } else { loglevel_1.default.setLevel("info"); } exports.logText = ""; const originalFactory = loglevel_1.default.methodFactory; loglevel_1.default.methodFactory = (methodName, logLevel, loggerName) => { const rawMethod = originalFactory(methodName, logLevel, loggerName); return (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) { loglevel_1.default.error(error); } rawMethod(message); }; }; loglevel_1.default.setLevel(loglevel_1.default.getLevel()); function saveLogTextToFile() { (0, file_saver_1.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}, \ 分卷名:${this.sectionName}, URL:${this.chapterUrl}, \ VIP:${this.isVIP}, Paid:${this.isPaid}, \ isNull:${!Boolean(this.contentHTML)} 解析出错。`); } else { log_1.log.info(`[Chapter]章节名:${this.chapterName}, \ 分卷名:${this.sectionName}, 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/router/download.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": case "www.bz01.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; } case "www.tycqxs.com": { const { tycqxs } = await Promise.resolve().then(() => __webpack_require__("./src/rules/biquge.ts")); ruleClass = tycqxs(); 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/router/ui.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getUI = void 0; function getUI() { const host = document.location.host; switch (host) { case "m.shuquge.com": { const _pathname = document.location.pathname.split("/").slice(-1)[0]; const _id = _pathname.match(/^(\d+)/); if (_id) { const id = _id[0]; const jumpUrl = `https://www.shuquge.com/txt/${id}/index.html`; return { type: "jump", jumpUrl, }; } else { return { type: "error", }; } } default: { return { type: "download", }; } } } exports.getUI = getUI; /***/ }), /***/ "./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/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 progress_1 = __webpack_require__("./src/ui/progress.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(); log_1.log.debug("[book]Book object:\n" + JSON.stringify(self.book)); 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; progress_1.vm.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("button-div")?.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 saveOptionsInner = unsafeWindow.saveOptions; log_1.log.info("[run]发现自定义保存参数,内容如下\n", saveOptionsInner); return (0, save_1.getSaveBookObj)(book, saveOptionsInner); } 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 []; } progress_1.vm.totalChapterNumber = chapters.length; if (self.concurrencyLimit === 1) { for (const chapter of chapters) { if (window.stopFlag) { log_1.log.info("[chapter]收到停止信号,停止继续下载。"); break; } try { let chapterObj = await chapter.init(); chapterObj = await self.postChapterParseHook(chapterObj, saveBookObj); } 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 chapterObj = await curChapter.init(); chapterObj = await self.postChapterParseHook(chapterObj, saveBookObj); return chapterObj; } catch (error) { log_1.log.error(error); log_1.log.trace(error); } }); } log_1.log.info(`[initChapters]章节初始化完毕`); return chapters; } async postChapterParseHook(chapter, saveBookObj) { 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); progress_1.vm.finishedChapterNumber++; } return chapter; } } 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"); const log_1 = __webpack_require__("./src/log.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 = {}; const coverUrl = doc.querySelector("#bookCover img.book").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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 (const a of Array.from(cs)) { 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); 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { 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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of chapterList) { 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("h1.title").innerText.trim(); const content = doc.querySelector("#content"); const ad = '<div class="posterror"><a href="javascript:postError();" class="red">章节错误,点此举报(免注册(不可用))</a>,举报后维护人员会在两分钟内校正章节内容,请耐心等待,并刷新页面。</div>'; content.innerHTML = content.innerHTML.replace(ad, ""); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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.tycqxs = 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of chapterList) { 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 }); 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); const { dom: domClean, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: domClean, contentImages: images, additionalMetadate: null, }; } else { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } function mkBiqugeClass(introDomPatch, contentPatch, concurrencyLimit) { 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, 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, 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; const tycqxs = () => mkBiqugeClass((introDom) => introDom, (content) => { content.innerHTML = content.innerHTML.replace(/推荐都市大神老施新书:<a href="https:\/\/www\.tycqxs\.com\/[\d_]+\/" target="_blank">.+<\/a>/, ""); return content; }); exports.tycqxs = tycqxs; 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) { 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, 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, charset, }); } overrideConstructor(self) { } }; } const shuquge = () => mkBiqugeClass2((introDom) => { document.querySelector(".noshow")?.classList.remove("noshow"); if (document.querySelector(".showall")) { document.querySelector(".showall").innerHTML = ""; } introDom.innerHTML = introDom.innerHTML .replace(/作者:.+所写的《.+》无弹窗免费全文阅读为转载作品,章节由网友发布。/, "") .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"); const CryptoJS = __webpack_require__("crypto-js"); 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; }) .catch((error) => log_1.log.error(error)); } 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 (const c of Array.from(cs)) { 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; const keys = item.keys; const len = item.keys.length; const accessKey = item.accessKey; const accessKeyList = accessKey.split(""); const charsNotLatinNum = accessKeyList.length; const 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); const data = output[i]; const iv = btoa(message.substr(0, 16)); const keys255 = btoa(message.substr(16)); const 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 chapterAuthorSays = doc.querySelectorAll("#J_BookCnt .chapter.author_say"); let divChapterAuthorSay; if (chapterAuthorSays.length !== 0) { const hr = document.createElement("hr"); divChapterAuthorSay = document.createElement("div"); divChapterAuthorSay.appendChild(hr); for (const chapterAuthorSay of Array.from(chapterAuthorSays)) { (0, misc_1.rm)("i", true, chapterAuthorSay); divChapterAuthorSay.appendChild(chapterAuthorSay); } } return divChapterAuthorSay; } const chapterId = chapterUrl.split("/").slice(-1)[0]; async function publicChapter() { async function chapterDecrypt(chapterIdt, refererUrl) { const rootPath = "https://www.ciweimao.com/"; const accessKeyUrl = rootPath + "chapter/ajax_get_session_code"; const chapterContentUrl = rootPath + "chapter/get_book_chapter_detail_info"; log_1.log.debug(`[Chapter]请求 ${accessKeyUrl} Referer ${refererUrl}`); const accessKeyObj = await (0, http_1.gfetch)(accessKeyUrl, { 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=${chapterIdt}`, responseType: "json", }) .then((response) => response.response) .catch((error) => log_1.log.error(error)); const chapter_access_key = accessKeyObj .chapter_access_key; log_1.log.debug(`[Chapter]请求 ${chapterContentUrl} Referer ${refererUrl}`); const chapterContentObj = await (0, http_1.gfetch)(chapterContentUrl, { 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=${chapterIdt}&chapter_access_key=${chapter_access_key}`, responseType: "json", }) .then((response) => response.response) .catch((error) => log_1.log.error(error)); if (chapterContentObj.code !== 100000) { log_1.log.error(chapterContentObj); throw new Error(`下载 ${refererUrl} 失败`); } return decrypt({ content: chapterContentObj.chapter_content, keys: chapterContentObj.encryt_keys, accessKey: chapter_access_key, }); } const divChapterAuthorSay = await getChapterAuthorSay(); const content = document.createElement("div"); const decryptDate = await chapterDecrypt(chapterId, chapterUrl); content.innerHTML = decryptDate; (0, misc_1.rm)(".chapter span", true, content); if (divChapterAuthorSay) { content.appendChild(divChapterAuthorSay); } const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { 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(chapterIdi, refererUrl) { const HB = unsafeWindow.HB; const parentWidth = 871; const setFontSize = "14"; const imageSessionCodeUrl = HB.config.rootPath + "chapter/ajax_get_image_session_code"; log_1.log.debug(`[Chapter]请求 ${imageSessionCodeUrl} Referer ${refererUrl}`); const imageSessionCodeObject = await (0, http_1.gfetch)(imageSessionCodeUrl, { 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) .catch((error) => log_1.log.error(error)); if (imageSessionCodeObject.code !== 100000) { log_1.log.error(imageSessionCodeObject); throw new Error(`下载 ${refererUrl} 失败`); } const imageCode = decrypt({ content: imageSessionCodeObject .image_code, keys: imageSessionCodeObject .encryt_keys, accessKey: imageSessionCodeObject .access_key, }); const vipCHapterImageUrlI = HB.config.rootPath + "chapter/book_chapter_image?chapter_id=" + chapterIdi + "&area_width=" + parentWidth + "&font=undefined" + "&font_size=" + setFontSize + "&image_code=" + imageCode + "&bg_color_name=white" + "&text_color_name=white"; return vipCHapterImageUrlI; } const divChapterAuthorSay = await getChapterAuthorSay(); const vipCHapterImageUrl = await vipChapterDecrypt(chapterId, 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) .catch((error) => log_1.log.error(error)); const vipCHapterName = `vipCHapter${chapterId}.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; let dtext; let dimages; if (divChapterAuthorSay) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(divChapterAuthorSay, "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`; if (dtext) { contentText = contentText + "\n\n" + dtext; } return { chapterName, contentRaw: contentHTML, contentText, contentHTML, contentImages, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of chapterList) { 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".bookname > h1:nth-child(1)").innerText.trim(); const content = doc.querySelector("#content"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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; }) .catch((error) => log_1.log.error(error)); } const chapters = []; const 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(docI) { const imgPrefix = "https://images.dmzj.com/"; let pages = (0, misc_1.sandboxed)(docI.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 picUrlListI = info.page_url .split("|") .map((pic) => imgPrefix + pic); return picUrlListI; } } 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); } const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } return { 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`; }, }; } 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const CryptoJS = __webpack_require__("crypto-js"); 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()) .catch((error) => log_1.log.error(error)); 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; }) .catch((error) => log_1.log.error(error)); } 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()) .catch((error) => log_1.log.error(error)); 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(contentOrig) { 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, }; }; 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 LCngpxaFSubstr; if (_CP_NUXT) { LCngpxaFSubstr = _CP_NUXT.state.CpST.LCngpxaF.substr(2, 10); } else { LCngpxaFSubstr = unsafeWindow.__NUXT__.state.CpST.LCngpxaF.substr(1, 10); } const ivG = setIv("iGzsYn"); const keyG = setKey(LCngpxaFSubstr); const cfgG = setcfg(ivG); const content = decrypt(contentOrig, keyG, cfgG); 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 resultI = 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()) .catch((error) => log_1.log.error(error)); if (resultI.data.chapterInfo.content.length !== 0 && resultI.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 resultI; } } 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, 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 "<p><br/></p>"; } else { return `<p>${p}</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 "<p><br/></p>"; } else { return `<p>${p}</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, contentRaw, contentText, contentHTML, contentImages: null, additionalMetadate: null, }; } } return { 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, (introDomI) => { (0, misc_1.rm)("span:nth-child(1)", false, introDomI); return introDomI; }); 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 indexUrlsI = []; const maxPageNumber = Number(getMaxPageNumber()); for (let i = 1; i <= maxPageNumber; i++) { const indexUrl = [ document.location.origin, document.location.pathname.split("/")[1], `${bookId}_${i}`, ].join("/") + "/"; indexUrlsI.push(indexUrl); } return indexUrlsI; }; const indexUrls = getIndexUrls(); let lis = []; for (const indexUrl of indexUrls) { log_1.log.debug(`[chapter]请求 ${indexUrl}`); const doc = await (0, http_1.getHtmlDOM)(indexUrl, "UTF-8"); const ul = doc.querySelector("ul.chapters"); if (ul?.childElementCount) { lis = lis.concat(Array.from(ul.children)); } } const chapterList = lis.filter((obj) => obj !== undefined); let chapterNumber = 0; for (const node of chapterList) { 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)); const 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++) { const 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) { const { 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); const { 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, contentRaw: content, contentText: finalText, contentHTML: finalDom, contentImages: finalImages, additionalMetadate: null, }; } else { return { 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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of chapterList) { 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; let bid; let sid; let 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")) .catch((error) => log_1.log.error(error)); if (token) { const tokenDict = atob(token) .split(/[A-Z]+%/) .map((v) => Number(v)); const thisBody = doc.querySelector("#content"); let b = 0; let star = 0; for (let i = 0; i < thisBody.childNodes.length; i++) { if (thisBody.childNodes[i].nodeName === "H2") { star = i + 1; } if (thisBody.childNodes[i].nodeName === "DIV" && thisBody.childNodes[i].className !== "chapter") { break; } } const thisChildNode = []; for (let i = 0; i < tokenDict.length; i++) { if (tokenDict[i] < 5) { thisChildNode[tokenDict[i]] = thisBody.childNodes[i + star]; b++; } else { thisChildNode[tokenDict[i] - b] = thisBody.childNodes[i + star]; } } for (const childNode of thisChildNode) { if (!childNode) { continue; } thisBody.appendChild(childNode); } } } const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("#content .h2").innerText.trim(); await sorfPage(); const content = doc.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); }); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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; }) .catch((error) => log_1.log.error(error)); } 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 }); 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}`); const 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 (const a of Array.from(cs)) { 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 }); 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".title > h1:nth-child(1)").innerText.trim(); const content = doc.querySelector("#content"); if (content) { content.innerHTML = content.innerHTML.replace(`<p>您可以在百度里搜索“${bookname} 妙笔阁(imiaobige.com)”查找最新章节!</p>`, ""); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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 getInformationBlocked = () => { const fl = Array.from(document.querySelectorAll(".smallreadbody")).filter((div) => div.innerText.includes("文案信息审核未通过,等待作者修改后重新审核")); if (fl.length !== 0) { return true; } else { return false; } }; let bookname = ""; const additionalMetadate = {}; let author = "佚名"; let introduction = null; let introductionHTML = null; let introCleanimages = null; if (!getInformationBlocked()) { bookname = document.querySelector('h1[itemprop="name"] > span').innerText.trim(); author = document.querySelector("td.sptd h2 a span").innerText .replace(/作\s+者:/, "") .trim(); const introDom = document.querySelector("#novelintro"); [introduction, introductionHTML, introCleanimages] = await (0, common_1.introDomHandle)(introDom); if (introCleanimages) { additionalMetadate.attachments = [...introCleanimages]; } const coverUrl = document.querySelector(".noveldefaultimage").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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; } else { window.scrollTo(0, document.body.scrollHeight); await (0, misc_1.sleep)(3000); bookname = document.querySelector("td[id^=comment_] span.coltext > a")?.innerText .trim() .replace(/《|》/g, ""); window.scrollTo(0, 0); if (!bookname) { throw new Error("抓取书名出错"); } const authorPageUrl = document.querySelector("#oneboolt > tbody > tr:nth-child(1) > td > div > h2 > a")?.href; if (authorPageUrl) { const authorPage = await (0, http_2.getHtmlDOM)(authorPageUrl, this.charset); author = authorPage.querySelector('span[itemprop="name"]') ?.innerText ?? author; } } const chapters = []; const trList = document.querySelectorAll("#oneboolt > tbody > tr"); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (const tr of Array.from(trList)) { 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); } } else { const chapterName = "[锁]"; const chapterUrl = ""; const chapter = new main_1.Chapter(bookUrl, bookname, chapterUrl, chapterNumber, chapterName, false, null, sectionName, sectionNumber, sectionChapterNumber, this.chapterParse, this.charset, {}); 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_2.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("div.noveltext h2").innerText.trim(); const content = doc.querySelector("div.noveltext"); if (content) { (0, misc_1.rm)("hr", true, content); const rawAuthorSayDom = content.querySelector(".readsmall"); let authorSayDom; let authorSayText; if (rawAuthorSayDom) { const { 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, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } return { 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 fontNameI; let fontUrlI; 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) { fontNameI = 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) { fontUrlI = document.location.protocol + m3[1]; return [fontNameI, fontUrlI]; } } } } } const _fontName = document.querySelector("div.noveltext")?.classList[1]; if (_fontName) { fontNameI = _fontName; fontUrlI = document.location.protocol + `//static.jjwxc.net/tmp/fonts/${fontNameI}.woff2?h=my.jjwxc.net`; return [fontNameI, fontUrlI]; } return [null, null]; } let retryTime = 0; function fetchFont(fontUrlI) { log_1.log.debug(`[Chapter]请求 ${fontUrlI} Referer ${chapterUrl} 重试次数 ${retryTime}`); return (0, http_1.gfetch)(fontUrlI, { headers: { accept: "*/*", Referer: chapterUrl, }, responseType: "blob", }) .then((response) => { if (response.status >= 200 && response.status <= 299) { return response.response; } else { log_1.log.error(`[Chapter]请求 ${fontUrlI} 失败 Referer ${chapterUrl}`); if (retryTime < setting_1.retryLimit) { retryTime++; return fetchFont(fontUrlI); } else { return null; } } }) .catch((error) => log_1.log.error(error)); } 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 isPaidF = () => { if (!dom.querySelector("#buy_content") && dom.querySelector("div.noveltext")) { return true; } else { return false; } }; if (isPaidF()) { 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; let authorSayText; if (rawAuthorSayDom) { const { 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, 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) { if (introDom === null) { return [null, null, null]; } else { if (domPatch) { introDom = domPatch(introDom.cloneNode(true)); } const { 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { 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; }) .catch((error) => log_1.log.error(error)); } 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 }); 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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) { if (Object.prototype.hasOwnProperty.call(imageTable, imageFilename)) { const normalCharacter = imageTable[imageFilename]; const imageHTML = `<img src="${document.location.origin}/wzbodyimg/${imageFilename}">`; 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) { if (Object.prototype.hasOwnProperty.call(jjwxcFontTable, jjwxcCharacter)) { const normalCharacter = jjwxcFontTable[jjwxcCharacter]; outputText = outputText.replaceAll(jjwxcCharacter, normalCharacter); } } outputText = outputText.replace(/\u200c/g, ""); } 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/readability.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.gfetchAndParse = exports.fetchAndParse = exports.parse = void 0; const readability_1 = __webpack_require__("./node_modules/@mozilla/readability/index.js"); const http_1 = __webpack_require__("./src/lib/http.ts"); function parse(doc, options) { return new readability_1.Readability(doc, options).parse(); } exports.parse = parse; async function fetchAndParse(url, charset, init, patch = (docm) => docm, options) { let doc = await (0, http_1.getHtmlDOM)(url, charset, init); if (typeof patch === "function") { doc = patch(doc); } return parse(doc, options); } exports.fetchAndParse = fetchAndParse; async function gfetchAndParse(url, charset, init, patch = (docm) => docm, options) { let doc = await (0, http_1.ggetHtmlDOM)(url, charset, init); if (typeof patch === "function") { doc = patch(doc); } return parse(doc, options); } exports.gfetchAndParse = gfetchAndParse; /***/ }), /***/ "./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) { if (Object.prototype.hasOwnProperty.call(imageTable, imageFilename)) { const normalCharacter = imageTable[imageFilename]; const imageHTML = `<img src="${document.location.origin}/wzbodyimg/${imageFilename}">`; 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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); }) .catch((error) => log_1.log.error(error)); } } 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 (const div of Array.from(cs)) { 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) { 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 { return { chapterName: ChapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of Array.from(liList)) { 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 ss = Array.from(doc.querySelectorAll("script")).find((s) => s.innerHTML.includes('document.getElementById("chapter_last")')); if (ss) { const _domNr = ss.innerText.trim().match(/let dom_nr = '(.+)';/); if (_domNr) { const domNr = _domNr[1]; doc.getElementById("chapter_last").innerHTML = domNr; } } (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; }) .catch((error) => log_1.log.error(error)); } 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 = (urlI) => { const _pageNumber = new URL(urlI).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 }); 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) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { 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) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { 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 self = this; 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"); if (!bookId) { throw new Error("获取 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, undefined); } 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; }) .catch((error) => log_1.log.error(error)); } additionalMetadate.tags = document.querySelector('#mypages > div:nth-child(8) > div:nth-child(1) > font[color="#800080"]')?.innerText .split("/") .map((item) => item.trim()) ?? []; async function getLiList() { const showbooklistAPIUrl = document.location.origin + "/showbooklist.php"; let flag = false; let page = 1; let pageMax = 0; const showbooklistParams = { ebookid: bookId, pages: page.toString(), showbooklisttype: "1", }; const liListTemp = []; do { log_1.log.info(`[book]请求章节目录中,page: ${page}`); const doc = await (0, http_1.getHtmlDOM)(showbooklistAPIUrl, self.charset, { headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "x-requested-with": "XMLHttpRequest", }, body: new URLSearchParams(showbooklistParams).toString(), method: "POST", mode: "cors", credentials: "include", }); if (doc.documentElement.innerText.includes("章節數量較多,採分頁顯示")) { const pageLi = Array.from(doc.querySelectorAll(".uk-list.uk-list-divider > li")).filter((li) => li.innerHTML.includes("換頁: "))[0]; const pages = Array.from(pageLi.querySelectorAll("a")) .map((a) => { const _page = a .getAttribute("onclick") ?.match(/\('\d+','(\d+)'\)/); if (_page?.length === 2) { return Number(_page[1]); } }) .filter((p) => p); pageMax = Math.max(...pages); page++; if (page !== 1 && page <= pageMax) { showbooklistParams.pages = page.toString(); flag = true; } else { flag = false; } } else { flag = false; } const _liList = Array.from(doc.querySelectorAll(".uk-list.uk-list-divider > li")).filter((li) => { const filters = ["章節數量較多,採分頁顯示", "換頁: "]; for (const f of filters) { if (li.innerHTML.includes(f)) { return false; } } return true; }); _liList.push(..._liList); } while (flag); return liListTemp; } const chapters = []; const liList = await getLiList(); let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (const li of liList) { const ukIcon = li.querySelector("span")?.getAttribute("uk-icon"); if (ukIcon === "folder") { const _sectionName = li.querySelector("b > font")?.innerText.trim(); if (_sectionName !== sectionName) { sectionName = _sectionName; sectionNumber++; sectionChapterNumber = 0; } } else if (ukIcon === "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, 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, 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, contentRaw: content, contentText, contentHTML: content, 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 ss = Array.from(doc.querySelectorAll("script")).filter((s) => s.innerText.includes("vercodechk"))[0]; const m = ss.innerText.match(/{\spaperid:\s'(\d+)',\svercodechk:\s'(\w+)'}/); if (m?.length === 3) { const [paperidInner, vercodechkInner] = m.slice(1); return [paperidInner, vercodechkInner]; } 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, 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"); const log_1 = __webpack_require__("./src/log.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, (introDomI) => { (0, misc_1.rm)("b", false, introDomI); return introDomI; }); 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; }) .catch((error) => log_1.log.error(error)); } 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 (const li of chapterList) { 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("article > header > h1").innerText.trim(); const content = doc.querySelector("#content"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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; }) .catch((error) => log_1.log.error(error)); } 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 (const c of Array.from(cs)) { 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, bookId, authorId, chapterId, limitFree, }); const isLogin = () => { const signInDom = document.querySelector(".sign-in"); const signOutDom = document.querySelector(".sign-out"); if (signInDom && signOutDom) { if (Array.from(signOutDom.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 doc = await (0, http_2.ggetHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".j_chapterName > .content-wrap").innerText.trim(); const nullObj = { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; if (doc.querySelector(".vip-limit-wrap")) { return nullObj; } const content = doc.querySelector(".read-content"); const authorSayWrap = doc.querySelector(".author-say-wrap"); if (content) { if (authorSayWrap) { const authorSay = authorSayWrap.querySelector("div.author-say > p:nth-child(3)"); const hr = document.createElement("hr"); content.appendChild(hr); content.appendChild(authorSay); } const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { 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, bookId, chapterId, 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) .catch((error) => log_1.log.error(error)); } async function getByAPI() { const chapterInfo = await getChapterInfo(); if (!chapterInfo) { throw new Error("Request Api failed!"); } 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, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { log_1.log.error(`[chapter]VIP章节API请求失败!\n${JSON.stringify(chapterInfo)}`); return { 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, 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() { const 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; }) .catch((error) => log_1.log.error(error)); } 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}`); const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".title").innerText.trim(); const content = doc.querySelector(".article"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { 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"); const log_1 = __webpack_require__("./src/log.ts"); class Qingoo extends rules_1.BaseRuleClass { constructor() { super(); this.imageMode = "TM"; this.charset = "UTF-8"; } async bookParse() { const 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; }) .catch((error) => log_1.log.error(error)); } 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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 = {}; const coverUrl = dom.querySelector("#hasTicket div.pic img").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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 (const c of Array.from(cs)) { const _chapterName = c .getAttribute("title") ?.trim(); chapterNumber++; sectionChapterNumber++; const chapterName = _chapterName ? _chapterName : ""; const chapterUrl = c.href; let isVIP = false; const 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 chapterId = chapterUrl.split("/").slice(-2, -1)[0]; async function publicChapter() { const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("h1.article-title").innerText.trim(); const content = doc.querySelector(".article-content"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { async function getvipChapterImage(vipChapterImageUrl, vipChapterName) { let retryTime = 0; function fetchVipChapterImage(vipChapterImageUrlI) { log_1.log.debug(`[Chapter]请求 ${vipChapterImageUrlI} Referer ${chapterUrl} 重试次数 ${retryTime}`); return fetch(vipChapterImageUrlI, { 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]请求 ${vipChapterImageUrlI} 失败 Referer ${chapterUrl}`); if (retryTime < setting_1.retryLimit) { retryTime++; return fetchVipChapterImage(vipChapterImageUrlI); } else { return null; } } else { return blob; } }) .catch((error) => log_1.log.error(error)); } 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 chapterNameI = dom.querySelector("h1.article-title").innerText.trim(); isPaid = dom.querySelector(".pay-section") === null; if (isPaid) { const vipChapterDom = dom.querySelector(".article-content > #vipImage"); if (vipChapterDom) { const vipChapterImageUrl = vipChapterDom.src; const vipChapterName = `vipCHapter${chapterId}.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`; return { chapterName: chapterNameI, contentRaw: contentHTML, contentText, contentHTML, contentImages, additionalMetadate: null, }; } else { return publicChapter(); } } } return { 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"); const log_1 = __webpack_require__("./src/log.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, (introDomI) => { (0, misc_1.rm)(".book_keywords", false, introDomI); (0, misc_1.rm)("script", true, introDomI); (0, misc_1.rm)("#cambrian0", false, introDomI); return introDomI; }); 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; }) .catch((error) => log_1.log.error(error)); } 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".kfyd > h2:nth-child(1)").innerText.trim(); const content = doc.querySelector("#content"); if (content) { (0, misc_1.rm)("p:last-child", false, content); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".bookname > h1:nth-child(1)").innerText.trim(); const content = doc.querySelector("#content"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const CryptoJS = __webpack_require__("crypto-js"); 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, (introDomI) => { introDomI.innerHTML = introDomI.innerHTML.replace("简介:", ""); return introDomI; }); const additionalMetadate = {}; const coverUrl = document.querySelector(".book-img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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 (const c of Array.from(cs)) { 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; const keys = item.keys; const len = item.keys.length; const accessKey = item.accessKey; const accessKeyList = accessKey.split(""); const charsNotLatinNum = accessKeyList.length; const 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); const data = output[i]; const iv = btoa(message.substr(0, 16)); const keys255 = btoa(message.substr(16)); const 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 rootPath = "https://www.shubl.com/"; const chapterId = chapterUrl.split("/").slice(-1)[0]; async function publicChapter() { async function chapterDecrypt(chapterIdt, refererUrl) { const accessKeyUrl = rootPath + "chapter/ajax_get_session_code"; const chapterContentUrl = rootPath + "chapter/get_book_chapter_detail_info"; log_1.log.debug(`[Chapter]请求 ${accessKeyUrl} Referer ${refererUrl}`); const accessKeyObj = await (0, http_1.gfetch)(accessKeyUrl, { 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=${chapterIdt}`, responseType: "json", }) .then((response) => response.response) .catch((error) => log_1.log.error(error)); const chapter_access_key = accessKeyObj .chapter_access_key; log_1.log.debug(`[Chapter]请求 ${chapterContentUrl} Referer ${refererUrl}`); const chapterContentObj = await (0, http_1.gfetch)(chapterContentUrl, { 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=${chapterIdt}&chapter_access_key=${chapter_access_key}`, responseType: "json", }) .then((response) => response.response) .catch((error) => log_1.log.error(error)); if (chapterContentObj.code !== 100000) { log_1.log.error(chapterContentObj); throw new Error(`下载 ${refererUrl} 失败`); } return decrypt({ content: chapterContentObj.chapter_content, keys: chapterContentObj.encryt_keys, accessKey: chapter_access_key, }); } const content = document.createElement("div"); const decryptDate = await chapterDecrypt(chapterId, chapterUrl); content.innerHTML = decryptDate; (0, misc_1.rm)(".chapter span", true, content); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } async function vipChapter() { if (isPaid) { async function vipChapterDecrypt(chapterIdi, refererUrl) { const parentWidth = 939.2; const setFontSize = "18"; const imageSessionCodeUrl = rootPath + "chapter/ajax_get_image_session_code"; log_1.log.debug(`[Chapter]请求 ${imageSessionCodeUrl} Referer ${refererUrl}`); const imageSessionCodeObject = await (0, http_1.gfetch)(imageSessionCodeUrl, { 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) .catch((error) => log_1.log.error(error)); if (imageSessionCodeObject.code !== 100000) { log_1.log.error(imageSessionCodeObject); throw new Error(`下载 ${refererUrl} 失败`); } const imageCode = decrypt({ content: imageSessionCodeObject .image_code, keys: imageSessionCodeObject .encryt_keys, accessKey: imageSessionCodeObject .access_key, }); const vipCHapterImageUrlI = rootPath + "chapter/book_chapter_image?chapter_id=" + chapterIdi + "&area_width=" + parentWidth + "&font=undefined" + "&font_size=" + setFontSize + "&image_code=" + imageCode + "&bg_color_name=white" + "&text_color_name=white"; return vipCHapterImageUrlI; } const vipCHapterImageUrl = await vipChapterDecrypt(chapterId, 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) .catch((error) => log_1.log.error(error)); const vipCHapterName = `vipCHapter${chapterId}.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); const contentText = `VIP章节,请打开HTML文件查看。\n`; return { chapterName, contentRaw: contentHTML, contentText, contentHTML, contentImages, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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 = {}; const 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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of Array.from(dsList)) { 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 doc = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("div.chapter-name").innerText .replace("正文 ", "") .trim(); const content = doc.querySelector("#reader-content > div:nth-child(1)"); if (content) { (0, misc_1.rm)("div.chaper-info", false, content); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { 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") ?? document.querySelector("span.bookinfo:nth-child(1)")).innerText .replace(/^作者:/, "") .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 { const { 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) { const { 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, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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, (introDomI) => { (0, misc_1.rm)("span.tags", false, introDomI); (0, misc_1.rm)("q", true, introDomI); return introDomI; }); 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; }) .catch((error) => log_1.log.error(error)); } const chapters = []; const novelList = document.querySelector("div.novel_list[id]"); const sections = Array.from(novelList.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 }); 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(); } } }); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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() { const 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; }) .catch((error) => log_1.log.error(error)); } 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()}`); } }) .catch((error) => log_1.log.error(error)); if (!jsonpText) { throw new Error("jsonp request failed!"); } const callback = (obj) => { return obj; }; const contentObj = eval(jsonpText); if (typeof contentObj === "object") { content.innerHTML = contentObj.content; const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } } return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } async function vipChapter() { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } const liList = document.querySelectorAll("#readerlist > ul > li"); const chapters = []; let chapterNumber = 0; let sectionNumber = 0; let sectionName = null; let sectionChapterNumber = 0; for (const li of Array.from(liList)) { 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 }); 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, ""))); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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, (introDomI) => { introDomI.innerHTML = introDomI.innerHTML .replace(/^.+简介:\s+www.uukanshu.com\s+/, "") .replace(/\s+https:\/\/www.uukanshu.com/, "") .replace(/-+/, ""); return introDomI; }); 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; }) .catch((error) => log_1.log.error(error)); } 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 (const li of Array.from(chapterList)) { 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector("#timu").innerText.trim(); const content = doc.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 (const r of contentReplace) { content.innerHTML = content.innerHTML.replace(r, ""); } const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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 = {}; const 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; }) .catch((error) => log_1.log.error(error)); } 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 (const td of Array.from(tdList)) { 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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 = {}; const coverUrl = document.querySelector(".img-img") .src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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, (introDomI) => { introDomI.innerHTML = introDomI.innerHTML.replace("内容简介:", ""); return introDomI; }); 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; }) .catch((error) => log_1.log.error(error)); } 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 (const a of Array.from(cos)) { chapterNumber++; sectionChapterNumber++; 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".page-body > h1:nth-child(4)").innerText.trim(); const _content = doc.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, "<br/>"); const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const CryptoJSGlobal = __webpack_require__("crypto-js"); 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; }) .catch((error) => log_1.log.error(error)); } 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()) .catch((error) => log_1.log.error(error)); 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 = ""; const ttmpColumnList = []; let ttmpChapterList = []; 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", ""); ttmpChapterList.push({ chapterid: Number(chapterid) - bookid * 11, chaptername: chapterName, isempty: 0, originalurl: "", currenturl: "", }); } else if (node.nodeName === "DT") { const tmpColumnObj = { columnname: tmpColumnName, columnid: 0, chapterlist: ttmpChapterList, }; ttmpColumnList.push(tmpColumnObj); tmpColumnName = node.innerText .replace(`《${bookname}》`, "") .trim(); ttmpChapterList = []; } } else { tmpColumnName = node.innerText .replace(`《${bookname}》`, "") .trim(); } } } return [ttmpColumnList, ttmpChapterList]; }; 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) { const key = CryptoJS.enc.Utf8.parse(keyStr); const iv = CryptoJS.enc.Utf8.parse(ivStr); const encryptedHexStr = CryptoJS.enc.Hex.parse(str); const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); const decrypt = CryptoJS.DES.decrypt(srcs, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function gettt2(str, keyStr, ivStr) { const key = CryptoJS.enc.Utf8.parse(keyStr); const iv = CryptoJS.enc.Utf8.parse(ivStr); const encryptedHexStr = CryptoJS.enc.Hex.parse(str); const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); const decrypt = CryptoJS.AES.decrypt(srcs, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function gettt3(str, keyStr, ivStr) { const key = CryptoJS.enc.Utf8.parse(keyStr); const iv = CryptoJS.enc.Utf8.parse(ivStr); const encryptedHexStr = CryptoJS.enc.Hex.parse(str); const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); const decrypt = CryptoJS.RC4.decrypt(srcs, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function getttn(str, keyStr, ivStr) { const key = CryptoJS.enc.Utf8.parse(keyStr); const iv = CryptoJS.enc.Utf8.parse(ivStr); const encryptedHexStr = CryptoJS.enc.Hex.parse(str); const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); const decrypt = CryptoJS.TripleDES.decrypt(srcs, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } function showttt1(dom) { const obj = dom.getElementById("other"); const objTips = dom.getElementById("contenttips"); if (obj) { let content = obj.innerHTML.trim(); const type = parseInt(content.substring(0, 1), 10); 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(doc); } const doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); runEval(CryptoJSGlobal); chapterName = doc.querySelector(".bookname > h1:nth-child(1)").innerText.trim(); const contentG = doc.querySelector("#content"); if (contentG) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(contentG, "TM"); return { chapterName, contentRaw: contentG, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 (const node of chapterList) { 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 }); 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"); const log_1 = __webpack_require__("./src/log.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; }) .catch((error) => log_1.log.error(error)); } 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 doc = await (0, http_1.getHtmlDOM)(chapterUrl, charset); chapterName = doc.querySelector(".bookname > h1:nth-child(1)").innerText.trim(); const content = doc.querySelector("#content"); if (content) { const { dom, text, images } = await (0, cleanDOM_1.cleanDOM)(content, "TM"); return { chapterName, contentRaw: content, contentText: text, contentHTML: dom, contentImages: images, additionalMetadate: null, }; } else { return { 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, (introDomI) => { (0, misc_1.rm)("span:nth-child(1)", false, introDomI); return introDomI; }); 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 indexUrlsI = []; const maxPageNumber = Number(getMaxPageNumber()); for (let i = 1; i <= maxPageNumber; i++) { const indexUrl = [ document.location.origin, document.location.pathname.split("/")[1], `${bookId}_${i}`, ].join("/") + "/"; indexUrlsI.push(indexUrl); } return indexUrlsI; }; const indexUrls = getIndexUrls(); let lis = []; for (const indexUrl of indexUrls) { log_1.log.debug(`[chapter]请求 ${indexUrl}`); const doc = await (0, http_1.getHtmlDOM)(indexUrl, "UTF-8"); const ul = doc.querySelector("ul.chapters"); if (ul?.childElementCount) { lis = lis.concat(Array.from(ul.children)); } } const chapterList = lis.filter((obj) => obj !== undefined); let chapterNumber = 0; for (const node of chapterList) { 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)); const 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++) { const 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) { const { 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); const { 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, contentRaw: content, contentText: finalText, contentHTML: finalDom, contentImages: finalImages, additionalMetadate: null, }; } else { return { 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"); const log_1 = __webpack_require__("./src/log.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 = {}; const coverUrl = doc.querySelector("div.book-img > img").src; if (coverUrl) { (0, attachments_1.getImageAttachment)(coverUrl, this.imageMode, "cover-") .then((coverClass) => { additionalMetadate.cover = coverClass; }) .catch((error) => log_1.log.error(error)); } 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 (const c of Array.from(cs)) { 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 doc = await (0, http_1.ggetHtmlDOM)(chapterUrl, charset); const ChapterName = doc.querySelector("div.title_txtbox").innerText.trim(); const content = doc.querySelector("div.content"); if (content) { 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 { return { chapterName: ChapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } } async function vipChapter() { return { chapterName, contentRaw: null, contentText: null, contentHTML: null, contentImages: null, additionalMetadate: null, }; } if (isVIP) { return vipChapter(); } else { return publicChapter(); } } } exports.Zongheng = Zongheng; /***/ }), /***/ "./src/save/save.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getSaveBookObj = exports.saveOptionsValidate = exports.getSectionsObj = 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"); const main_css_1 = __webpack_require__("./src/save/main.css"); const toc_css_1 = __webpack_require__("./src/save/toc.css"); const template_1 = __webpack_require__("./src/save/template.ts"); const progress_1 = __webpack_require__("./src/ui/progress.ts"); const file_saver_1 = __webpack_require__("./node_modules/file-saver/dist/FileSaver.min.js"); class SaveBook { constructor(book) { this.book = book; this.chapters = book.chapters; this.savedZip = new zip_1.FflateZip(); this._sections = []; this.savedTextArray = []; this.saveFileNameBase = `[${this.book.author}]${this.book.bookname}`; this.mainStyleText = main_css_1.default; this.tocStyleText = toc_css_1.default; } saveTxt() { const metaDateText = this.genMetaDateTxt(); this.savedTextArray.push(metaDateText); log_1.log.debug("[save]对 chapters 排序"); this.chapters.sort(this.chapterSort); const sections = []; for (const chapterTemp of this.chapters) { const chapterName = this.getchapterName(chapterTemp); if (chapterTemp.sectionName && !sections.includes(chapterTemp.sectionName)) { sections.push(chapterTemp.sectionName); const sectionText = this.genSectionText(chapterTemp.sectionName); this.savedTextArray.push(sectionText); } const chapterText = this.genChapterText(chapterName, chapterTemp.contentText ?? ""); this.savedTextArray.push(chapterText); if (!setting_1.enableDebug.value) { chapterTemp.contentText = null; } } log_1.log.info("[save]保存TXT文件"); const savedText = this.savedTextArray.join("\n").replaceAll("\n", "\r\n"); (0, file_saver_1.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); } } log_1.log.debug("[save]开始生成并保存卷文件"); this.saveSections(); log_1.log.debug("[save]开始生成并保存 index.html"); this.saveToC(); if (runSaveChapters) { log_1.log.debug("[save]开始保存章节文件"); this.saveChapters(); } else { log_1.log.debug("[save]保存仅标题章节文件"); this.chapters .filter((c) => c.status !== main_1.Status.saved) .forEach((c) => this.addChapter(c)); } log_1.log.info("[save]开始保存ZIP文件"); const self = this; self.saveLog(); return new Promise((resolve, reject) => { const finalHandle = (blob) => { (0, file_saver_1.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) => { progress_1.vm.zipPercent = percent; }); }); } saveToC() { log_1.log.debug("[save]对 chapters 排序"); this.chapters.sort(this.chapterSort); const self = this; const sectionsListObj = getSectionsObj(self.chapters); modifyTocStyleText(); const indexHtmlText = template_1.index.render({ creationDate: Date.now(), bookname: self.book.bookname, tocStyleText: self.tocStyleText, author: self.book.author, cover: self.book.additionalMetadate.cover, introductionHTML: self.book.introductionHTML?.outerHTML, bookUrl: self.book.bookUrl, sectionsObj: Object.values(sectionsListObj), Status: main_1.Status, }); this.savedZip.file("index.html", new Blob([indexHtmlText.replaceAll("data-src-address", "src")], { type: "text/html; charset=UTF-8", })); function modifyTocStyleText() { if (self.book.additionalMetadate.cover) { self.tocStyleText = `${self.tocStyleText} .info { display: grid; grid-template-columns: 30% 70%; }`; } else { self.tocStyleText = `${self.tocStyleText} .info { display: grid; grid-template-columns: 100%; }`; } } } saveChapters() { for (const chapter of this.chapters) { this.addChapter(chapter); } } saveSections() { log_1.log.debug("[save]对 chapters 排序"); this.chapters.sort(this.chapterSort); for (const chapter of this.chapters) { const chapterNumberToSave = this.getChapterNumberToSave(chapter); const sectionHtmlFileName = `No${chapterNumberToSave}Section.html`; 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); this.savedZip.file(sectionHtmlFileName, sectionHTMLBlob); } } } } getChapterNumberToSave(chapter) { return `${"0".repeat(this.chapters.length.toString().length - chapter.chapterNumber.toString().length)}${chapter.chapterNumber.toString()}`; } addChapter(chapter) { const chapterName = this.getchapterName(chapter); const chapterNumberToSave = this.getChapterNumberToSave(chapter); const chapterHtmlFileName = `No${chapterNumberToSave}Chapter.html`; log_1.log.debug(`[save]保存章HTML文件:${chapterName}`); const chapterHTMLBlob = this.genChapterHtmlFile(chapter); if (!setting_1.enableDebug.value) { chapter.contentRaw = null; chapter.contentHTML = null; } this.savedZip.file(chapterHtmlFileName, chapterHTMLBlob); chapter.chapterHtmlFileName = chapterHtmlFileName; chapter.status = main_1.Status.saved; if (chapter.contentImages && chapter.contentImages.length !== 0) { log_1.log.debug(`[save]保存章节附件:${chapterName}`); for (const attachment of chapter.contentImages) { this.addImageToZip(attachment, this.savedZip); } if (!setting_1.enableDebug.value) { chapter.contentImages = null; } } } 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); attachment.status = main_1.Status.saved; if (!setting_1.enableDebug.value) { attachment.imageBlob = null; } } 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(chapterObj) { const htmlText = template_1.section.render({ sectionName: chapterObj.sectionName }); return new Blob([htmlText.replaceAll("data-src-address", "src")], { type: "text/html; charset=UTF-8", }); } genChapterHtmlFile(chapterObj) { const htmlText = template_1.chapter.render({ chapterUrl: chapterObj.chapterUrl, chapterName: chapterObj.chapterName, outerHTML: chapterObj.contentHTML?.outerHTML ?? "", }); return new Blob([htmlText.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 getSectionsObj(chapters) { const _sectionsObj = {}; for (const chapter of chapters) { let sectionNumber = null; const sectionName = null; if (chapter.sectionNumber && chapter.sectionName) { sectionNumber = chapter.sectionNumber; } else { sectionNumber = -99999999; } if (_sectionsObj[sectionNumber]) { _sectionsObj[sectionNumber].chpaters.push(chapter); } else { _sectionsObj[sectionNumber] = { sectionName: chapter.sectionName, sectionNumber: chapter.sectionNumber, chpaters: [chapter], }; } } const _sectionsListObj = Object.entries(_sectionsObj); function sectionListSort(a, b) { const aKey = Number(a[0]); const bKey = Number(b[0]); if (aKey > bKey) { return 1; } if (aKey === bKey) { return 0; } if (aKey < bKey) { return -1; } return 0; } _sectionsListObj.sort(sectionListSort); const sectionsListObj = _sectionsListObj.map((s) => s[1]); return sectionsListObj; } exports.getSectionsObj = getSectionsObj; function saveOptionsValidate(data) { const keyNamesS = ["mainStyleText", "tocStyleText"]; const keyNamesF = [ "getchapterName", "genSectionText", "genChapterText", "genSectionHtmlFile", "genChapterHtmlFile", "chapterSort", ]; 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 (Object.prototype.hasOwnProperty.call(data, keyname)) { 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)) { Object.assign(saveBookObj, options); } if (book.saveOptions !== undefined) { Object.assign(saveBookObj, book.saveOptions); } return saveBookObj; } exports.getSaveBookObj = getSaveBookObj; /***/ }), /***/ "./src/save/template.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.index = exports.chapter = exports.section = void 0; const section_html_j2_1 = __webpack_require__("./src/save/section.html.j2"); const chapter_html_j2_1 = __webpack_require__("./src/save/chapter.html.j2"); const index_html_j2_1 = __webpack_require__("./src/save/index.html.j2"); const nunjucks = __webpack_require__("nunjucks"); const env = new nunjucks.Environment(undefined, { autoescape: false }); exports.section = new nunjucks.Template(section_html_j2_1.default, env, undefined, true); exports.chapter = new nunjucks.Template(chapter_html_j2_1.default, env, undefined, true); exports.index = new nunjucks.Template(index_html_j2_1.default, env, undefined, true); /***/ }), /***/ "./src/setting.ts": /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.r18SiteList = exports.iconJump = exports.iconSetting = exports.iconStart1 = exports.iconStart0 = exports.enableJjwxcRemoteFont = exports.enableR18SiteWarning = exports.enableCustomSaveOptions = exports.enableCustomChapterFilter = exports.enableCustomFinishCallback = exports.enableDebug = exports.retryLimit = void 0; exports.retryLimit = 5; exports.enableDebug = { value: unsafeWindow.enableDebug ?? false, }; exports.enableCustomFinishCallback = true; exports.enableCustomChapterFilter = true; exports.enableCustomSaveOptions = true; exports.enableR18SiteWarning = false; exports.enableJjwxcRemoteFont = true; exports.iconStart0 = "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.iconStart1 = "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.iconSetting = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABmJLR0QA/wD/AP+gvaeTAAAIxElEQVR4nO2dW4wWRRbHfzArzAIioFxk4oMKjLgqug9k2UUi3g0YYwKId59UXnaj0ejDamLUxTWi8cEbglFJvL7hLfFuHBGNVxBXjFGZWVC8jIoDOzPLTPtwvk+GoafOqe6qntbpf1LJZKrr1L+quqtOnXOqPqhQoUKFChUqVKhQoUKF8uDvQBIoXVUwdzOGDzYBB44JKOtPAWUFRZkHYFZAWUcHlDUk0ADsJNwUtKsms3Qo6xcwAxgVUN4fgcMCyguGsg5AyPm/jlJOQ0NpAI6KIDM3yjoAIRfgOko5AGVFG+5F9fiUMqcrZT6Ozvp3goOAXtydOT6lXJNS5v9AY2Tuv2mcAKwCfsDdkVscMtqVsiuAA+PQ/+3iNGA9dp3+KYes1wzlfwZuASbm4LxfjrJRcASwGXnD5mJb3A8BnsF/U3WTQ+ZdHnI6gFuBA4xtbEBeljXIVzrTWK4QPMvejfsauA9ZGEekPH8x8BP+nZ8ASxw8lmWQtw041yFzFvJibetX7jlHmUKxAHcDfwQeARYDE4B7lOe11OzgMjeH3Bf7yG4CrgY2KGUW+HVVeIwAPsHeSE270dKnuG0643LK7wReB3qMz28m/QsvDFemkAqduoAngFOwrS0n157vKoBbUuuDQcFEdJUxa+pB3sQrgMkZ+U0GrgFaI3Gspx+BSRk55sJ9GchqaTdwP3BoQJ4jkcV5SwS+9bQyIF8TjkU6K2QjNgGzI3IeAVwGfBOYd/3FOTYi933wauAGPAqMLoj7OOBOwr9ALcCwIhqwyEDmv8Db2LSeFUWQTsFsRKuydG478K3hucWxSTcCXxiILKo9fwhwKWI+6E557vbYhBVMRqa+gaaVF4CLEO+c5cVrJawnbx/800DiddI/xQlIY55AzACD3fl1TEZM1X3XomtI12xeQW//dbGINiGGrBCLUZb5fixwHqIlvY0spt219E3tfyuBpcD+nrKbkI6boTxnUT46avKC42Gl4gS4N0K9zcBqJLLBuiDuREzb0yPwsajfa0JX+hdsC+pJAescBdyGOFKsHd8/dSMWz5COmAsN9fYCc0JVOAy7vb49UMXTgY3GOi3pTeDgALwuxf5CvEVAn/vV2A1pP5PvSziOOJulNrJHWwwDbvSs7w4CBz1cht1K2AmclaGO6cTp/L6D4Psl7Ac86FFHD2LDioKlpOvzaWk3cImH7EbgA6PsPOkdJFLOgjHs62zSXrylHm3OhDOB/xkJ9QCXG+XeZpQZIt1g4NMIvO8hs530cJkomA/sMBLrRY9EaMa2uPUCTwMXILGeo2rpcEQ7edrIqQOYonAajl31/ZJB8BHPBr43kNtqkLXaIKcV+KtB1lz0wK4EuNsg612DnPcIo2FlwlHs66zun9YqMsaih6K34tfIqeiD0IHM8S6sUWS04L/r3gt51aSPkFgcF95V8hfiNmAlyML2lQcvLdIBxByiOdU3KfmtiNqdGSH0VC3o9T0lf76S/wywzk7nV7QgGowLJyr52gDkPvoUYgCmKvmblXwtEvpxDy6+ZbW6Ne5a2wuBppJqlk/N0ZHnZMs0RfZ2pfxopfyuHNyCQdsda2eztPCRPA4OrQM7lfJ/UMrvzsENKOaARpKzfB4/ayE+2jwIMQBdSr4WObZDyc8aFwT6ZusnJX+kkt/twSUVIQagQ8nXOvBzJf9vHlx8y2p1a56tnR5cUhFiAFwHJkAPsvpQyT/Hg0t/aIYxrW5XIDDYdvlOhBgA7S06Usl/WclfgJgXfDEPCY934SUl/89K/n/sdOJgDOJtcmkKqxUZ+6ObItrw07mbkNikvKaItYqMHcCpHryCYgo2Y9UHBlmrDHLasH0J89A7P8EWz7nVIKcbP79HEMzEFqCVIGZmzQEyHbuj51kkvmgaouePrv19MXbnSRf6Bm+SUVaCmMmvV+QFw/HYzND19D42i+GtHjLzpuXGtl6L36GSVcjmLRrOxi8+50Xsh+Aa0deTEGkdun7fF4uwewAT4HnExB4c/8DulE+Ah/A/zjmFuAcqtpItam0+chDDWs+HGetJxXAkxMKnoTeS3QxwDDaPlm9qJd+NKUd78tpEIFPIMCTIyFLpbuxOeBcmYjt07TPtaGYJC6Zid9S7zjN7Yw62xejCgHU2ItELHYZ6B0pdwL/wm/M1nGCodzsR1gHNP5oggauhMQVxoPsMREeNS4xbsl4y1L8sQr00oXeCJTx9BhIK7rtIjUHsQvcisarbkTe8q/b3euQQ+BL0HW4aLCHzC9E7/2MiqqLXGQiknZUajwS2trBnKvuUSHH0GbAcUTVfQLS9tPWiAQlC0Nq/MCZRnyNKI5EoOteh6TIMwnLSv+QW5KTMtNpzlnsoXimC8GIDkW/R7+7pOwgxj6e6sMLAr5c9J3Jcz/WgW0+DIfQx1V7kBM5BBfEfAzwWuA0PFsQdiHNQO0HessuJewHGHMSOH5L3LuREaKFYGYD4QGkLMueG1N+nAQ8Q58W5OSBPMybhZx/JktqQhTDPhR1XAG/gZ8fySVE2XVYUcV1Nwp4ra042cBqOXG1T1JU1UTZdVoxAwvcsROtX0HQanx8ojXPwacB+/cBAycf+H3XTZYV2ZdkG5JBfXd9vRjY8WTvI5ZZsziE3QS79m4Co2o+g32sXddPlg+fYm9g2RMd2Bb8uxeZz9fnkl2SQlyBr2fkp8kYCZyAKx/Z+ZbRojkIxE7k9aw1ytaP1rv6xwL/xM7Td5ZB3k4ecelqLbTfegDj870BCcQrbdFmR5zLTiYhJwHLuzHUg5ClD+Xp6A9uiPqRwILp5oN1RXruW7Afkso95cej/PtCIfmIybcoYr5TppThThxll/P2ATuAz5Zm0Y1HaNQRtwHeZGA1BPEk+dXKgxbZ0KOMXAOL4CA0tEnpQMJQGYEMEmblR1gHYGEFmKQegrGjALwRSS9UPuXmih7CHHzbWZJYOZR0ACDsNlXIBhnIPQMiFuJr/K1SoUKFChQoVKlSoUBr8Ah3QujNKRJdpAAAAAElFTkSuQmCC"; exports.iconJump = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAG6wAABusBTDGeSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAeVSURBVHic7VpvTBNpHv6901L+yQU3nCfrByU9IRYrWrCVGkVzgu4ZCSFSMBDJrhcTP+iqMdlcLvFyl7sPftn9diZsiHterpYz8TxuCXsauBNy2VVoXIEIXV2hAYt/WqF/mMGZ6fzugwxXSjudlnYHWJ5kMm+n7/zmeZ55531/7ztDEBF+zKCUJqA01gxQmoDSWDNAaQJKY80ApQkojTUDlCawFNTU1Pzk3LlzzYQQkmiMFW0AABzRarVfXLx40UYISUjLijaA4zjNunXrQK/XWy5dutS5b98+dbwxVrQB4jwmIyMDtm/fXrV3796eQ4cOZcYTY0UbEAqNRgM6na7caDTeP3r0aI7c81aNAQAAaWlpsG3bNr3BYHhYW1v7npxzVpUBAABqtRoKCwu1er1+sK6uLj9W/RVtQLS1DJVKBVu3bn1fr9cPWCyWAqkYK9oAKVAUBVqtNq+kpORRQ0ODLlo9kooVoVOnTv0yOzv7F1J1Yl1XDi+e53++e/fu6uzs7AX1w8sTExPMo0eP9lmtVnt4jKQbQAhJv3z58rDBYJhveuI1pEjKLSd6nsvlYh8+fFhptVp7Qvmm4hFQAUDCqWmqkJ+frykrK+tubGz8IPR4SvqA5brQumHDBpXJZPqyqampTjy2KjvBYDAILMsCwzAQCATA5/OB1+uFqakpAACqsLDQ1tzcfAoAIO7cWQ5S3QIEQYDZ2VngOA6CwSDwPA88z8+XAQDECWKkfVZWFqXVaj9vaGiYTYkByQbP80DTNDAMAwzDAMuyABBZnJRwcY+IMDMz4x8eHuYTNoAQQk6fPn1yYmLi7x0dHb7Q/5baAliWBZqm5zc5d1WOcJGby+V6cevWrY+dTudXCRlACKHOnj17o6ioyPL8+XMGAP6WSBwRgiCAz+cDn88HDMNAMBiUJSYe4YQQCAaD4HQ6v2tra/vY7Xb3ICIdtwFms1l9/vz5DpPJVMXzPLAsqwmvg4goipj7vWAP8K6jCgQCMD09DYFAICJpKcQjnBACLMvCkydPHlit1osMw/Qj4luAODvBAwcOZJrN5i6j0Vienp4OPp8vUjX+7t27nz5+/NgoFSsZmWBWVtZPi4uLj6Snp0u2jtnZWRgaGuq02Wy/EQRhEBF5MYZsAw4fPpxjMpn+W1paqtdoNICIEUkiIksI+UtfX9+SHgs5OHjw4NHi4uIj4Y9CaDkQCEBfX9+f29vbrwCAAxGF0BiyDDh27Nh7ZWVlD0pKSrRpaWnz4qPdJUT0LkWYXFRWVnKi4Ej9gdfrFXp6ej7r7u7+EwCMYgTCMQ2oqanJ37lzZ79er39frVaDIPzfwNCyUiCEAEVR82URr1+/Zru6un53//79LxDRFe18SQNqa2sLdu3a9UCn0+VRFDUveLmkuiKP8DF+cnLS39nZ+cng4OBNRHRLxYhqwPHjx3UGg+GboqKiHACIKH65tADRAEEQYHx8/OXt27cvjI6OdiBixF46FBENsFgspaWlpb1arTYz1jR0y5YtdWfOnNkVSihSWeo/OWW/3/+v1tbWO+FcRQM4joPR0dHvb968ee7Vq1f/QUQ6suSFWGRAfX39/rKysrubN2/WSIlHRMjMzASz2Vw9PT0NDMNEHMfjGa+l9uPj45WEkN3i+B0an2VZcDgc9ra2tgt+v/9BeB3ZBtTX139gNBr/uWnTJlV4Lx9eRkSYmpoCv98fNXGJJSoezF1fFXYMaZqGp0+f3rHZbL8WBGEgdIyXg3kDTpw4Ubdnzx7bxo0bqdBnO5IJHMeBx+MBlmWXJE7u3Y8Gu93+Lcdxf+zt7bUCwEj4GC8HagCAxsbGX5WXl7fk5eWRaOJF0DQNHo8n5kiQzLsf7Ryv1+vo7e29AgCBSGO8HKgtFkvj/v37P8/NzY3Zq79582ZBk0+GqKXEmmvu/rgvHgJqeHiY93g8tJT4YDAILpcL/H7pay21SUvFEpOdZIMaGhrqvHbt2ocOh8MTOoMTEQwG4cWLF8BxXERiSt39ZIFCRJ/T6fyypaWlaWBgYEwUCrBYvBRS8cz/EMZQAACISLvd7n9fvXq1yW63f8uy7ALxUoRCJ0ZSm1g31h4RQRCERVuq0u8FL0YIIWqKovQnT568UlBQUBk+yQjfcxwHIyMjXzEM8zpicIlMMNrxaHXGxsa+7u/vb0VEVpYymVj0Zoi8+9SkqLq6+pMdO3Y0Z2RkLCAWSpDjOLh3795H3d3dHckkFQVvUzHNXpQKI6JACBlpb2///czMjNtkMl3Iyspa1AWLRqhUKg4RXyWb2A+FiJOhuaTiGSHk05mZmTcVFRW/zcnJ0SjRS6cakusBiOgihLTQND1VVVV1Zf369TkAyg5byUbMFSFEdBNC/hoIBKarq6s/y8vL+5lKpYp12oqBrPQKEX3Pnj37x40bNz6anJz8XhCEVXH3AeJ4OYqI9MuXL7uuX7/+4djYmF1OcrQSEFeCjYhv/X7/162tracdDseduXd0y2OBMFHIzeTCsjoKAHQVFRV/yM3NLU4kxnLZEv5EhrzrBNYBABPvKsxyQko+klpJWJVfiMSDNQOUJqA01gxQmoDSWDNAaQJK40dvwP8AKk+/HC2PJW8AAAAASUVORK5CYII="; exports.r18SiteList = [ "www.dierbanzhu1.com", "www.bz01.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; async function getStatData() { const _data = await (0, GM_1._GM_getValue)(statKeyName); let statData; if (_data) { statData = JSON.parse(_data); } else { statData = { success: {}, failed: {} }; } return statData; } const saveData = async (statData) => { const dataJSON = JSON.stringify(statData); await (0, GM_1._GM_setValue)(statKeyName, dataJSON); return statData; }; const dataPlus = async (key) => { const statData = await getStatData(); const tmpData = statData[key]; if (tmpData[domain]) { tmpData[domain] = tmpData[domain] + 1; } else { tmpData[domain] = 1; } return saveData(statData); }; const successPlus = () => { return dataPlus("success"); }; exports.successPlus = successPlus; const failedPlus = () => { return dataPlus("failed"); }; exports.failedPlus = failedPlus; const printStat = async () => { const statData = await getStatData(); log_1.log.info("[stat]小说下载器脚本运行情况统计:"); log_1.log.info(statData); for (const k in statData) { if (Object.prototype.hasOwnProperty.call(statData, k)) { log_1.log.info(`[stat]${k}:`); const subData = statData[k]; for (const j in subData) { if (Object.prototype.hasOwnProperty.call(subData, j)) { log_1.log.info(` [stat]${j}: ${subData[j]}`); } } } } }; exports.printStat = printStat; const resetStat = () => { const statData = { success: {}, failed: {} }; return saveData(statData); }; exports.resetStat = resetStat; /***/ }), /***/ "./src/ui/ChapterList.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); const Vue = __webpack_require__("./node_modules/vue/index.js"); const download_1 = __webpack_require__("./src/router/download.ts"); const main_1 = __webpack_require__("./src/main.ts"); const save_1 = __webpack_require__("./src/save/save.ts"); const ChapterList_html_1 = __webpack_require__("./src/ui/ChapterList.html"); const ChapterList_css_1 = __webpack_require__("./src/ui/ChapterList.css"); const createEl_1 = __webpack_require__("./src/lib/createEl.ts"); const FilterTab_1 = __webpack_require__("./src/ui/FilterTab.ts"); async function getSections() { if (window._sections) { return window._sections; } else { const rule = await (0, download_1.getRule)(); const book = await rule.bookParse(); window._sections = (0, save_1.getSectionsObj)(book.chapters); return window._sections; } } (0, createEl_1.createStyle)(ChapterList_css_1.default); exports["default"] = Vue.defineComponent({ name: "ChapterList", setup(props, context) { const sectionsObj = Vue.reactive([]); const loading = Vue.ref(true); Vue.onMounted(async () => { if (sectionsObj.length === 0) { const _sectionsObj = await getSections(); Object.assign(sectionsObj, _sectionsObj); } loading.value = false; }); const filterSetting = Vue.inject("filterSetting"); const filter = (chapter) => { if (chapter.status === main_1.Status.aborted) { return false; } if (filterSetting.value) { const filterFunction = (0, FilterTab_1.getFilterFunction)(filterSetting.value.arg, filterSetting.value.functionBody); if (typeof filterFunction === "function") { return filterFunction(chapter); } } return true; }; const isChapterDisabled = (chapter) => { if (!chapter?.chapterUrl) { return true; } return false; }; const isChapterSeen = (chapter) => { if (filterSetting.value.hiddenBad && filter(chapter) === false) { return false; } else { return true; } }; const isSectionSeen = (sectionObj) => { const chapters = sectionObj.chpaters; return chapters.some((chapter) => isChapterSeen(chapter) === true); }; return { sectionsObj, loading, filter, isChapterDisabled, isChapterSeen, isSectionSeen, }; }, template: ChapterList_html_1.default, }); /***/ }), /***/ "./src/ui/FilterTab.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getFilterFunction = exports.filterOptionDict = exports.getFunctionBody = void 0; const Vue = __webpack_require__("./node_modules/vue/index.js"); const FilterTab_html_1 = __webpack_require__("./src/ui/FilterTab.html"); const FilterTab_css_1 = __webpack_require__("./src/ui/FilterTab.css"); const ChapterList_1 = __webpack_require__("./src/ui/ChapterList.ts"); const createEl_1 = __webpack_require__("./src/lib/createEl.ts"); function getFunctionBody(fn) { return fn .toString() .replace("(arg) => {", "") .replace(/}$/, "") .split("\n") .map((l) => l.trim()) .join(" ") .trim(); } exports.getFunctionBody = getFunctionBody; exports.filterOptionDict = { null: { raw: (arg) => { return (chapter) => true; }, description: "<p>不应用任何过滤器(默认)</p>", abbreviation: "无", }, number: { raw: (arg) => { function characterCheck() { return /^[\s\d\-,,]+$/.test(arg); } function match(s, n) { switch (true) { case /^\d+$/.test(s): { const _m = s.match(/^(\d+)$/); if (_m?.length === 2) { const m = Number(_m[1]); if (m === n) { return true; } } return false; } case /^\d+\-\d+$/.test(s): { const _m = s.match(/^(\d+)\-(\d+)$/); if (_m?.length === 3) { const m = _m.map((_s) => Number(_s)); if (n >= m[1] && n <= m[2]) { return true; } } return false; } case /^\d+\-$/.test(s): { const _m = s.match(/^(\d+)\-$/); if (_m?.length === 2) { const m = Number(_m[1]); if (n >= m) { return true; } } return false; } case /^\-\d+$/.test(s): { const _m = s.match(/^\-(\d+)$/); if (_m?.length === 2) { const m = Number(_m[1]); if (n <= m) { return true; } } return false; } default: { return false; } } } if (!characterCheck()) { return; } return (chapter) => { const n = chapter.chapterNumber; const ss = arg.split(/,|,/).map((s) => s.replace(/\s/g, "").trim()); return ss.map((s) => match(s, n)).some((b) => b === true); }; }, description: "<p>基于章节序号过滤,章节序号可通过章节标题悬停查看。</p><p>支持以下格式:13, 1-5, 2-, -89。可通过分号(,)使用多个表达式。</p>", abbreviation: "章节序号", }, baseOnString: { raw: (arg) => { return (chapter) => { return (chapter && chapter.chapterName?.includes(arg)) || false; }; }, description: "<p>过滤出所有包含过滤条件字符的章节</p>", abbreviation: "章节标题", }, }; function getFilterFunction(arg, functionBody) { const filterFunctionFactor = new Function("arg", functionBody); const filterFunction = filterFunctionFactor(arg); if (typeof filterFunction === "function") { return filterFunction; } else { return undefined; } } exports.getFilterFunction = getFilterFunction; exports["default"] = Vue.defineComponent({ components: { "chapter-list": ChapterList_1.default }, emits: ["filterupdate"], setup(props, { emit }) { const arg = Vue.ref(""); const hiddenBad = Vue.ref(true); const filterType = Vue.ref("null"); const filterOptionList = Object.entries(exports.filterOptionDict); const functionBody = Vue.computed(() => getFunctionBody(exports.filterOptionDict[filterType.value].raw)); const filterDescription = Vue.computed(() => exports.filterOptionDict[filterType.value].description); const filterSetting = Vue.computed(() => ({ arg: arg.value, hiddenBad: hiddenBad.value, filterType: filterType.value, functionBody: functionBody.value, })); Vue.provide("filterSetting", filterSetting); Vue.watch(filterSetting, () => { emit("filterupdate", filterSetting.value); }, { deep: true, }); const getFilterSetting = Vue.inject("getFilterSetting"); Vue.onMounted(() => { const faterFilterSetting = getFilterSetting(); if (faterFilterSetting) { arg.value = faterFilterSetting.arg; hiddenBad.value = faterFilterSetting.hiddenBad; filterType.value = faterFilterSetting.filterType; } }); return { arg, hiddenBad, filterType, filterOptionList, filterDescription, }; }, template: FilterTab_html_1.default, }); (0, createEl_1.createStyle)(FilterTab_css_1.default); /***/ }), /***/ "./src/ui/button.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.vm = exports.el = void 0; const Vue = __webpack_require__("./node_modules/vue/index.js"); const createEl_1 = __webpack_require__("./src/lib/createEl.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); const download_1 = __webpack_require__("./src/router/download.ts"); const ui_1 = __webpack_require__("./src/router/ui.ts"); const log_1 = __webpack_require__("./src/log.ts"); const button_html_1 = __webpack_require__("./src/ui/button.html"); const button_css_1 = __webpack_require__("./src/ui/button.css"); const setting_2 = __webpack_require__("./src/ui/setting.ts"); const GM_1 = __webpack_require__("./src/lib/GM.ts"); (0, createEl_1.createStyle)(button_css_1.default, "button-div-style"); exports.el = (0, createEl_1.createEl)("<div></div>"); exports.vm = Vue.createApp({ data() { return { imgStart: setting_1.iconStart0, imgSetting: setting_1.iconSetting, isSettingSeen: GM_1._GM_info.scriptHandler !== "Greasemonkey", imgJump: setting_1.iconJump, uiObj: (0, ui_1.getUI)(), }; }, methods: { startButtonClick() { if (window.downloading) { alert("正在下载中,请耐心等待……"); return; } const self = this; self.imgStart = setting_1.iconStart1; async function run() { const ruleClass = await (0, download_1.getRule)(); await ruleClass.run(); } run() .then(() => { self.imgStart = setting_1.iconStart0; }) .catch((error) => log_1.log.error(error)); }, settingButtonClick() { setting_2.vm.openSetting(); }, jumpButtonClick() { document.location = this.uiObj.jumpUrl; }, }, template: button_html_1.default, }).mount(exports.el); /***/ }), /***/ "./src/ui/dialog.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); const Vue = __webpack_require__("./node_modules/vue/index.js"); const dialog_html_1 = __webpack_require__("./src/ui/dialog.html"); const dialog_css_1 = __webpack_require__("./src/ui/dialog.css"); exports["default"] = Vue.defineCustomElement({ name: "Dialog", props: { dialogTitle: String, status: String, }, emits: ["dialogclose"], data() { return { myPrivateStatus: this.status === "true", }; }, methods: { dialogClose() { this.myPrivateStatus = false; this.$emit("dialogclose"); }, }, mounted() { this.myPrivateStatus = this.status === "true"; }, watch: { status() { this.myPrivateStatus = this.status === "true"; }, }, template: dialog_html_1.default, styles: [dialog_css_1.default], }); /***/ }), /***/ "./src/ui/progress.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.vm = exports.el = void 0; const Vue = __webpack_require__("./node_modules/vue/index.js"); const createEl_1 = __webpack_require__("./src/lib/createEl.ts"); const progress_css_1 = __webpack_require__("./src/ui/progress.css"); const progress_html_1 = __webpack_require__("./src/ui/progress.html"); (0, createEl_1.createStyle)(progress_css_1.default); exports.el = (0, createEl_1.createEl)(`<div id="progress-bar"></div>`); exports.vm = Vue.createApp({ data() { return { totalChapterNumber: 0, finishedChapterNumber: 0, zipPercent: 0, }; }, computed: { chapterPercent() { if (this.totalChapterNumber !== 0 && this.finishedChapterNumber !== 0) { return (this.finishedChapterNumber / this.totalChapterNumber) * 100; } else { return 0; } }, chapterProgressSeen() { return this.chapterPercent !== 0; }, zipProgressSeen() { return this.zipPercent !== 0; }, ntProgressSeen() { if (this.chapterProgressSeen || this.zipProgressSeen) { return true; } else { return false; } }, chapterProgressTitle() { return `章节:${this.finishedChapterNumber}/${this.totalChapterNumber}, ${this.chapterPercent}`; }, }, methods: { reset() { this.totalChapterNumber = 0; this.finishedChapterNumber = 0; this.zipPercent = 0; }, }, template: progress_html_1.default, }).mount(exports.el); /***/ }), /***/ "./src/ui/setting.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.vm = exports.el = void 0; const Vue = __webpack_require__("./node_modules/vue/index.js"); const createEl_1 = __webpack_require__("./src/lib/createEl.ts"); const misc_1 = __webpack_require__("./src/lib/misc.ts"); const log_1 = __webpack_require__("./src/log.ts"); const setting_html_1 = __webpack_require__("./src/ui/setting.html"); const setting_css_1 = __webpack_require__("./src/ui/setting.css"); const FilterTab_1 = __webpack_require__("./src/ui/FilterTab.ts"); const main_1 = __webpack_require__("./src/main.ts"); const setting_1 = __webpack_require__("./src/setting.ts"); (0, createEl_1.createStyle)(setting_css_1.default); exports.el = (0, createEl_1.createEl)(`<div id="setting"></div>`); exports.vm = Vue.createApp({ name: "nd-setting", components: { "filter-tab": FilterTab_1.default }, setup(props, context) { const setting = Vue.reactive({}); let settingBackup = {}; const saveOptions = [ { key: "null", value: "不使用自定义保存参数", options: {} }, { key: "chapter_name", value: "将章节名称格式修改为 第xx章 xxxx", options: { getchapterName: (chapter) => { if (chapter.chapterName) { return `第${chapter.chapterNumber.toString()}章 ${chapter.chapterName}`; } else { return `第${chapter.chapterNumber.toString()}章`; } }, }, }, { key: "txt_space", value: "txt文档每个自然段前加两个空格", options: { genChapterText: (chapterName, contentText) => { contentText = contentText .split("\n") .map((line) => { if (line.trim() === "") { return line; } else { return line.replace(/^/, " "); } }) .join("\n"); return `## ${chapterName}\n\n${contentText}\n\n`; }, }, }, { key: "reverse_chapters", value: "保存章节时倒序排列", options: { 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; }, }, }, ]; setting.enableDebug = setting_1.enableDebug.value; setting.chooseSaveOption = "null"; const curSaveOption = () => { const _s = saveOptions.find((s) => s.key === setting.chooseSaveOption); if (_s) { return _s.options; } else { return saveOptions[0].options; } }; const saveFilter = (filterSetting) => { setting.filterSetting = (0, misc_1.deepcopy)(filterSetting); }; const getFilterSetting = () => { if (setting.filterSetting) { return setting.filterSetting; } else { return; } }; Vue.provide("getFilterSetting", getFilterSetting); const setConfig = (config) => { setEnableDebug(); setCustomSaveOption(); setCustomFilter(); function setEnableDebug() { if (typeof config.enableDebug === "boolean") { config.enableDebug ? log_1.log.setLevel("trace") : log_1.log.setLevel("info"); setting_1.enableDebug.value = config.enableDebug; } } function setCustomSaveOption() { unsafeWindow.saveOptions = curSaveOption(); } function setCustomFilter() { if (config.filterSetting) { if (config.filterSetting.filterType === "null") { unsafeWindow.chapterFilter = undefined; } else { const filterFunction = (0, FilterTab_1.getFilterFunction)(config.filterSetting.arg, config.filterSetting.functionBody); if (filterFunction) { const chapterFilter = (chapter) => { if (chapter.status === main_1.Status.aborted) { return false; } return filterFunction(chapter); }; unsafeWindow.chapterFilter = chapterFilter; } } } } }; const openStatus = Vue.ref("false"); const currentTab = Vue.ref("tab-1"); const openSetting = () => { settingBackup = (0, misc_1.deepcopy)(setting); openStatus.value = "true"; }; const closeSetting = (keep) => { if (keep === true) { settingBackup = (0, misc_1.deepcopy)(setting); } else { Object.assign(setting, settingBackup); } openStatus.value = "false"; }; const closeAndSaveSetting = async () => { closeSetting(true); await (0, misc_1.sleep)(30); setConfig((0, misc_1.deepcopy)(setting)); log_1.log.info("[Init]自定义设置:" + JSON.stringify(setting)); }; return { openStatus, currentTab, openSetting, closeSetting, closeAndSaveSetting, saveFilter, setting, saveOptions, }; }, template: setting_html_1.default, }).mount(exports.el); /***/ }), /***/ "./src/ui/ui.ts": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.init = void 0; const dialog_1 = __webpack_require__("./src/ui/dialog.ts"); const button_1 = __webpack_require__("./src/ui/button.ts"); const progress_1 = __webpack_require__("./src/ui/progress.ts"); const setting_1 = __webpack_require__("./src/ui/setting.ts"); function register() { customElements.define("dialog-ui", dialog_1.default); } function init() { register(); document.body.appendChild(button_1.el); document.body.appendChild(progress_1.el); document.body.appendChild(setting_1.el); } exports.init = init; /***/ }), /***/ "./node_modules/vue/dist/vue.cjs.prod.js": /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); var compilerDom = __webpack_require__("./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js"); var runtimeDom = __webpack_require__("./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js"); var shared = __webpack_require__("./node_modules/@vue/shared/dist/shared.esm-bundler.js"); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { n[k] = e[k]; }); } n['default'] = e; return Object.freeze(n); } var runtimeDom__namespace = /*#__PURE__*/_interopNamespace(runtimeDom); // This entry is the "full-build" that includes both the runtime const compileCache = Object.create(null); function compileToFunction(template, options) { if (!shared.isString(template)) { if (template.nodeType) { template = template.innerHTML; } else { return shared.NOOP; } } const key = template; const cached = compileCache[key]; if (cached) { return cached; } if (template[0] === '#') { const el = document.querySelector(template); // __UNSAFE__ // Reason: potential execution of JS expressions in in-DOM template. // The user must make sure the in-DOM template is trusted. If it's rendered // by the server, the template should not contain any user data. template = el ? el.innerHTML : ``; } const { code } = compilerDom.compile(template, shared.extend({ hoistStatic: true, onError: undefined, onWarn: shared.NOOP }, options)); // The wildcard import results in a huge object with every export // with keys that cannot be mangled, and can be quite heavy size-wise. // In the global build we know `Vue` is available globally so we can avoid // the wildcard object. const render = (new Function('Vue', code)(runtimeDom__namespace)); render._rc = true; return (compileCache[key] = render); } runtimeDom.registerRuntimeCompiler(compileToFunction); Object.keys(runtimeDom).forEach(function (k) { if (k !== 'default') exports[k] = runtimeDom[k]; }); exports.compile = compileToFunction; /***/ }), /***/ "./node_modules/vue/index.js": /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; if (true) { module.exports = __webpack_require__("./node_modules/vue/dist/vue.cjs.prod.js") } else {} /***/ }), /***/ "crypto-js": /***/ ((module) => { "use strict"; module.exports = CryptoJS; /***/ }), /***/ "nunjucks": /***/ ((module) => { "use strict"; module.exports = nunjucks; /***/ }), /***/ "./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] = { /******/ id: moduleId, /******/ // 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/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* 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/global */ /******/ (() => { /******/ __webpack_require__.g = (function() { /******/ if (typeof globalThis === 'object') return globalThis; /******/ try { /******/ return this || new Function('return this')(); /******/ } catch (e) { /******/ if (typeof window === 'object') return window; /******/ } /******/ })(); /******/ })(); /******/ /******/ /* 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 setting_1 = __webpack_require__("./src/setting.ts"); const global_1 = __webpack_require__("./src/global.ts"); const ui_1 = __webpack_require__("./src/ui/ui.ts"); const detect_1 = __webpack_require__("./src/detect.ts"); const debug_1 = __webpack_require__("./src/debug.ts"); const log_1 = __webpack_require__("./src/log.ts"); function printEnvironments() { log_1.log.info("[Init]开始载入小说下载器……"); Object.entries(detect_1.environments).forEach((kv) => log_1.log.info("[Init]" + kv.join(":"))); } function main() { printEnvironments(); (0, global_1.init)(); (0, ui_1.init)(); if (setting_1.enableDebug.value) { setTimeout(debug_1.debug, 3000); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", (event) => { main(); }); } else { main(); } })(); /******/ })() ;
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址