(function(){ const ID_SCRAPERLET="scraperlet",URL_BASE="https://www.novelupdates.com",URL_GROUPLIST="https://www.novelupdates.com/groupslist/",URL_GROUPDETAILS_TEMPL="https://www.novelupdates.com/group/{name}/",URL_SERIESLIST="https://www.novelupdates.com/series-ranking/?rank=popular",URL_SERIES_TEMPL="https://www.novelupdates.com/series/{name}/",URL_USER_TEMPL="https://www.novelupdates.com/user/{idname}/",URL_GENRELIST="https://www.novelupdates.com/genre-explanation/",URL_TAGLIST="https://www.novelupdates.com/list-tags/",URL_RECOMMENDATIONLIST_TEMPL="https://www.novelupdates.com/viewlist/{id}/",KEY_STORE_SERIESIDS="scrapeSeriesDetails-seriesIds",KEY_STORE_SERIESIDS_SOURCE="scrapeSeriesDetails-seriesIds-source",KEY_STORE_STATS="STATS",KEY_STORE_STATS_HISTORY="STATS_HISTORY",STATS=new Proxy({numRequests:0,numBytesResponseText:0,numGroups:null,numGroupInfos:null,numGroupInfosTotal:null,numSeries:null,numSeriesForCrawl:null,numSeriesInfos:null,numSeriesInfosTotal:null,numChapters:null,numSeriesForChapters:null,numSeriesForChaptersTotal:null,numChapterLinksResolved:null,numReviews:null,numSeriesForReviews:null,numSeriesForReviewsTotal:null,numGenres:null,numTags:null},{set(e,t,r){return e[t]=r,updateStats(t),localforage.setItem(KEY_STORE_STATS,e),!0}}),CONFIGS={requestDelay:2e3,stop:!1,blockLeavePage:!0};async function bytesToBase64DataUrl(a,s="application/octet-stream"){return new Promise((e,t)=>{const r=Object.assign(new FileReader,{onload:()=>e(r.result),onerror:()=>t(r.error)});r.readAsDataURL(new File([a],"",{type:s}))})}function textToBytes(e){return(new TextEncoder).encode(e)}async function saveData(e,t){var r,e=await bytesToBase64DataUrl(textToBytes(JSON.stringify(e)),"application/json");void 0!==t?((r=document.createElement("a")).download=t,r.href=e,r.addEventListener("click",function(e){e.stopPropagation(),this.removeEventListener("click",arguments.callee)}),r.click()):window.open(e)}function sleep(t){return new Promise(e=>setTimeout(e,t))}function rtrim(e,t){if(!e)return e;for(var r=e.length-1;0<=t.indexOf(e[r]);)--r;return e.substr(0,r+1)}function ltrim(e,t){if(!e)return e;for(var r=0;0<=t.indexOf(e[r]);)r+=1;return e.substr(r)}function trim(e,t){return e&<rim(rtrim(e,t),t)}function humanFileSize(e,t=!1,r=1){var a=t?1e3:1024;if(Math.abs(e)=a&&n{t[e.getAttribute("href").split("/").filter(Boolean).pop()]=e.textContent}),t}function parseSerieslist(e){var r={};return(void 0!==e?e:document).querySelectorAll("div.w-blog-content .search_main_box_nu").forEach(e=>{var t,e={name:e.querySelector(".search_body_nu .search_title a").href.split("/").filter(Boolean).pop(),title:e.querySelector(".search_body_nu .search_title a").textContent,langCode:e.querySelector(".search_img_nu .search_ratings span")?.textContent.toLowerCase()||null,rating:Number.parseFloat(trim(e.querySelector(".search_img_nu .search_ratings").textContent.split(" ")[1],"()")),isCompleted:!!e.querySelector(".search_body_nu .search_genre a.gennew.complete"),genres:Array.from(e.querySelectorAll(".search_body_nu .search_genre a.gennew.search")).filter(e=>e.href.includes("novelupdates.com/genre/")).map(e=>e.href.split("/").filter(Boolean).pop()),numChapters:Number.parseInt(e.querySelector(".search_main_box_nu .search_body_nu .search_stats span:nth-child(1)").textContent.split(" ").filter(Boolean).shift()),updateFrequency:Number.parseFloat(e.querySelector(".search_main_box_nu .search_body_nu .search_stats span:nth-child(2)").textContent.split(" ").filter(Boolean)[1]),numReaders:Number.parseInt(e.querySelector(".search_main_box_nu .search_body_nu .search_stats span:nth-child(3)").textContent.split(" ").filter(Boolean).shift()),numReviews:Number.parseInt(e.querySelector(".search_main_box_nu .search_body_nu .search_stats span:nth-child(4)").textContent.split(" ").filter(Boolean).shift()),lastUpdated:"N/A"===(t=e.querySelector(".search_main_box_nu .search_body_nu .search_stats span:nth-child(5)").textContent.trim())?null:t,summary:(Array.from(e.querySelector(".search_main_box_nu .search_body_nu").childNodes).filter(e=>3===e.nodeType).map(e=>e.textContent).join(" ")+Array.from(e.querySelector(".search_main_box_nu .search_body_nu span.testhide")?.childNodes||[]).filter(e=>3===e.nodeType).map(e=>e.textContent).join(" ")).trim(),imgUrl:"https://cdn.novelupdates.com/imgmid/noimagemid.jpg"===(t=e.querySelector(".search_main_box_nu .search_img_nu img")?.src)?null:t};r[e.name]=e}),r}function parseGroupSeriesUrls(e){var t="div.w-blog-content.group table.groupinfo tr:nth-child(4) td:nth-child(2)",r=[];return(void 0!==e?e:document).querySelectorAll(t+" a").forEach(e=>{e.classList.contains("chosen-single")||r.push(e.getAttribute("href").split("/").filter(Boolean).pop())}),(void 0!==e?e:document).querySelectorAll(t+" select option").forEach(e=>{"---"!==e.value&&r.push(e.value.split("/").filter(Boolean).pop())}),r}function parseGroupDetails(t){t=void 0!==t?t:document;const r="div.w-blog-content.group table.groupinfo";function e(e){return t.querySelector(r+e).textContent}return{name:e(" tr:nth-child(1) td:nth-child(2)"),homepage:t.querySelector(r+" tr:nth-child(2) td:nth-child(2) a")?.href||null,numFollowers:Number.parseInt(e(" tr:nth-child(3) td:nth-child(2)")),numReleases:Number.parseInt(e(" tr:nth-child(5) td:nth-child(2)")),series:parseGroupSeriesUrls(t)}}function parseSeriesDetailsCommunity(r){function e(e){var t=r.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}function t(e){var t=r.createElement("div");return t.innerHTML=e,t}r=void 0!==r?r:document;var a=Array.from(r.querySelectorAll(".two-thirds .wpb_wrapper h5.seriesother")).slice(1),s=r.createRange(),n=(s.setStart(a[0].nextSibling,0),s.setEnd(a[1].previousSibling,0),e(s.cloneContents()).split("
").map(e=>e.trim()).filter(Boolean).filter(e=>"n/a"!==e.toLowerCase()).map(t).map(e=>({name:e.querySelector("a")?.href.split("/").filter(Boolean).pop(),details:trim(e.querySelector("a")?.nextSibling.textContent.trim(),"()")||null}))),a=(s.setStart(a[1].nextSibling,0),s.setEnd(a[2].previousSibling,0),e(s.cloneContents()).split("
").map(e=>e.trim()).filter(Boolean).filter(e=>"n/a"!==e.toLowerCase()).filter(e=>!e.startsWith("Be the first to make a")).map(t).map(e=>({name:e.querySelector("a")?.href.split("/").filter(Boolean).pop(),numUsers:Number.parseInt(trim(e.querySelector("a")?.nextSibling.textContent.trim(),"()"))||0})));return{relatedSeries:n,recommendations:a,recommendationListsFirst:Array.from(r.querySelectorAll(".two-thirds .wpb_text_column .wpb_wrapper ol.ulc_sp li a")).map(e=>e.href.split("/").filter(Boolean).pop()),discussionUrl:r.querySelector(".two-thirds .wpb_text_column .wpb_wrapper .seriesother .nuf_link a")?.href||null}}function parseSeriesRatings(e){var t=trim((e=void 0!==e?e:document).querySelector(".one-third .wpb_text_column .wpb_wrapper h5 > .uvotes")?.textContent.trim(),"()")?.match(/\(?(?\d\.\d) \/ 5\.0, (?\d+) votes\)?/)?.groups||{},r=Object.fromEntries(Array.from(e.querySelectorAll(".one-third .wpb_text_column .wpb_wrapper table#myrates span.votetext")).map(e=>trim(e.textContent.trim(),"()")).map(e=>Number.parseInt(e.match(/\(?(?\d+) votes\)?/)?.groups.votes)||0).reverse().map((e,t)=>[t+1,e]));return{rating:Number.parseFloat(t?.rating)||null,votes:Number.parseInt(t?.votes)||null,votesPerStar:r,numReviews:Number.parseInt(e.querySelector("#comments > div.review-count")?.textContent.split(" ").shift())||null}}function parseSeriesDetails(t){function e(e){return t.querySelector(e)?.href.split("/").filter(Boolean).pop()||null}function r(e){return Array.from(t.querySelectorAll(e)).map(e=>e.href.split("/").filter(Boolean).pop())}function a(e){return"yes"===(e=e.trim().toLowerCase())||"no"!==e&&null}var s={title:(t=void 0!==t?t:document).querySelector(".w-blog-content .seriestitlenu").textContent,language:e(".one-third .wpb_text_column .wpb_wrapper #showlang a.genre.lang"),novelType:e(".one-third .wpb_text_column .wpb_wrapper #showtype a.genre.type"),authors:r(".one-third .wpb_text_column .wpb_wrapper #showauthors a"),artists:r(".one-third .wpb_text_column .wpb_wrapper #showartists a"),genres:r(".one-third .wpb_text_column .wpb_wrapper #seriesgenre a.genre"),tags:r(".one-third .wpb_text_column .wpb_wrapper #showtags a.genre"),imageUrl:"https://www.novelupdates.com/img/noimagefound.jpg"===(s=t.querySelector(".seriesimg img")?.src)?null:s,year:Number.parseInt(t.querySelector(".one-third .wpb_text_column .wpb_wrapper #edityear")?.textContent.trim())||null,status:Array.from(t.querySelectorAll(".one-third .wpb_text_column .wpb_wrapper #editstatus")).map(e=>e.textContent.trim()),licensed:a(t.querySelector(".one-third .wpb_text_column .wpb_wrapper #showlicensed")?.textContent),translated:a(t.querySelector(".one-third .wpb_text_column .wpb_wrapper #showtranslated")?.textContent),publisherOriginal:r(".one-third .wpb_text_column .wpb_wrapper #showopublisher a"),publisherEnglish:r(".one-third .wpb_text_column .wpb_wrapper #showepublisher a"),associatedNames:Array.from(t.querySelectorAll("#editassociated")).map(e=>e.textContent.trim()).filter(e=>"n/a"!==e.toLowerCase()),description:Array.from(t.querySelectorAll("#editdescription p")).map(e=>e.textContent.trim()).filter(e=>"n/a"!==e.toLowerCase()).join("\n")||null};return Object.assign(s,parseSeriesDetailsCommunity(t)),Object.assign(s,{ratings:parseSeriesRatings(t)}),s}function parseSeriesChapterList(e){return Array.from((void 0!==e?e:document).querySelectorAll(".w-blog-content .two-thirds .wpb_text_column .wpb_wrapper table tr")).slice(1).map(e=>{return{date:(t=(t=e.querySelector("td:nth-child(1)").textContent.trim()).split("/"),new Date(2e3+Number.parseInt(t[2],10),Number.parseInt(t[0],10)-1,Number.parseInt(t[1],10))),group:e.querySelector("td:nth-child(2) a")?.href.split("/").filter(Boolean).pop()||null,title:(e.querySelector("td:nth-child(3) span")||e.querySelector("td:nth-child(3) a"))?.textContent.trim(),url:(t=e.querySelector("td:nth-child(3) a")?.href)&&t.split("/").filter(Boolean).pop()||null};var t})}function parseSeriesReviews(e){return e=void 0!==e?e:document,Array.from(e.querySelectorAll("#comments > div.w-comments-list > div.w-comments-item")).map(e=>{var t,r,a=Number.parseInt(e.id.slice(8));return{id:a,num_liked:Number.parseInt(e.nextElementSibling.querySelector(".liked_"+a)?.textContent||0),reviewer_name:e.querySelector("a#revname.revname"+a)?.textContent.trim()||null,reviewer_id:e.querySelector("a#revname.revname"+a)?.href.split("/").filter(Boolean).slice(-2).join("/")||null,num_stars:e.querySelectorAll(".w-comments-item-meta-new i.fa.fa-star").length,date:(t=e.querySelector(".w-comments-item-meta-new > table > tbody > tr > td:nth-child(2) > div:nth-child(1)")?.textContent)?(t=Date.parse(t),r=-(new Date).getTimezoneOffset()/60*1e3*3600,new Date(t+r).toISOString()):null,reading_status:(!(t=e.querySelector("#stat"+a)?.textContent.trim())||"-"===t?null:"Completed"===t||t)||null,content_html:(r=e.querySelector(".w-comments-item-text"))?(a=r.querySelector('span[style="display:none"]'))?(r.querySelector("span.dots").remove(),Array.from(r.querySelectorAll("span.morelink")).forEach(e=>e.remove()),a.remove(),r?.innerHTML.trim()+a.innerHTML.trimRight()):r?.innerHTML.trim():null}})}function parseGenrelist(e){let t={};return(void 0!==e?e:document).querySelectorAll(".w-blog-content table tr").forEach(e=>{e.querySelector("b.genreexplain")&&(t[e.querySelector("b.genreexplain a").href.split("/").filter(Boolean).pop()]={title:e.querySelector("b.genreexplain a").textContent.trim(),description:e.querySelector("td:nth-child(2)").textContent.trim()})}),t}function parseTaglist(e){let r={};return(void 0!==e?e:document).querySelectorAll(".w-blog-content .staglistall .one-half ul > li").forEach(e=>{var t,e=e.querySelector("a");r[e.href.split("/").filter(Boolean).pop()]={title:e.textContent.trim(),description:!(t=e?.title.trim())||"N/A"===t||"No definition found."===t||t.startsWith("Locked. Propose a definition here:")?null:t,count:Number.parseInt(trim(e.nextSibling.textContent," ()"))||null}}),r}async function scrapeGrouplist(){var e="scrapeGrouplist-finished",t="scrapeGrouplist-curUrl",r="scrapeGrouplist-groupMap",a=await localforage.getItem(r)||{};let s=await localforage.getItem(t)||URL_GROUPLIST;for(await localforage.removeItem(e);null!==s;){await localforage.setItem(t,s);await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay));var n=await navigate(s),o=parseGrouplist(n),n=parseNextPageUrlRelative(n,URL_GROUPLIST);Object.assign(a,o),await localforage.setItem(r,a),STATS.numGroups=Object.keys(a).length,s=n}return await localforage.setItem(e,new Date),a}async function scrapeGroupDetails(e){var t,r="scrapeGroupDetails-finished",a="scrapeGroupDetails-groupInfoMap",s=await localforage.getItem(a)||{};console.debug("Processing group details of",e),STATS.numGroupInfosTotal=e.length,STATS.numGroupInfos=Object.keys(s).length,await localforage.removeItem(r);for(const n of e)n in s?console.debug(`Found group details for key '${n}'. Skipping ...`):(STATS.numGroupInfos++,await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay)),t=parseGroupDetails(await navigate(URL_GROUPDETAILS_TEMPL.replace("{name}",n))),Object.assign(s,{[n]:t}),await localforage.setItem(a,s));return await localforage.setItem(r,new Date),s}async function scrapeSerieslist(){var e="scrapeSerieslist-finished",t="scrapeSerieslist-curUrl",r="scrapeSerieslist-seriesMap",a=await localforage.getItem(r)||{};let s=await localforage.getItem(t)||URL_SERIESLIST,n=[];for(await localforage.removeItem(e);null!==s;){await localforage.setItem(t,s);await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay));var o=await navigate(s),i=parseSerieslist(o),l=parseNextPageUrlAbsolute(o),l=(Object.assign(a,i),await localforage.setItem(r,a),STATS.numSeries=Object.keys(a).length,s=l,Object.keys(i).filter(e=>!n.includes(e)));n=l.length!==Object.keys(i).length?(console.log("Found rank change in series list. New Series:",l,"Known ones:",Object.keys(i).filter(e=>n.includes(e))),(l=parsePrevPageUrlAbsolute(o))&&(s=l),[]):Object.keys(i)}return await localforage.setItem(e,new Date),a}async function scrapeSeriesDetails(e){var t,r="scrapeSeriesDetails-finished",a="scrapeSeriesDetails-seriesInfoMap",s=await localforage.getItem(a)||{};console.debug("Processing series details of",e),STATS.numSeriesInfosTotal=e.length,await localforage.removeItem(r);for(const n of e)n in s?console.debug(`Found series details for key '${n}'. Skipping ...`):(await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay)),t=parseSeriesDetails(await navigate(URL_SERIES_TEMPL.replace("{name}",n))),Object.assign(s,{[n]:t}),STATS.numSeriesInfos=Object.keys(s).length,await localforage.setItem(a,s));return await localforage.setItem(r,new Date),s}async function scrapeSeriesChapterList(e){var t=URL_SERIES_TEMPL.replace("{name}",e),r="scrapeSeriesChapterList-seriesId",a="scrapeSeriesChapterList-curUrl",s="scrapeSeriesChapterList-chapterList",n=await localforage.getItem(r);null!==n&&n!==e&&(console.debug(`Found possibly stale data in STORE for seriesId: '${e}'`,n,await localforage.getItem(a),await localforage.getItem(s)),await localforage.removeItem(s),await localforage.removeItem(a)),await localforage.setItem(r,e);let o=await localforage.getItem(s)||[],i=await localforage.getItem(a)||t;for(;null!==i;){await localforage.setItem(a,i);await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay));var l=await navigate(i),c=parseSeriesChapterList(l),l=parseNextPageUrlRelative(l,t);o=o.concat(c),await localforage.setItem(s,o),i=l}return o}async function scrapeAllSeriesChapterList(e){var t,r="scrapeAllSeriesChapterList-finished",a="scrapeAllSeriesChapterList-seriesChapterListMap",s=await localforage.getItem(a)||{};console.debug("Processing series chapter lists of",e),STATS.numSeriesForChaptersTotal=e.length,STATS.numSeriesForChapters=Object.keys(s).length,await localforage.removeItem(r);for(const n of e)n in s?console.debug(`Found series chapter list for key '${n}'. Skipping ...`):(STATS.numSeriesForChapters++,t=await scrapeSeriesChapterList(n),Object.assign(s,{[n]:t}),STATS.numChapters=Object.values(s).map(e=>e.length).reduce((e,t)=>e+t,0),await localforage.setItem(a,s));return await localforage.setItem(r,new Date),s}async function scrapeSeriesReviews(e){var t=URL_SERIES_TEMPL.replace("{name}",e),r="scrapeSeriesReviews-seriesId",a="scrapeSeriesReviews-curUrl",s="scrapeSeriesReviews-reviewsList",n=await localforage.getItem(r);null!==n&&n!==e&&(console.debug(`Found possibly stale data in STORE for seriesId: '${e}'`,n,await localforage.getItem(a),await localforage.getItem(s)),await localforage.removeItem(s),await localforage.removeItem(a)),await localforage.setItem(r,e);let o=await localforage.getItem(s)||[],i=await localforage.getItem(a)||t;for(;null!==i;){await localforage.setItem(a,i);await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay));var l=await navigate(i),c=parseSeriesReviews(l),l=parseNextPageUrlAbsolute(l,"#comments .mb_review_pagination .w-comments-pagination a.next.page-numbers");o=o.concat(c),await localforage.setItem(s,o),i=l}return o}async function scrapeAllSeriesReviews(e){var t,r="scrapeAllSeriesReviews-finished",a="scrapeAllSeriesReviews-seriesReviewsMap",s=await localforage.getItem(a)||{};console.debug("Processing series reviews of",e),STATS.numSeriesForReviewsTotal=e.length,STATS.numSeriesForReviews=Object.keys(s).length,await localforage.removeItem(r);for(const n of e)n in s?console.debug(`Found series reviews for key '${n}'. Skipping ...`):(STATS.numSeriesForReviews++,t=await scrapeSeriesReviews(n),Object.assign(s,{[n]:t}),STATS.numReviews=Object.values(s).map(e=>e.length).reduce((e,t)=>e+t,0),await localforage.setItem(a,s));return await localforage.setItem(r,new Date),s}async function scrapeGenres(){var e=parseGenrelist(await navigate(URL_GENRELIST));return await localforage.setItem("scrapeGenres-genresMap",e),STATS.numGenres=Object.keys(e).length,await localforage.setItem("scrapeGenres-finished",new Date),e}async function scrapeTags(){var e="scrapeTags-finished",t="scrapeTags-curUrl",r="scrapeTags-tagsMap",a=await localforage.getItem(r)||{};let s=await localforage.getItem(t)||URL_TAGLIST;for(await localforage.removeItem(e);null!==s;){await localforage.setItem(t,s);await sleep(Math.floor(CONFIGS.requestDelay/2+Math.random()*CONFIGS.requestDelay));var n=await navigate(s),o=parseTaglist(n),n=parseNextPageUrlAbsolute(n);Object.assign(a,o),await localforage.setItem(r,a),STATS.numTags=Object.keys(a).length,s=n}return await localforage.setItem(e,new Date),a}function filterMultiAuthorSeriesByGroupDetails(e){return Object.fromEntries(Object.entries(Object.entries(e).map(([e,t])=>[e,t.series]).reduce((t,[r,e])=>((e||[]).forEach(e=>(t[e]||(t[e]=[])).push(r)),t),{})).filter(([,e])=>2<=e.length))}async function runGrouplistScraper(){var t=document.getElementById("runGrouplistScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runGrouplistScraper] already running?!");else{setTaskStatusWorking(t);try{await saveData(await scrapeGrouplist(),"groups.json"),setTaskStatusSuccess(t),setHasData(t),document.getElementById(ID_SCRAPERLET).classList.add("has-groups")}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runGroupDetailsScraper(){var t=document.getElementById("runGroupDetailsScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runGroupDetailsScraper] already running?!");else{setTaskStatusWorking(t);var e=await localforage.getItem("scrapeGrouplist-groupMap");if(null===e)console.warn("[runGroupDetailsScraper] No 'groupMap' found in STORE! Try to first scrape the Group List!"),setTaskStatusError(t,"Error: No 'groupMap' found in STORE! Try to first scrape the Group List!");else try{var r=await scrapeGroupDetails(Object.keys(e).sort());await saveData(r,"groupDetails.json"),await localforage.setItem(KEY_STORE_SERIESIDS,Object.values(r).map(e=>e.series).flat(1/0)),await localforage.setItem(KEY_STORE_SERIESIDS_SOURCE,"runGroupDetailsScraper"),STATS.numSeriesForCrawl=(await localforage.getItem(KEY_STORE_SERIESIDS)||[]).length,document.getElementById(ID_SCRAPERLET).classList.add("has-groups-details"),document.getElementById(ID_SCRAPERLET).classList.add("has-series"),setTaskStatusSuccess(t),setHasData(t)}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runFindMASeries(){var e,t=document.getElementById("runFindMASeries");null===t||t.hasAttribute("disabled")?console.warn("[runFindMASeries] already running?!"):(setTaskStatusWorking(t),null===(e=await localforage.getItem("scrapeGroupDetails-groupInfoMap"))?(console.warn("[runFindMASeries] No 'groupInfoMap' found in STORE! Try to first scrape the Group List, and then Group Details!"),setTaskStatusError(t,"Error: No 'groupInfoMap' found in STORE! Try to first scrape the Group List, and then Group Details!")):(await saveData(e=filterMultiAuthorSeriesByGroupDetails(e),"multi_groups_series.json"),await localforage.setItem(KEY_STORE_SERIESIDS,Object.keys(e)),await localforage.setItem(KEY_STORE_SERIESIDS_SOURCE,"runFindMASeries"),STATS.numSeriesForCrawl=Object.keys(e).length,document.getElementById(ID_SCRAPERLET).classList.add("has-series")),setTaskStatusSuccess(t),setHasData(t))}async function runSerieslistScraper(){var t=document.getElementById("runSerieslistScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runSerieslistScraper] already running?!");else{setTaskStatusWorking(t);try{var e=await scrapeSerieslist();await saveData(e,"series.json"),await localforage.setItem(KEY_STORE_SERIESIDS,Object.keys(e)),await localforage.setItem(KEY_STORE_SERIESIDS_SOURCE,"runSerieslistScraper"),STATS.numSeriesForCrawl=Object.keys(e).length,setTaskStatusSuccess(t),setHasData(t),document.getElementById(ID_SCRAPERLET).classList.add("has-series")}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runSeriesDetailsScraper(){var t=document.getElementById("runSeriesDetailsScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runSeriesDetailsScraper] already running?!");else{setTaskStatusWorking(t);var e=await localforage.getItem(KEY_STORE_SERIESIDS);if(null===e)console.warn("[runSeriesDetailsScraper] No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!"),setTaskStatusError(t,"Error: No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!");else try{e.sort(),await saveData(await scrapeSeriesDetails(e),"seriesDetails.json"),setTaskStatusSuccess(t),setHasData(t)}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runChapterLinksScraper(){var t=document.getElementById("runChapterLinksScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runChapterLinksScraper] already running?!");else{setTaskStatusWorking(t);var e=await localforage.getItem(KEY_STORE_SERIESIDS);if(null===e)console.warn("[runChapterLinksScraper] No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!"),setTaskStatusError(t,"Error: No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!");else try{e.sort(),await saveData(await scrapeAllSeriesChapterList(e),"chapters.json"),setTaskStatusSuccess(t),setHasData(t),document.getElementById(ID_SCRAPERLET).classList.add("has-chapter-links")}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runChapterLinkResolver(){var e=await localforage.getItem("scrapeAllSeriesChapterList-seriesChapterListMap")||{};throw await saveData(Object.values(e).flat().map(e=>e?.url.split("/").filter(Boolean).pop()).filter(Boolean),"extnu.json"),new Error("Not possible currently.")}async function runSeriesReviewsScraper(){var t=document.getElementById("runSeriesReviewsScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runSeriesReviewsScraper] already running?!");else{setTaskStatusWorking(t);var e=await localforage.getItem(KEY_STORE_SERIESIDS);if(null===e)console.warn("[runSeriesReviewsScraper] No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!"),setTaskStatusError(t,"Error: No 'seriesIds' found in STORE! Try to first scrape the [Group List, then Group Infos or Find Multi Author Series] / [Series List]!");else try{e.sort(),await saveData(await scrapeAllSeriesReviews(e),"reviews.json"),setTaskStatusSuccess(t),setHasData(t)}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runGenrelistScraper(){var t=document.getElementById("runGenrelistScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runGenrelistScraper] already running?!");else{setTaskStatusWorking(t);try{await saveData(await scrapeGenres(),"genres.json"),setTaskStatusSuccess(t),setHasData(t)}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function runTaglistScraper(){var t=document.getElementById("runTaglistScraper");if(null===t||t.hasAttribute("disabled"))console.warn("[runTaglistScraper] already running?!");else{setTaskStatusWorking(t);try{await saveData(await scrapeTags(),"tags.json"),setTaskStatusSuccess(t),setHasData(t)}catch(e){console.error(e),setTaskStatusError(t,e)}}}async function doDownload(e){document.getElementById("runGrouplistScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeGrouplist-groupMap"),"groups.json"):document.getElementById("runGroupDetailsScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeGroupDetails-groupInfoMap"),"groupDetails.json"):document.getElementById("runFindMASeries").contains(e.target)?await saveData(filterMultiAuthorSeriesByGroupDetails(await localforage.getItem("scrapeGroupDetails-groupInfoMap")),"multi_groups_series.json"):document.getElementById("runSerieslistScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeSerieslist-seriesMap"),"series.json"):document.getElementById("runSeriesDetailsScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeSeriesDetails-seriesInfoMap"),"seriesDetails.json"):document.getElementById("runChapterLinksScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeAllSeriesChapterList-seriesChapterListMap"),"chapters.json"):document.getElementById("runChapterLinkResolver").contains(e.target)||(document.getElementById("runSeriesReviewsScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeAllSeriesReviews-seriesReviewsMap"),"reviews.json"):document.getElementById("runGenrelistScraper").contains(e.target)?await saveData(await localforage.getItem("scrapeGenres-genresMap"),"genres.json"):document.getElementById("runTaglistScraper").contains(e.target)&&await saveData(await localforage.getItem("scrapeTags-tagsMap"),"tags.json"))}async function doDataDelete(e){document.getElementById("runGrouplistScraper").contains(e.target)?(await localforage.removeItem("scrapeGrouplist-finished"),await localforage.removeItem("scrapeGrouplist-curUrl"),await localforage.removeItem("scrapeGrouplist-groupMap"),document.getElementById("runGrouplistScraper").classList.remove("has-data")):document.getElementById("runGroupDetailsScraper").contains(e.target)?(await localforage.removeItem("scrapeGroupDetails-finished"),await localforage.removeItem("scrapeGroupDetails-groupInfoMap"),document.getElementById("runGroupDetailsScraper").classList.remove("has-data")):document.getElementById("runFindMASeries").contains(e.target)||(document.getElementById("runSerieslistScraper").contains(e.target)?(await localforage.removeItem("scrapeSerieslist-finished"),await localforage.removeItem("scrapeSerieslist-curUrl"),await localforage.removeItem("scrapeSerieslist-seriesMap"),document.getElementById("runSerieslistScraper").classList.remove("has-data")):document.getElementById("runSeriesDetailsScraper").contains(e.target)?(await localforage.removeItem("scrapeSeriesDetails-finished"),await localforage.removeItem("scrapeSeriesDetails-seriesInfoMap"),document.getElementById("runSeriesDetailsScraper").classList.remove("has-data")):document.getElementById("runChapterLinksScraper").contains(e.target)?(await localforage.removeItem("scrapeAllSeriesChapterList-finished"),await localforage.removeItem("scrapeAllSeriesChapterList-seriesChapterListMap"),await localforage.removeItem("scrapeSeriesChapterList-seriesId"),await localforage.removeItem("scrapeSeriesChapterList-curUrl"),await localforage.removeItem("scrapeSeriesChapterList-chapterList"),document.getElementById("runChapterLinksScraper").classList.remove("has-data")):document.getElementById("runChapterLinkResolver").contains(e.target)||(document.getElementById("runSeriesReviewsScraper").contains(e.target)?(await localforage.removeItem("scrapeAllSeriesReviews-finished"),await localforage.removeItem("scrapeAllSeriesReviews-seriesReviewsMap"),await localforage.removeItem("scrapeSeriesReviews-seriesId"),await localforage.removeItem("scrapeSeriesReviews-curUrl"),await localforage.removeItem("scrapeSeriesReviews-reviewsList"),document.getElementById("runSeriesReviewsScraper").classList.remove("has-data")):document.getElementById("runGenrelistScraper").contains(e.target)?(await localforage.removeItem("scrapeGenres-finished"),await localforage.removeItem("scrapeGenres-genresMap"),document.getElementById("runGenrelistScraper").classList.remove("has-data")):document.getElementById("runTaglistScraper").contains(e.target)&&(await localforage.removeItem("scrapeTags-finished"),await localforage.removeItem("scrapeTags-curUrl"),await localforage.removeItem("scrapeTags-tagsMap"),document.getElementById("runTaglistScraper").classList.remove("has-data"))))}function updateStopFlag(){CONFIGS.stop=document.querySelector(`#${ID_SCRAPERLET} input[type="checkbox"][name="stop"]`).checked}function updateRequestDelay(){CONFIGS.requestDelay=Number.parseInt(document.querySelector(`#${ID_SCRAPERLET} input[type="text"][name="delay"]`).value)}function updateBlockClicksFlag(){CONFIGS.blockLeavePage=document.querySelector(`#${ID_SCRAPERLET} input[type="checkbox"][name="clicks"]`).checked,CONFIGS.blockLeavePage?(document.body.style.pointerEvents="none",window.disablePageClicksHandler=disablePageClicksHandler,document.body.addEventListener("click",disablePageClicksHandler,!0)):(document.body.style.removeProperty("pointer-events"),document.body.removeEventListener("click",disablePageClicksHandler),delete window.disablePageClicksHandler)}function disablePageClicksHandler(e){return!CONFIGS.blockLeavePage||document.getElementById(ID_SCRAPERLET).contains(e.target)?void 0:(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),!1)}function updateStats(e){void 0!==e&&"numRequests"!==e||(document.querySelector(`#${ID_SCRAPERLET} .stats-requests`).innerHTML=`${STATS.numRequests.toLocaleString()}`),void 0!==e&&"numBytesResponseText"!==e||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-response-bytes`),{innerHTML:`${humanFileSize(STATS.numBytesResponseText)}`,title:STATS.numBytesResponseText+" bytes received (content only)"}),void 0!==e&&"numGroups"!==e||null===STATS.numGroups||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-groups`),{innerHTML:`${STATS.numGroups.toLocaleString()}`,hidden:null===STATS.numGroups}),void 0!==e&&"numGroupInfos"!==e&&"numGroupInfosTotal"!==e||null===STATS.numGroupInfos||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-groups-infos`),{innerHTML:`${STATS.numGroupInfos.toLocaleString()} / ${(STATS.numGroupInfosTotal||STATS.numGroupInfos).toLocaleString()}`,hidden:null===STATS.numGroupInfos}),void 0!==e&&"numSeries"!==e||null===STATS.numSeries||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-series`),{innerHTML:`${STATS.numSeries.toLocaleString()}`,hidden:null===STATS.numSeries}),void 0!==e&&"numSeriesForCrawl"!==e||null===STATS.numSeriesForCrawl||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-series-ids`),{innerHTML:`${STATS.numSeriesForCrawl.toLocaleString()}`,hidden:null===STATS.numSeriesForCrawl}),void 0!==e&&"numSeriesInfos"!==e&&"numSeriesInfosTotal"!==e||null===STATS.numSeriesInfos||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-series-infos`),{innerHTML:`${STATS.numSeriesInfos.toLocaleString()} / ${(STATS.numSeriesInfosTotal||STATS.numSeriesInfos).toLocaleString()}`,hidden:null===STATS.numSeriesInfos}),void 0!==e&&"numChapters"!==e||null===STATS.numChapters||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-chapters`),{innerHTML:`${STATS.numChapters.toLocaleString()}`,hidden:null===STATS.numChapters}),void 0!==e&&"numSeriesForChapters"!==e&&"numSeriesForChaptersTotal"!==e||null===STATS.numSeriesForChapters||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-chapters-series-progress`),{innerHTML:`${STATS.numSeriesForChapters.toLocaleString()} / ${(STATS.numSeriesForChaptersTotal||STATS.numSeriesForChapters).toLocaleString()}`,hidden:null===STATS.numSeriesForChapters}),void 0!==e&&"numChapterLinksResolved"!==e&&"numChapters"!==e||null===STATS.numChapterLinksResolved||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-chapter-links`),{innerHTML:`${STATS.numChapterLinksResolved.toLocaleString()} / ${(STATS.numChapters||STATS.numChapterLinksResolved).toLocaleString()}`,hidden:null===STATS.numChapterLinksResolved}),void 0!==e&&"numReviews"!==e||null===STATS.numReviews||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-reviews`),{innerHTML:`${STATS.numReviews.toLocaleString()}`,hidden:null===STATS.numReviews}),void 0!==e&&"numSeriesForReviews"!==e&&"numSeriesForReviewsTotal"!==e||null===STATS.numSeriesForReviews||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-reviews-series-progress`),{innerHTML:`${STATS.numSeriesForReviews.toLocaleString()} / ${(STATS.numSeriesForReviewsTotal||STATS.numSeriesForReviews).toLocaleString()}`,hidden:null===STATS.numSeriesForReviews}),void 0!==e&&"numGenres"!==e||null===STATS.numGenres||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-genres`),{innerHTML:`${STATS.numGenres.toLocaleString()}`,hidden:null===STATS.numGenres}),void 0!==e&&"numTags"!==e||null===STATS.numTags||Object.assign(document.querySelector(`#${ID_SCRAPERLET} .stats-tags`),{innerHTML:`${STATS.numTags.toLocaleString()}`,hidden:null===STATS.numTags}),void 0===e&&(document.querySelector(`#${ID_SCRAPERLET} .stats-groups`).hidden=null===STATS.numGroups,document.querySelector(`#${ID_SCRAPERLET} .stats-groups-infos`).hidden=null===STATS.numGroupInfos,document.querySelector(`#${ID_SCRAPERLET} .stats-series`).hidden=null===STATS.numSeries,document.querySelector(`#${ID_SCRAPERLET} .stats-series-ids`).hidden=null===STATS.numSeriesForCrawl,document.querySelector(`#${ID_SCRAPERLET} .stats-series-infos`).hidden=null===STATS.numSeriesInfos,document.querySelector(`#${ID_SCRAPERLET} .stats-chapters`).hidden=null===STATS.numChapters,document.querySelector(`#${ID_SCRAPERLET} .stats-chapters-series-progress`).hidden=null===STATS.numSeriesForChapters,document.querySelector(`#${ID_SCRAPERLET} .stats-chapter-links`).hidden=null===STATS.numChapterLinksResolved,document.querySelector(`#${ID_SCRAPERLET} .stats-reviews`).hidden=null===STATS.numReviews,document.querySelector(`#${ID_SCRAPERLET} .stats-reviews-series-progress`).hidden=null===STATS.numSeriesForReviews,document.querySelector(`#${ID_SCRAPERLET} .stats-genres`).hidden=null===STATS.numGenres,document.querySelector(`#${ID_SCRAPERLET} .stats-tags`).hidden=null===STATS.numTags)}function setTaskStatusWorking(e){e.setAttribute("disabled","disabled"),e.classList.add("working"),e.classList.remove("success","error");e=e.querySelector(".status");e.textContent="🏭",e.removeAttribute("title")}function setTaskStatusSuccess(e){e.removeAttribute("disabled"),e.classList.remove("working"),e.classList.add("success");e=e.querySelector(".status");e.textContent="✅",e.removeAttribute("title")}function setTaskStatusError(e,t=null){e.removeAttribute("disabled"),e.classList.remove("working"),e.classList.add("error");e=e.querySelector(".status");e.textContent="⚠️",e.title=t}function setHasData(e){e.classList.add("has-data")}async function setStatsFromStorage(){var e=await localforage.getItem(KEY_STORE_STATS)||{};Object.entries(e).forEach(([e,t])=>{null!==t&&0!==t&&(STATS[e]=t)})}async function backupStorageStats(){var e=await localforage.getItem(KEY_STORE_STATS_HISTORY)||[],t=await localforage.getItem(KEY_STORE_STATS);null!==t&&(e.push([new Date,t]),await localforage.setItem(KEY_STORE_STATS_HISTORY,e))}async function setHasDataFromStorage(){await localforage.getItem("scrapeGrouplist-groupMap")&&(document.getElementById("runGrouplistScraper").classList.add("has-data"),await localforage.getItem("scrapeGrouplist-finished")||!1)&&(setTaskStatusSuccess(document.getElementById("runGrouplistScraper")),document.getElementById(ID_SCRAPERLET).classList.add("has-groups")),await localforage.getItem("scrapeGroupDetails-groupInfoMap")&&(document.getElementById("runGroupDetailsScraper").classList.add("has-data"),await localforage.getItem("scrapeGroupDetails-finished")||!1)&&(document.getElementById("runFindMASeries").classList.add("has-data"),setTaskStatusSuccess(document.getElementById("runGroupDetailsScraper")),document.getElementById(ID_SCRAPERLET).classList.add("has-groups-details"),document.getElementById(ID_SCRAPERLET).classList.add("has-series")),await localforage.getItem("scrapeSerieslist-seriesMap")&&(document.getElementById("runSerieslistScraper").classList.add("has-data"),await localforage.getItem("scrapeSerieslist-finished")||!1)&&(setTaskStatusSuccess(document.getElementById("runSerieslistScraper")),document.getElementById(ID_SCRAPERLET).classList.add("has-series")),await localforage.getItem("scrapeSeriesDetails-seriesInfoMap")&&(document.getElementById("runSeriesDetailsScraper").classList.add("has-data"),await localforage.getItem("scrapeSeriesDetails-finished")||!1)&&setTaskStatusSuccess(document.getElementById("runSeriesDetailsScraper")),await localforage.getItem("scrapeAllSeriesChapterList-seriesChapterListMap")&&(document.getElementById("runChapterLinksScraper").classList.add("has-data"),document.getElementById(ID_SCRAPERLET).classList.add("has-chapter-links"),await localforage.getItem("scrapeAllSeriesChapterList-finished")||!1)&&(setTaskStatusSuccess(document.getElementById("runChapterLinksScraper")),document.getElementById(ID_SCRAPERLET).classList.add("has-chapter-links")),(await localforage.getItem("scrapeAllSeriesReviews-seriesReviewsMap")||{})&&(document.getElementById("runSeriesReviewsScraper").classList.add("has-data"),await localforage.getItem("scrapeAllSeriesReviews-finished")||!1)&&setTaskStatusSuccess(document.getElementById("runSeriesReviewsScraper")),await localforage.getItem("scrapeGenres-genresMap")&&(document.getElementById("runGenrelistScraper").classList.add("has-data"),await localforage.getItem("scrapeGenres-finished")||!1)&&setTaskStatusSuccess(document.getElementById("runGenrelistScraper"));await localforage.getItem("scrapeTags-tagsMap")&&(document.getElementById("runTaglistScraper").classList.add("has-data"),await localforage.getItem("scrapeTags-finished")||!1)&&setTaskStatusSuccess(document.getElementById("runTaglistScraper"))}function buildMenu(){var e=` /* https://stackoverflow.com/a/60660207/9360161 */ @media (pointer: coarse), (hover: none) { [title] { position: relative; display: inline-flex; justify-content: center; } [title]:focus::after { content: attr(title); position: absolute; top: 90%; color: #000; background-color: #fff; border: 1px solid; width: fit-content; padding: 3px; } } #${ID_SCRAPERLET} { pointer-events: auto; position: absolute; /* fixed */ z-index: 1000; top: 0; right: 0; background-color: #2c3e50; color: #fff; border: 1px #e8ebee solid; border-radius: 5px; width: max-content; height: min-content; margin: 1em; padding: 1em; } #${ID_SCRAPERLET} h1 { font-size: 1.8rem; font-family: "Open Sans",sans-serif; font-weight: 700; color: rgba(255,255,255,.87); text-decoration: none; border-bottom: 1px solid #c3d7eb; padding-bottom: 3px; margin: 0 0 15px 0; } #${ID_SCRAPERLET} h2 { font-size: 1.1rem; color: rgba(255,255,255,.87); text-decoration: none; border-top: 1px solid #c3d7eb; padding-top: 3px; margin: 15px 0 0 0; } #${ID_SCRAPERLET} input[type="checkbox"] { position: unset; left: unset; margin: 0 1ex 0 0; } #${ID_SCRAPERLET} input[type="checkbox"] + label { position: unset; left: unset; margin: unset; padding: unset; } #${ID_SCRAPERLET} input[type="checkbox"] + label::before, #${ID_SCRAPERLET} input[type="checkbox"] + label::after { display: none; } #${ID_SCRAPERLET} input[type="text"] { position: unset; left: unset; height: unset; line-height: unset; font-size: unset; padding: 0 10px; margin: 0 0 0 10px; text-align: end; width: 5em; } #${ID_SCRAPERLET} .btn { border: 1px solid #4b627a; padding: 0px 9px; cursor: pointer; } #${ID_SCRAPERLET} .btn:hover { background-color: #314961; } #${ID_SCRAPERLET} ul.actions { list-style: none; margin: 4px 0 0 10px; padding: 0; } #${ID_SCRAPERLET} ul.actions > li { margin-bottom: 4px; display: flex; } #${ID_SCRAPERLET} ul.actions > li.l1 { margin-left: 9px; } #${ID_SCRAPERLET} ul.actions > li.l2 { margin-left: 18px; } #${ID_SCRAPERLET} ul.actions > li span { margin-block: auto; } #${ID_SCRAPERLET} ul.actions > li span.action { margin-right: auto; } #${ID_SCRAPERLET} ul.actions > li span.action ~ span { margin-left: 3px; } #${ID_SCRAPERLET} ul.actions > li span.status { margin-left: 6px; padding: 0 3px; } #${ID_SCRAPERLET} ul.actions > li:not(.has-data) span.action ~ span.icon.btn, #${ID_SCRAPERLET} ul.actions > li.no-cache span.action ~ span.icon.btn, #${ID_SCRAPERLET}.delete-not-allowed ul.actions > li span.icon.btn.delete { opacity: 0.3; pointer-events: none; cursor: not-allowed; } #${ID_SCRAPERLET} ul.actions > li span.icon { width: 2rem; padding: 0; text-align: center; } #${ID_SCRAPERLET} ul.actions > li span.icon::before { content: " "; } #${ID_SCRAPERLET} ul.actions > li span.icon.download::before { content: "📥"; } #${ID_SCRAPERLET} ul.actions > li span.icon.delete::before { content: "🗙"; } #${ID_SCRAPERLET} ul.actions > li.working span.action, #${ID_SCRAPERLET}:not(.has-groups) #runGroupDetailsScraper span.action, #${ID_SCRAPERLET}:not(.has-groups-details) #runFindMASeries span.action, #${ID_SCRAPERLET}:not(.has-series) #runSeriesDetailsScraper span.action, #${ID_SCRAPERLET}:not(.has-series) #runChapterLinksScraper span.action, #${ID_SCRAPERLET}:not(.has-chapter-links) #runChapterLinkResolver span.action, #${ID_SCRAPERLET}:not(.has-series) #runSeriesReviewsScraper span.action { pointer-events: none; color: #a8a8a8; } #${ID_SCRAPERLET} ul.stats { list-style: square inside; margin-left: 9px; font-size: 0.8rem; line-height: 1rem; } #${ID_SCRAPERLET} ul.stats > li.sep-above { position: relative; margin-top: 5px; } #${ID_SCRAPERLET} ul.stats > li.sep-above::before { position: absolute; top: -3px; left: 4%; content: ""; border-top: 1px solid aliceblue; width: 92%; height: 0.6rem; } #${ID_SCRAPERLET} ul.stats > .stats-requests::after { content: " Requests Sent"; } #${ID_SCRAPERLET} ul.stats > .stats-response-bytes::after { content: " Received"; } #${ID_SCRAPERLET} ul.stats > .stats-groups::after { content: " Groups Found"; } #${ID_SCRAPERLET} ul.stats > .stats-groups-infos::after { content: " Group Details Scraped"; } #${ID_SCRAPERLET} ul.stats > .stats-series::after { content: " Series Found"; } #${ID_SCRAPERLET} ul.stats > .stats-series-ids::after { content: " Series IDs for Crawls"; } #${ID_SCRAPERLET} ul.stats > .stats-series-infos::after { content: " Series Details Scraped"; } #${ID_SCRAPERLET} ul.stats > .stats-chapters::after { content: " Chapters Found"; } #${ID_SCRAPERLET} ul.stats > .stats-chapters-series-progress::after { content: " Series for Chapters Processed"; } #${ID_SCRAPERLET} ul.stats > .stats-chapter-links::after { content: " Chapter Links Resolved"; } #${ID_SCRAPERLET} ul.stats > .stats-reviews::after { content: " Reviews Found"; } #${ID_SCRAPERLET} ul.stats > .stats-reviews-series-progress::after { content: " Series for Reviews Processed"; } #${ID_SCRAPERLET} ul.stats > .stats-genres::after { content: " Genres Found"; } #${ID_SCRAPERLET} ul.stats > .stats-tags::after { content: " Tags Found"; } #${ID_SCRAPERLET} div.configs { margin-left: 9px; font-size: 0.8rem; line-height: 1.2rem; } `,t=document.createElement("style"),e=(t.id=ID_SCRAPERLET+"-style",t.innerText=e,document.getElementsByTagName("head")[0].appendChild(t),` `.trim()),t=`

NU Scraper

  • Group List ${e}
  • Group Infos ${e}
  • Find Multi-Author Series ${e}
  • Series List ${e}
  • Series Infos ${e}
  • Chapter Links ${e}
  • Resolve External Links ${e}
  • Series Reviews ${e}
  • Genres ${e}
  • Tags ${e}

Stats Load from Cache

  • ${STATS.numRequests}
  • ${humanFileSize(STATS.numBytesResponseText)}
  • ${STATS.numGroups||0}
  • ${STATS.numGroupInfos||0} / ${STATS.numGroupInfosTotal||"?"}
  • ${STATS.numSeries||0}
  • ${STATS.numSeriesForCrawl||0}
  • ${STATS.numSeriesInfos||0} / ${STATS.numSeriesInfosTotal||"?"}
  • ${STATS.numChapters||0}
  • ${STATS.numSeriesForChapters||0} / ${STATS.numSeriesForChaptersTotal||"?"}
  • ${STATS.numReviews||0}
  • ${STATS.numSeriesForReviews||0} / ${STATS.numSeriesForReviewsTotal||"?"}
  • ${STATS.numGenres||0}
  • ${STATS.numTags||0}

Configs

`,e=document.createElement("div");e.id=ID_SCRAPERLET,e.innerHTML=t,e.classList.add("delete-not-allowed"),document.body.append(e),window.runGrouplistScraper=runGrouplistScraper,window.runGroupDetailsScraper=runGroupDetailsScraper,window.runFindMASeries=runFindMASeries,window.runSerieslistScraper=runSerieslistScraper,window.runSeriesDetailsScraper=runSeriesDetailsScraper,window.runChapterLinksScraper=runChapterLinksScraper,window.runChapterLinkResolver=runChapterLinkResolver,window.runSeriesReviewsScraper=runSeriesReviewsScraper,window.runGenrelistScraper=runGenrelistScraper,window.runTaglistScraper=runTaglistScraper,window.updateStopFlag=updateStopFlag,window.updateRequestDelay=updateRequestDelay,window.updateBlockClicksFlag=updateBlockClicksFlag,window.doDownload=doDownload,window.doDataDelete=doDataDelete,window.setStatsFromStorage=setStatsFromStorage,updateStats(),updateStopFlag(),updateRequestDelay(),updateBlockClicksFlag(),setHasDataFromStorage()}function install(){document.location.origin!==URL_BASE?console.error("Bookmarklet not for this page. Please visit",URL_BASE):(null!==document.getElementById(ID_SCRAPERLET)&&(console.warn("Already installed Bookmarklet. Removing old HTML..."),document.getElementById(ID_SCRAPERLET).remove(),document.getElementById(ID_SCRAPERLET+"-style").remove()),void 0!==window.disablePageClicksHandler&&(document.body.removeEventListener("click",window.disablePageClicksHandler),delete window.disablePageClicksHandler),localforage.config({driver:localforage.INDEXEDDB,name:"nuscraper",version:1,storeName:"keyvaluepairs",description:"NovelUpdates Scraper Storage"}),backupStorageStats(),buildMenu())}install(); })();